# Modo de color

Permite elegir Automático, claro, oscuro o alto contraste: con botones de opción que funcionan sin JavaScript o con un botón redondo que los recorre.

### Problemas conocidos
Qué puedes esperar:

- Sin [el script de la cabecera](https://nandovejer.github.io/luz/es/docs/components/theme-mode/#boot), una persona con modo oscuro ve primero la página clara durante un instante: el elemento se ejecuta después del primer pintado.
- Automático sigue solo los ajustes del sistema. Para que quien lee pueda elegir también la hora del día, añade [`<luz-theme-time>`](https://nandovejer.github.io/luz/es/docs/catalog/theme-time/), del catálogo.
- El texto es tuyo: LUZ no escribe ninguna etiqueta, así que traduce la leyenda y los modos con la página.
- No se ha probado con un lector de pantalla.

### Copiar el marcado
Escribe un botón de opción por cada elección dentro de `<luz-theme-mode>`, en el orden en que el botón los recorre. Pon un icono SVG (`currentColor`, `aria-hidden`) en cada etiqueta: el botón muestra el de la opción seleccionada. La leyenda y las etiquetas son tuyas.

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

<luz-theme-mode>
  <fieldset class="luz-theme-mode__group">
    <legend class="luz-theme-mode__legend">Color mode</legend>
    <label class="luz-theme-mode__option"><input class="luz-theme-mode__input" type="radio" name="luz-theme-mode" value="auto" checked><svg class="luz-theme-mode__icon" aria-hidden="true">…</svg>Auto</label>
    <label class="luz-theme-mode__option"><input class="luz-theme-mode__input" type="radio" name="luz-theme-mode" value="light"><svg class="luz-theme-mode__icon" aria-hidden="true">…</svg>Light</label>
    <label class="luz-theme-mode__option"><input class="luz-theme-mode__input" type="radio" name="luz-theme-mode" value="dark"><svg class="luz-theme-mode__icon" aria-hidden="true">…</svg>Dark</label>
    <label class="luz-theme-mode__option"><input class="luz-theme-mode__input" type="radio" name="luz-theme-mode" value="high-contrast"><svg class="luz-theme-mode__icon" aria-hidden="true">…</svg>High contrast</label>
  </fieldset>
</luz-theme-mode>
```

`luz.min.js` carga `theme-mode.min.js` cuando la página tiene el elemento. Para cargarlo tú, o para un elemento añadido cuando la página ya ha cargado, `import "@luz-ds/core/theme-mode";`.

### Variantes y opciones
- `<luz-theme-mode>`: El elemento. Contiene los botones de opción; con scripting activado añade un botón redondo, fijo en la esquina final.
- `inline`: Un booleano. El botón se queda donde lo pone el marcado: un pie de página, una barra de navegación, una barra lateral.
- `no-remember`: Un booleano. La elección no se lee ni se guarda en `luz-theme`: la página empieza en Automático.
- `name="luz-theme-mode"`: Mantenlo: sin JavaScript, los tokens lo leen para cambiar el modo.
- `value`: `auto`, `light`, `dark` o `high-contrast`. El botón recorre los botones de opción en el orden del marcado y se salta los desactivados.
- `.luz-theme-mode__group`: El fieldset de botones de opción; sin el botón, una fila de opciones.
- `.luz-theme-mode__legend`, `.luz-theme-mode__option`, `.luz-theme-mode__input`, `.luz-theme-mode__icon`: La leyenda (da nombre al grupo y, con la etiqueta seleccionada, al botón); una etiqueta con su botón de opción, su icono y su nombre; el botón de opción, oculto a la vista pero con foco; el icono, que el botón copia de la opción seleccionada.
- `__button`, `__button--fixed`, `__status`: Los escribe el script, no tú: el botón redondo (fijo salvo con `inline`) y una región dinámica oculta que dice el nuevo modo.

#### Propiedades, métodos y evento

- `el.choice`: La elección (`auto`, `light`, `dark`, `high-contrast`). Al asignarla se elige ese botón de opción; cualquier otro valor se ignora.
- `el.mode`: El modo en uso. En Automático es el del sistema.
- `el.refresh()`: Aplica el modo de nuevo. Llámalo después de cambiar lo que significa Automático.
- `el.autoMode`: Una función que devuelve `light`, `dark` o nada (el del sistema). Otro script la asigna para decidir qué significa Automático, como hace `<luz-theme-time>`; el alto contraste del sistema sigue ganando.
- `luz-theme-mode:change`: Sube por el árbol tras la mejora y en cada cambio. `detail`: `mode`, `auto` (la elección es Automático) y `user` (la ha elegido una persona).

### Cómo funciona
Un grupo nativo de botones de opción con estilos de `components/theme-mode.css`. Los botones de opción son el estado; con scripting activado, el elemento los convierte en un botón.

- **El botón:** cada pulsación marca el siguiente botón de opción y lo aplica; el grupo se oculta mientras está el botón. El script añade `luz-theme-mode__button--fixed` al botón fijo y no lo añade con `inline`. Un botón de opción con foco se lo pasa al botón.
- **Automático sigue el sistema,** también mientras la página está abierta: `prefers-contrast: more` da `high-contrast`; si no, `prefers-color-scheme: dark` da `dark`; si no, `light`.
- **Qué escribe en `<html>`:** el modo en `data-mode` y, sin marca, el mismo valor en `data-theme`, que es el que leen los tokens. Una página que nombra una marca (`data-theme="my-brand"`, un [tema propio](https://nandovejer.github.io/luz/es/docs/tokens/themes/) hecho a partir de `_template.css`) la conserva, y los bloques de la marca responden a `data-mode`.
- **La elección se recuerda** en `luz-theme`, en `localStorage`; Automático la elimina y `no-remember` lo desactiva. Si el script de la cabecera ya ha escrito `data-mode`, el primer Automático lo adopta. Un segundo `<luz-theme-mode>` sigue al primero.
- **Dónde está el botón:** salvo con `inline`, en la esquina final de la ventana (abajo a la izquierda en una página de derecha a izquierda), en `--luz-z-raised`: por encima del contenido y por debajo de la barra lateral, los diálogos y los avisos.
- **Deja libre la esquina.** Dale al pie de página un relleno final de `calc(var(--luz-control-lg) + var(--luz-space-md) * 2)` dentro de `@media (scripting: enabled)`. La hoja de estilos añade `scroll-padding-block-end` a `<html>`, así que con Tab ningún elemento con foco queda bajo el botón; con [`<luz-cookie-consent>`](https://nandovejer.github.io/luz/es/docs/catalog/cookie-consent/) visible, el botón se coloca sobre el banner.
- **En una barra lateral** toma los colores de la [barra lateral](https://nandovejer.github.io/luz/es/docs/catalog/sidebar/) del catálogo; en otra superficie oscura, define las propiedades `--luz-theme-mode-*`.

### Sin JavaScript
Los cuatro botones de opción se muestran donde los pone el marcado; no hay botón. Elegir uno cambia el modo, porque los tokens leen el botón de opción seleccionado (`:root:has()`), mientras `<html>` no tenga un `data-mode`. Funciona también con un [tema de marca](https://nandovejer.github.io/luz/es/docs/tokens/themes/), si su `_template.css` es el actual. La elección no se recuerda y Automático sigue al sistema: oscuro con `prefers-color-scheme: dark`, alto contraste con `prefers-contrast: more` y claro en los demás casos.

### Teclado y ARIA
- **Botón:** se llega a él con Tab; Enter o Espacio pasa al modo siguiente. El foco sigue el marcado, no la esquina.
- **Nombre y estado:** el nombre del botón es el texto de la leyenda, dos puntos y la etiqueta de la opción seleccionada, como «Modo de color: Oscuro». Después de que una persona elija, una región oculta con `role="status"` dice lo mismo; no dice nada cuando carga la página.
- **Botones de opción:** sin el botón, con Tab se llega al grupo y las teclas de dirección eligen un modo.

### Cuándo usarlo
Ofrece un control del modo de color en todas las páginas del sitio, siempre en el mismo lugar.

- El botón redondo en la esquina final, una vez por página.
- El botón redondo con `inline`, cuando forma parte de un panel: un pie de página, una barra de navegación, una barra lateral.

### Cuándo no usarlo
No pongas un segundo botón fijo en una página: los demás son en línea.

- No lo fijes en una esquina que ocupa otro control, como un botón de chat.
- No dejes los botones de opción fuera del marcado: sin JavaScript son el único control.
- No lo uses para elegir una marca: una marca se nombra con `data-theme`; este elemento elige su modo.
