# Color mode by time of day

Adds the time of day to the color mode: a reader picks a moment you declare, or drags a slider through the hours, and Auto stays the system's.

### Known issues
What to expect:

- The [script for the head](https://nandovejer.github.io/luz/docs/catalog/theme-time/#boot) ignores `latitude` and `longitude`: with a place, the element corrects the moment after the first paint, so it can change once near sunrise or sunset.
- The moments are written twice: in the markup and in `data-moments` of the [script for the head](https://nandovejer.github.io/luz/docs/catalog/theme-time/#boot). Nothing checks that they agree, so change both together.
- Without `data-luz-label-scrub` the slider has no name, and without `data-luz-label-saved` the note is silent: no English fallback.
- Only the first `<luz-theme-time>` with moments owns the page.
- It has not been tested with a screen reader.

### Copy the markup
Wrap core's [`<luz-theme-mode>`](https://nandovejer.github.io/luz/docs/components/theme-mode/) in `<luz-theme-time>` and add the moments of the day after it, one radio each, in the order of the day. Its `value` is the name of the moment; its label is what a reader sees.

Markup
```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@luz-ds/core@0.3.0/dist/luz.min.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/catalog.min.js"></script>

<luz-theme-time>
  <luz-theme-mode>
    …the fieldset and the four radios of core's page…
  </luz-theme-mode>
  <fieldset class="luz-theme-time__moments">
    <legend class="luz-theme-time__legend">Time of day</legend>
    <label class="luz-theme-time__moment"><input class="luz-theme-time__input" type="radio" name="luz-theme-moment" value="dawn" data-from="05:00" data-theme="dark">Dawn</label>
    <label class="luz-theme-time__moment"><input class="luz-theme-time__input" type="radio" name="luz-theme-moment" value="morning" data-from="07:30" data-theme="light">Morning</label>
    <label class="luz-theme-time__moment"><input class="luz-theme-time__input" type="radio" name="luz-theme-moment" value="afternoon" data-from="12:00" data-theme="light" data-default>Afternoon</label>
    <label class="luz-theme-time__moment"><input class="luz-theme-time__input" type="radio" name="luz-theme-moment" value="sunset" data-from="17:30" data-theme="light">Sunset</label>
    <label class="luz-theme-time__moment"><input class="luz-theme-time__input" type="radio" name="luz-theme-moment" value="dusk" data-from="20:30" data-theme="dark">Dusk</label>
    <label class="luz-theme-time__moment"><input class="luz-theme-time__input" type="radio" name="luz-theme-moment" value="night" data-from="22:30" data-theme="dark" data-default>Night</label>
  </fieldset>
</luz-theme-time>
```

`catalog.min.js` loads `theme-time.min.js` when the browser is idle and the page has the element. To load it on its own, import `@luz-ds/catalog/theme-time` and link `components/theme-time.css` after core's.

### Variants and options
A bar with a place, and the texts it needs:

Bar markup
```html
<luz-theme-time variant="bar" show="time place saved" place="Madrid" latitude="40.42" longitude="-3.7"
                 data-luz-label-scrub="Hour of the day" data-luz-label-saved="Saved">
  <luz-theme-mode inline>
    …the fieldset and the four radios of core's page…
  </luz-theme-mode>
</luz-theme-time>
```

- `variant="bar"`: Adds the slider of the 24 hours: by default the slider alone.
- `show`: Words that add parts to the bar: `time` (the hour in large type), `place` (the place and the moment), `saved` (the note “Saved”; without it the note is still written, for a screen reader) and `moments` (the declared moments as options under the slider; choosing one pins its hour).
- `place`: The name of the place for `show="place"`; a label, it does not set the sun.
- `latitude`, `longitude`: Degrees north and east of the place whose sunrise and sunset set the turns of the day.
- `no-remember`: A pinned hour is not stored under `luz-light`.
- On a moment: `value`, `data-from`, `data-theme`, `data-default`: Its name (written to `data-moment`); where it starts, HH:MM by the visitor's clock; the base it is painted over, `light` or `dark`; and the one a chosen mode shows (light, the default light moment; dark and high contrast, the default dark one).
- `data-luz-label-scrub`, `data-luz-label-saved`: On the element or an ancestor: the slider's name and the note “Saved”.

#### Properties, methods and event

- `el.hour`, `el.moments`, `el.moment`, `el.dayMoment`, `el.pinned`, `el.place`: Read-only: the hour the slider shows (0 to 24: the pinned or previewed one, else the clock's); the declared moments, `{ name, from, theme, input }`; the name of the moment the page shows; the name of the moment at that hour, shown or not; the pinned hour (`null` if none); the `place` attribute.
- `preview(hour)`, `pin(hour)`, `unpin()`: The page shows the moment at that hour, and nothing is stored (`preview(null)` goes back); the page keeps the moment at that hour, stored under `luz-light` unless `no-remember`; lets go of the pinned hour, back to the system.
- `luz-theme-time:change`: Bubbles after the upgrade and when the moment or the pinned hour changes. `detail`: `moment` and `pinned` (each `null` if none).

A method returns false when it does nothing: no moments, or an hour outside 0 to 24.

### How it works
`theme-time.js` adds the moments of the day to [`<luz-theme-mode>`](https://nandovejer.github.io/luz/docs/components/theme-mode/), as a choice the reader makes. Core does the rest, and the button alone if the catalog does not load.

- **Auto is the system's,** as in core: dark, high contrast, or light. The clock moves nothing. `data-moment` takes the default moment of that mode (`data-default`), and no moment radio is checked. The mode radio checked is the one in use, Light or Dark, and the button is named after it; nothing is stored, and the choice is still Auto. Auto itself is checked only while an hour or a moment is chosen. Auto does not follow the hour: a page that wants a moment sets it, with the slider, a moment option or `pin(hour)`.
- **A moment the reader chose** is the last one that has started at that hour (night runs through midnight): its name goes to `data-moment`, its radio is checked and the page takes its base. The visitor's location is never asked.
- **A mode the reader chose** shows its default moment. **High contrast always wins:** `data-theme` is `high-contrast`, so a rule for `"light"` or `"dark"` does not match.
- **With a place,** `latitude` and `longitude` give today's real sunrise and sunset, worked out in the page with no network, in place of the two turns of the day; if the sun does not rise or set there, the declared hours stand.
- **A pinned hour** is the moment at that hour kept in Auto, stored under `luz-light` to five minutes; choosing a mode, or Auto, in `<luz-theme-mode>` lets it go, back to the system.
- **The slider** (`variant="bar"`): dragging previews the hour; letting go pins and stores it and writes the note “Saved”. Its track is painted with `--luz-theme-time-sky-<value>`, one for each moment: [Paint the track](https://nandovejer.github.io/luz/docs/catalog/theme-time/#sky).
- **Two files:** `theme-time.min.js` and `theme-time-bar.min.js`, which only `variant="bar"` loads. For a bar added after the scan, import `@luz-ds/catalog/theme-time-bar` and call `initThemeTimeBar(root)`.

### Without JavaScript
There is no bar and the moments are not shown. Core's radios still change the mode; Auto follows the system, and `data-moment` is not written.

### Keyboard and ARIA
- **Slider:** a native range in steps of 5 minutes: Tab reaches it, the arrow keys move one step, Home goes to 00:00 and End to 23:55. Each press previews the hour.
- **Escape** on the slider lets go of a pinned hour, and then does not close a dialog around the bar.
- **Name and value:** the name is `data-luz-label-scrub`; `aria-valuetext` is the moment and the hour, “Afternoon, 13:00”. When an hour is pinned a `role="status"` region says your `data-luz-label-saved`, shown or not.
- **Moments as options** (`show="moments"`) are radios in a fieldset: the arrow keys choose one. The mode button is core's: [its keyboard and ARIA](https://nandovejer.github.io/luz/docs/components/theme-mode/#keyboard). With the system in use it steps on from the mode shown, so the first press never repeats it.

### When to use
Use it when a site has a look for each part of the day, or when readers should be able to try the light at another hour.

- The moments alone, in a footer or a navbar, for a site that changes its look with the day.
- The bar, where the light is part of the page, such as a home page.

### When not to use
Do not use it when the site has one look in one mode: [core's color mode](https://nandovejer.github.io/luz/docs/components/theme-mode/) is enough.

- Do not promise the real sunrise without a place: the declared hours are fixed.
- Do not use the bar as the only control: keep core's button.
- Do not ask for the visitor's location: write the place yourself.
