/* =============================================================================
   Control de Horas Extra — hoja de estilo única
   =============================================================================
   Dirección industrial/utilitaria: fondo oscuro, superficies planas, esquinas
   rectas, sin sombras y sin degradados. Nada decora: el color se reserva para
   decir en qué estado está algo, y por eso hay tan poco.

   Todo el CSS del proyecto vive aquí. No hay framework ni utilidades sueltas:
   la CSP es default-src 'none' con style-src 'self', así que no hay estilos en
   línea ni hojas de terceros que puedan colarse sin que salte.

   Orden del fichero:
     1. Tipografías          8. Interruptores
     2. Tokens               9. Botones
     3. Reinicio            10. Mensajes
     4. Contenedores        11. Tablas
     5. Cabecera            12. Administración
     6. Paneles y lecturas  13. Calendario
     7. Formularios         14. Utilidades y anchos
   ========================================================================== */

/* --- 1. Tipografías ---------------------------------------------------------
   Autoalojadas (ver recursos/tipografias/LEEME.txt). Son las VARIABLES: un solo
   fichero por subconjunto cubre todos los pesos. El unicode-range hace que el
   navegador sólo baje 'latin-ext' si la página trae algún carácter que lo
   necesite, así que una página en español descarga unos 80 kB y no 176.
   -------------------------------------------------------------------------- */

@font-face {
    font-family: 'Inter';
    src: url('tipografias/inter-latin.woff2') format('woff2');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                   U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                   U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Inter';
    src: url('tipografias/inter-latin-ext.woff2') format('woff2');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                   U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                   U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('tipografias/jetbrains-mono-latin.woff2') format('woff2');
    font-weight: 400 800;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                   U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                   U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'JetBrains Mono';
    src: url('tipografias/jetbrains-mono-latin-ext.woff2') format('woff2');
    font-weight: 400 800;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                   U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                   U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- 2. Tokens ------------------------------------------------------------ */

:root {
    --bg-void: #1B1917;
    --bg-surface: #232120;
    --bg-surface-raised: #2A2825;
    --border: #3C3937;
    --border-strong: #524E4A;
    --text-primary: #F2EFEA;
    --text-secondary: #A8A29B;
    /* --text-tertiary sólo se usa ya en FORMAS (la flecha del desplegable, el
       tirador del interruptor, la luz apagada de una cuenta) y en los días que
       aún no han llegado. Como texto no llega a 4,5:1 sobre ningún fondo de
       esta paleta, así que no lo lleva ninguno que haya que leer. */
    --text-tertiary: #6F6A64;
    --status-normal: #5BA179;
    --status-normal-dim: #2C3B33;
    --status-caution: #E0983A;
    --status-caution-dim: #3D3222;
    --status-stop: #C4573F;
    --status-stop-dim: #3A2620;
    --accent: #5B8AA6;
    --accent-dim: #24333B;

    /* --- Derivados para cumplir el contraste -------------------------------
       Los tokens de arriba son los de la maqueta y no se tocan. Estos son
       aclarados suyos, calculados para llegar al mínimo que pide la WCAG AA
       (4,5:1 en texto y 3:1 en el borde de un control) sobre el fondo concreto
       en el que se usan. Sin ellos, un verde de #5BA179 sobre su propio fondo
       apagado se queda en 3,8:1 y el número del día no se lee a pleno sol, que
       es donde se usa esta aplicación. Conservan el tono: sólo suben de claridad
       lo justo. */
    --accent-sobre-panel: #608EA9;      /* enlace dentro de un panel  4,5:1 */
    --accent-fuerte: #769DB5;           /* sobre --accent-dim         4,5:1 */
    --normal-texto: #6FAD8A;            /* sobre --status-normal-dim  4,5:1 */
    --stop-texto: #D07A67;              /* sobre --status-stop-dim    4,5:1 */
    --caution-texto: #E0983A;           /* ya cumple: 5,2:1                 */
    --borde-control: #706A65;           /* borde de campo             3,0:1 */

    --texto: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --cifras: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

    /* Un solo alto para campos y botones. Es lo que hace que un input y el
       botón que lleva al lado queden a ras; ajustando este par de valores se
       mueven todos los controles a la vez y no se descuadra ninguna fila. */
    --control-pad-v: 10px;
    --control-pad-h: 12px;
    --control-linea: 20px;
}

/* --- 3. Reinicio ---------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    padding: 20px 14px 40px;
    min-height: 100vh;
    background: var(--bg-void);
    color: var(--text-primary);
    font-family: var(--texto);
    font-size: 14px;
    line-height: 1.55;
}

h1, h2, h3, p, dl, dd, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; }

img { max-width: 100%; }

a { color: var(--accent); text-decoration: none; }

/* Dentro de un panel el fondo es más claro y el acento se queda justo por
   debajo del mínimo: se sube un punto. */
.panel a, .tabla a, .mensaje a { color: var(--accent-sobre-panel); }
a:hover { text-decoration: underline; }

/* El foco de teclado tiene que verse SIEMPRE, en todo lo que se pueda enfocar.
   Es una regla general a propósito: así un control nuevo nace ya con foco
   visible en vez de esperar a que alguien se acuerde de dárselo. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* --- 4. Contenedores ------------------------------------------------------
   Móvil primero: una columna estrecha. .tarjeta es para las páginas de un solo
   formulario (entrar, mensajes) y .contenido para las de trabajo. */

.tarjeta,
.contenido {
    width: 100%;
    margin: 0 auto;
}

.tarjeta  { max-width: 400px; }
.contenido { max-width: 420px; }

/* --- 5. Cabecera y navegación --------------------------------------------- */

.cabecera {
    max-width: 420px;
    margin: 0 auto 18px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--border);
}

.cabecera-fila {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    min-width: 0;
}

.marca {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text-primary);
    text-decoration: none;
}
.marca:hover { text-decoration: none; }
.marca span { color: var(--text-secondary); font-weight: 400; }

/* Se deja encoger y, si aun así no cabe, se recorta. Sin esto un mes largo
   —"SEPTIEMBRE DE 2026"— ensancha la página entera y todo lo demás aparece
   desplazado, que es de los fallos más difíciles de rastrear a ojo. */
.cabecera-dato {
    flex: 0 1 auto;
    min-width: 0;
    font-family: var(--cifras);
    font-size: 11px;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.marca { flex: 0 0 auto; }

.rol {
    font-size: 9.5px;
    letter-spacing: 0.06em;
    color: var(--accent);
    border: 1px solid var(--accent);
    padding: 2px 7px;
    text-transform: uppercase;
    white-space: nowrap;
}

/* La navegación se desplaza en horizontal en el móvil en vez de partirse en
   varias líneas: así la cabecera mide siempre lo mismo y el contenido no baila
   al cambiar de sección. */
.navegacion {
    display: flex;
    gap: 2px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}
.navegacion::-webkit-scrollbar { display: none; }

/* Aviso de que hay más menú a un lado (Fase 14). Los degradados van en el
   marco, que no se desplaza; navegacion.js pone hay-izq / hay-der según lo
   que quede oculto, y al llegar al final se apagan solos. Sin JavaScript no
   se encienden nunca, que es mejor que un degradado que mienta. El color es
   el del fondo de la página, porque la cabecera no tiene fondo propio. */
.navegacion-marco {
    position: relative;
    margin-top: 12px;
}
.navegacion-marco::before,
.navegacion-marco::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 32px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s ease;
    z-index: 1;
}
.navegacion-marco::before { left: 0;  background: linear-gradient(to right, var(--bg-void), transparent); }
.navegacion-marco::after  { right: 0; background: linear-gradient(to left,  var(--bg-void), transparent); }
.navegacion-marco.hay-izq::before,
.navegacion-marco.hay-der::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
    .navegacion-marco::before, .navegacion-marco::after { transition: none; }
}

.navegacion a {
    flex: none;
    padding: 6px 10px;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
    border: 1px solid transparent;
    white-space: nowrap;
}
.navegacion a:hover { color: var(--text-secondary); text-decoration: none; }

.navegacion a[aria-current="page"] {
    color: var(--text-primary);
    background: var(--bg-surface);
    border-color: var(--border);
}

.navegacion form { margin-left: auto; }

.navegacion button {
    padding: 6px 10px;
    font: inherit;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
    background: none;
    border: 1px solid transparent;
    cursor: pointer;
}
.navegacion button:hover { color: var(--stop-texto); }

/* --- 6. Paneles y lecturas -------------------------------------------------
   El panel con la etiqueta montada sobre el borde superior es el componente que
   da carácter a todo: la etiqueta tapa la línea con el color del fondo, como el
   rótulo grabado de un cuadro de mandos. */

.panel {
    position: relative;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    padding: 18px 16px 16px;
    margin: 0 0 26px;
}

.panel-etq {
    position: absolute;
    top: -9px;
    left: 12px;
    padding: 0 6px;
    background: var(--bg-void);
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.panel > :last-child { margin-bottom: 0; }

/* Fila de lecturas: las cifras de cabecera, separadas por filetes. */
.lecturas {
    display: grid;
    grid-template-columns: 1fr 1px 1fr 1px 1fr;
    gap: 12px;
    align-items: end;
}

.lecturas-div { background: var(--border); }

.lectura .etq {
    font-size: 9.5px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin-bottom: 5px;
}

.lectura .val {
    font-family: var(--cifras);
    font-variant-numeric: tabular-nums;
    font-size: 21px;
    font-weight: 600;
    line-height: 1;
    color: var(--text-primary);
}

.lectura .val small {
    font-size: 11px;
    font-weight: 500;
    color: var(--text-secondary);
}

.lectura.pendiente .val { color: var(--status-caution); }
.lectura.pagado .val    { color: var(--normal-texto); }
.lectura.alerta .val    { color: var(--stop-texto); }

/* Panel de resultado: lo que vale el día, destacado en el color de acento. */
.resultado {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 16px 0;
    padding: 12px 14px;
    background: var(--accent-dim);
    border: 1px solid var(--accent);
}

.resultado .etq { font-size: 11px; color: var(--text-secondary); }

.resultado .val {
    font-family: var(--cifras);
    font-variant-numeric: tabular-nums;
    font-size: 17px;
    font-weight: 600;
    color: var(--accent-fuerte);
}

/* --- 7. Tipografía de contenido ------------------------------------------- */

h1 {
    font-size: 18px;
    font-weight: 600;
    letter-spacing: -0.01em;
    margin: 0 0 6px;
}

h2 {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin: 26px 0 12px;
}

h3 {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
    margin: 20px 0 10px;
}

.lede {
    color: var(--text-secondary);
    font-size: 13px;
    margin: 0 0 18px;
}

.apunte {
    color: var(--text-secondary);
    font-size: 11.5px;
    line-height: 1.5;
}

p { margin: 0 0 12px; }
p:last-child { margin-bottom: 0; }

code {
    font-family: var(--cifras);
    font-size: 0.92em;
    background: var(--bg-void);
    border: 1px solid var(--border);
    padding: 1px 5px;
    word-break: break-all;
}

/* Definiciones: etiqueta arriba, valor debajo. En una columna se lee mejor en
   el móvil que la rejilla de dos que había antes. */
.datos { margin: 0 0 18px; }

.datos dt {
    font-size: 9.5px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin-top: 12px;
}
.datos dt:first-child { margin-top: 0; }

.datos dd {
    margin: 2px 0 0;
    font-size: 13.5px;
    color: var(--text-primary);
}

/* --- 8. Formularios ------------------------------------------------------- */

.campo { margin: 0 0 14px; }

.campo label,
.etiqueta-campo {
    display: block;
    margin-bottom: 6px;
    font-size: 11.5px;
    font-weight: 500;
    color: var(--text-secondary);
}

.campo input[type="text"],
.campo input[type="email"],
.campo input[type="password"],
.campo input[type="date"],
.campo input[type="number"],
.campo select,
.tabla input[type="text"] {
    width: 100%;
    padding: var(--control-pad-v) var(--control-pad-h);
    background: var(--bg-void);
    border: 1px solid var(--borde-control);
    border-radius: 0;
    color: var(--text-primary);
    font-family: var(--texto);
    font-size: 14px;
    line-height: var(--control-linea);
    appearance: none;
}

/* Todo lo que es una cifra o una fecha, en la monoespaciada: así una columna de
   importes se lee como una columna y no como una lista de palabras. */
.campo input[type="date"],
.campo input[type="number"],
.campo input[inputmode="decimal"],
.tabla input[inputmode="decimal"] {
    font-family: var(--cifras);
    font-variant-numeric: tabular-nums;
}

.campo select {
    /* La flecha va dibujada aquí y no con una imagen: un SVG de fondo sería un
       recurso más que declarar en la CSP. */
    background-image: linear-gradient(45deg, transparent 50%, var(--text-tertiary) 50%),
                      linear-gradient(135deg, var(--text-tertiary) 50%, transparent 50%);
    background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    padding-right: 30px;
}

.campo input::placeholder { color: var(--text-secondary); opacity: 1; }

.campo input:focus-visible,
.campo select:focus-visible,
.tabla input:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-color: var(--accent);
}

.campo input[readonly] {
    background: var(--bg-surface-raised);
    color: var(--text-secondary);
    border-style: dashed;
    cursor: not-allowed;
}

.campo input:disabled,
.campo select:disabled { opacity: 0.5; cursor: not-allowed; }

/* Fila de campos que caben uno al lado del otro (fecha + botón, mes + botón). */
.fila-campos {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 10px;
    margin: 0 0 14px;
}
.fila-campos .campo { flex: 1 1 150px; margin: 0; }

/* --- 9. Interruptores ------------------------------------------------------
   Sustituyen a las casillas en los booleanos del parte (festivo, zonas,
   dietas). Por dentro siguen siendo <input type="checkbox"> con el mismo name y
   el mismo value: lo que llega al servidor es exactamente lo de antes, sólo
   cambia lo que se ve.

   La casilla no se oculta con display:none —eso la sacaría del recorrido del
   teclado y del lector de pantalla— sino que se hace transparente y se deja
   encima del interruptor. */

.conmutador {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 0;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
}

.conmutador:last-of-type { border-bottom: none; }

.conmutador-nombre {
    font-size: 13px;
    color: var(--text-primary);
    line-height: 1.35;
}

.conmutador-nombre .importe {
    color: var(--text-secondary);
    font-family: var(--cifras);
    font-size: 11px;
    margin-left: 5px;
}

.conmutador-nombre .apunte { display: block; margin-top: 2px; }

.conmutador input {
    position: absolute;
    right: 0;
    width: 38px;
    height: 22px;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

.conmutador-pista {
    position: relative;
    flex: none;
    width: 38px;
    height: 22px;
    background: var(--bg-void);
    border: 1px solid var(--borde-control);
    transition: background-color .12s linear, border-color .12s linear;
}

.conmutador-pista::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    background: var(--text-secondary);
    transition: left .12s linear, background-color .12s linear;
}

.conmutador input:checked ~ .conmutador-pista {
    background: var(--status-caution-dim);
    border-color: var(--status-caution);
}
.conmutador input:checked ~ .conmutador-pista::after {
    left: 20px;
    background: var(--status-caution);
}

.conmutador input:focus-visible ~ .conmutador-pista {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.conmutador input:disabled { cursor: not-allowed; }
.conmutador input:disabled ~ .conmutador-pista { opacity: 0.45; }
.conmutador:has(input:disabled) { cursor: not-allowed; }

/* Casilla normal, para lo que NO es un ajuste: el "recordarme" del login y la
   confirmación de una corrección de tarifa. Un interruptor promete un estado
   que se guarda, y esas dos son decisiones de un solo envío. */
.campo-casilla {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 0 0 14px;
    font-size: 13px;
    color: var(--text-secondary);
}

.campo-casilla input[type="checkbox"] {
    flex: none;
    width: 16px;
    height: 16px;
    margin: 2px 0 0;
    accent-color: var(--accent);
}

.campo-casilla label { margin: 0; font-weight: 400; cursor: pointer; }

/* --- 10. Botones ----------------------------------------------------------
   Mismo alto que los campos, para que un botón junto a un input quede a ras.
   El relleno vertical es el del control menos el borde que el campo también
   tiene, de modo que las dos cajas miden igual sin ajustar nada a ojo. */

.boton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: var(--control-pad-v) 16px;
    min-height: calc(var(--control-linea) + var(--control-pad-v) * 2 + 2px);
    background: var(--accent);
    border: 1px solid var(--accent);
    border-radius: 0;
    color: var(--bg-void);
    font-family: var(--texto);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.01em;
    line-height: var(--control-linea);
    text-align: center;
    text-decoration: none;
    cursor: pointer;
}

.boton:hover { background: #6E9CB8; border-color: #6E9CB8; text-decoration: none; }

.boton.secundario {
    background: transparent;
    border-color: var(--borde-control);
    color: var(--text-primary);
}
.boton.secundario:hover { background: var(--bg-surface-raised); border-color: var(--text-secondary); color: var(--text-primary); }

.boton.peligro {
    background: transparent;
    border-color: var(--status-stop);
    color: var(--stop-texto);
}
.boton.peligro:hover { background: var(--status-stop-dim); border-color: var(--status-stop); color: var(--status-stop); }

.boton:disabled,
.boton[disabled] { opacity: 0.4; cursor: not-allowed; }
.boton:disabled:hover { background: var(--accent); border-color: var(--accent); }

/* Variante pequeña, para las acciones de una fila de tabla. */
.boton.estrecho {
    padding: 5px 10px;
    min-height: 0;
    font-size: 11.5px;
    line-height: 18px;
}

/* Botón a todo lo ancho: el envío principal de un formulario en el móvil. */
.boton.ancho { width: 100%; }

/* Un botón principal que es un <a> dentro de un panel o un aviso: la regla de
   los enlaces de panel (.panel a) le pondría el texto azul sobre fondo azul.
   Los secundarios y los de peligro ya fijan su propio color. */
.panel a.boton:not(.secundario):not(.peligro),
.mensaje a.boton:not(.secundario):not(.peligro) { color: var(--bg-void); }

.acciones {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 14px 0;
}
.acciones form { margin: 0; }
.acciones.derecha { justify-content: flex-end; }

/* Botonera: los envíos de un formulario, repartiéndose el ancho. */
.botonera {
    display: flex;
    gap: 8px;
    margin: 16px 0 0;
}
.botonera .boton { flex: 1; }
.botonera .boton.encoge { flex: 0 0 auto; }

/* --- 11. Mensajes ---------------------------------------------------------- */

.mensaje {
    margin: 0 0 16px;
    padding: 11px 13px;
    border: 1px solid;
    font-size: 12.5px;
    line-height: 1.5;
}

.mensaje a { text-decoration: underline; }

.mensaje.exito { border-color: var(--status-normal); background: var(--status-normal-dim); color: #A9D6BC; }
.mensaje.error { border-color: var(--status-stop);   background: var(--status-stop-dim);   color: #E6A08C; }
.mensaje.aviso { border-color: var(--status-caution);background: var(--status-caution-dim);color: #EFC489; }
.mensaje.info  { border-color: var(--border-strong); background: var(--bg-surface);        color: var(--text-secondary); }

.mensaje strong { color: var(--text-primary); }
.mensaje ul { margin: 6px 0 0; padding-left: 18px; }
.mensaje li { margin: 3px 0; }

/* --- 12. Tablas ------------------------------------------------------------
   En el móvil se desplazan dentro de su caja en vez de arrastrar la página. */

.tabla-desplaza {
    overflow-x: auto;
    margin: 0 0 18px;
    border: 1px solid var(--border);
    background: var(--bg-surface);
}

/* Dentro de un panel, la tabla no necesita marco propio: ya lo pone el panel.
   Los márgenes negativos la llevan hasta el borde, que es donde se lee mejor
   una rejilla de cifras. */
.panel > .tabla-desplaza.sin-marco {
    border: 0;
    background: none;
    margin: 4px -16px -16px;
    width: calc(100% + 32px);
}

.tabla {
    width: 100%;
    border-collapse: collapse;
    font-size: 12.5px;
}

.tabla th,
.tabla td {
    padding: 10px 12px;
    text-align: left;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.tabla th {
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-secondary);
    white-space: nowrap;
}

.tabla tbody tr:last-child td { border-bottom: 0; }

.tabla .cifra {
    text-align: right;
    font-family: var(--cifras);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.tabla th.cifra { text-align: right; }

.tabla tfoot td,
.tabla tr.total td {
    border-top: 1px solid var(--border-strong);
    border-bottom: 0;
    color: var(--text-primary);
}

.tabla tfoot td { background: var(--bg-surface-raised); }

/* Un enlace dentro de una celda va subrayado para que se vea que lo es, pero
   un botón NO: ya se ve que lo es por su caja. */
.tabla td a { text-decoration: underline; }
.tabla td a.boton { text-decoration: none; }

/* Columnas de lista (zonas, dietas): en una sola línea, y que la tabla se
   desplace. Con ajuste de línea una fila con dos zonas se estira a cuatro
   renglones y la tabla deja de leerse como una rejilla. */
.tabla .lista { white-space: nowrap; }

.tabla .acciones { margin: 0; gap: 6px; }

/* La lista de festivos con su casilla: la columna de la casilla es estrecha,
   toda la fila es clicable a través de los <label> y un festivo desmarcado se
   apaga, para que se vea de un vistazo cuáles cuentan. */
.tabla th.casilla, .tabla td.casilla { width: 1%; padding-right: 4px; text-align: center; }
.tabla td.casilla input[type="checkbox"] { width: 16px; height: 16px; margin: 0; accent-color: var(--accent); vertical-align: middle; }
.tabla.festivos label { display: block; margin: 0; font-weight: 400; cursor: pointer; }
.tabla.festivos tr.excluido td { color: var(--text-secondary); text-decoration: line-through; }
.tabla.festivos tr.excluido td.casilla { text-decoration: none; }

.tabla input[type="text"] { font-size: 12.5px; padding: 5px 8px; }
.tabla input.corto { max-width: 92px; text-align: right; }

/* Un formulario que sigue a una tabla necesita aire: si no, su primera
   etiqueta se lee como una fila más de la tabla. */
.tabla-desplaza + form { margin-top: 18px; }

/* --- 13. Administración: filas con luz de estado --------------------------- */

.luz {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    white-space: nowrap;
}

.luz::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex: none;
    background: var(--text-tertiary);
}

.luz.activa      { color: var(--normal-texto); }
.luz.activa::before { background: var(--status-normal); }
.luz.pendiente   { color: var(--caution-texto); }
.luz.pendiente::before { background: var(--status-caution); }
.luz.inactiva    { color: var(--text-secondary); }
.luz.inactiva::before { background: var(--text-tertiary); }

.correo-usuario { color: var(--text-primary); word-break: break-all; }
.correo-usuario .rol-mini {
    display: block;
    font-size: 10.5px;
    color: var(--text-secondary);
    margin-top: 1px;
}

/* --- 14. Calendario --------------------------------------------------------
   El color dice de qué clase fue el día. La zona especial va como triángulo en
   la esquina y NO como fondo, para que un festivo con desplazamiento pueda
   enseñar las dos cosas a la vez. */

.calendario-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 0 0 12px;
}

.calendario-nav .mes-actual {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.calendario-nav a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    background: var(--bg-surface-raised);
    border: 1px solid var(--border-strong);
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1;
}
.calendario-nav a:hover { color: var(--text-primary); border-color: var(--text-secondary); text-decoration: none; }
.calendario-nav .grupo { display: flex; gap: 3px; }

.calendario {
    width: 100%;
    border-collapse: separate;
    border-spacing: 3px;
    table-layout: fixed;
}

.calendario th {
    padding: 0 0 3px;
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: var(--text-secondary);
    text-align: center;
}
.calendario th abbr { text-decoration: none; border: 0; }

.calendario td { padding: 0; }
.calendario td.hueco { background: none; border: 0; }

.calendario .dia {
    position: relative;
    background: var(--bg-surface-raised);
    border: 1px solid var(--border);
}

.calendario .celda {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    padding: 2px;
    color: var(--text-secondary);
    text-decoration: none;
}
.calendario a.celda:hover { text-decoration: none; }

.calendario .numero {
    font-family: var(--cifras);
    font-size: 11px;
    line-height: 1.2;
}

.calendario .horas {
    font-family: var(--cifras);
    font-variant-numeric: tabular-nums;
    font-size: 8.5px;
    line-height: 1.2;
    margin-top: 1px;
}

/* Estado del día. */
.dia-extra      { border-color: var(--status-normal) !important; background: var(--status-normal-dim) !important; }
.dia-extra .horas, .dia-extra .numero { color: var(--normal-texto); }

.dia-festivo    { border-color: var(--status-stop) !important; background: var(--status-stop-dim) !important; }
.dia-festivo .horas, .dia-festivo .numero { color: var(--stop-texto); }

.dia-registrado { border-color: var(--border-strong) !important; background: var(--bg-surface-raised) !important; }
.dia-registrado .numero { color: var(--text-secondary); }

.dia-vacio      { background: var(--bg-surface) !important; }
.dia-vacio .numero { color: var(--text-secondary); }

/* Festivo del usuario que aún no tiene parte: el mismo rojo que el festivo
   apuntado, pero sólo en el borde —a trazos— y en la cifra. Sin relleno, para
   que se distinga de un día ya guardado como festivo y quede claro que es una
   propuesta del calendario, no un dato. */
.dia-festivo-libre { border: 1px dashed var(--status-stop) !important; background: var(--bg-surface) !important; }
.dia-festivo-libre .numero { color: var(--stop-texto); }

/* Vacaciones: el azul del acento, que no usa ningún otro tipo de día. Relleno
   pleno, como lo guardado, porque es una decisión del usuario y no una
   propuesta del calendario. Además lleva escrito «vac», para leerse en gris. */
.dia-vacaciones { border-color: var(--accent) !important; background: var(--accent-dim) !important; }
.dia-vacaciones .numero, .dia-vacaciones .horas { color: var(--accent-fuerte); }

/* El triángulo de zona va superpuesto: no toca el fondo del día. */
.dia-zona::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    border-style: solid;
    border-width: 0 8px 8px 0;
    border-color: transparent var(--status-caution) transparent transparent;
    pointer-events: none;
}

.calendario .es-hoy { border-color: var(--accent) !important; border-width: 2px; }

.calendario a.celda:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.leyenda {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 12px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    list-style: none;
}

.leyenda li {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 10.5px;
    color: var(--text-secondary);
}

.leyenda .muestra { width: 9px; height: 9px; flex: none; border: 0; }
.leyenda .muestra.dia-extra      { background: var(--status-normal) !important; }
.leyenda .muestra.dia-festivo    { background: var(--status-stop) !important; }
.leyenda .muestra.dia-registrado { background: var(--border-strong) !important; }
.leyenda .muestra.dia-vacio      { background: var(--bg-surface-raised) !important; border: 1px solid var(--border) !important; }
.leyenda .muestra.dia-vacaciones { background: var(--accent) !important; }
/* Un [hidden] tiene que esconder aunque la clase diga display: … — si no,
   un botón con .boton seguiría viéndose con el atributo puesto. */
[hidden] { display: none !important; }

/* --- Selector de vacaciones (Fase 14) ------------------------------------ */
.selector-barra {
    margin: 0 0 12px;
    padding: 10px 12px;
    border: 1px solid var(--accent);
    background: var(--accent-dim);
}
.selector-barra p { margin: 0 0 8px; }
.selector-barra .acciones { margin: 0; }

.calendario.selector .pasado { opacity: 0.45; }
.calendario.seleccionando a.celda { cursor: pointer; }

/* El inicio, el rango bajo el dedo y el fin. En blanco y no en azul: el azul
   ya es «vacaciones puestas», y la selección no puede confundirse con ellas.
   Con !important porque los fondos de tipo de día también lo llevan; sin él
   no se vería la selección sobre un festivo o un día con parte. */
.calendario .sel-rango  { border: 2px solid var(--text-primary) !important; }
.calendario .sel-inicio,
.calendario .sel-fin    { background: var(--text-primary) !important; border-color: var(--text-primary) !important; }
.calendario .sel-inicio .numero,
.calendario .sel-fin .numero,
.calendario .sel-inicio .horas,
.calendario .sel-fin .horas { color: var(--bg-void) !important; font-weight: 700; }
.leyenda .muestra.seleccion { background: var(--text-primary) !important; }

/* Listado de vacaciones por bloques de días seguidos. Cada fila lleva
   debajo otra a todo el ancho con las acciones en un desplegable: así los
   formularios no abren una cuarta columna que en el móvil se salía de la
   pantalla, y no llenan la lista hasta que se necesitan. */
.lista-vacaciones tr.con-detalle td { border-bottom: 0; padding-bottom: 2px; }
.lista-vacaciones tr.detalle > td { padding-top: 0; }
.lista-vacaciones details > summary {
    cursor: pointer;
    font-size: 12px;
    color: var(--accent-sobre-panel);
    padding: 2px 0 6px;
}
.lista-vacaciones details[open] > summary { margin-bottom: 6px; }
.lista-vacaciones .acciones { flex-wrap: wrap; }
.lista-vacaciones .boton { white-space: nowrap; }
.lista-vacaciones input[type="text"] { flex: 1 1 140px; min-width: 0; max-width: 220px; }

.dias-bloque { list-style: none; margin: 0 0 10px; padding: 0; }
.dias-bloque li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 12px;
    padding: 8px 10px;
    background: var(--bg-surface-raised);
    border-bottom: 1px solid var(--border);
}
.dias-bloque li .acciones { margin: 0; }
.dia-bloque { white-space: nowrap; }

.leyenda .muestra.rango { height: 3px; background: var(--accent-fuerte); }

/* Días de un mismo rango (Fase 13): una franja por debajo que se prolonga
   sobre el hueco entre casillas cuando la vecina es del mismo rango, para que
   el bloque se lea de un vistazo. Va en ::before porque ::after es de la zona. */
.dia-rango::before {
    content: '';
    position: absolute;
    left: 3px;
    right: 3px;
    bottom: 3px;
    height: 3px;
    background: var(--accent-fuerte);
    pointer-events: none;
}
.dia-rango.une-izq::before { left: -4px; }
.dia-rango.une-der::before { right: -4px; }
.leyenda .muestra.dia-festivo-libre { background: none !important; border: 1px dashed var(--status-stop) !important; }

.leyenda .muestra.zona {
    width: 0;
    height: 0;
    background: none;
    border-right: 9px solid var(--status-caution);
    border-bottom: 9px solid transparent;
}

/* --- 15. Utilidades y anchos ----------------------------------------------- */

.mono,
.cifra {
    font-family: var(--cifras);
    font-variant-numeric: tabular-nums;
}

.indice {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 22px;
}

.indice a {
    padding: 5px 9px;
    border: 1px solid var(--border);
    background: var(--bg-surface);
    color: var(--text-secondary);
    font-size: 11px;
    letter-spacing: 0.03em;
}
.indice a:hover { color: var(--text-primary); border-color: var(--border-strong); text-decoration: none; }

.pie {
    max-width: 420px;
    margin: 28px auto 0;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    text-align: center;
    font-size: 10.5px;
    color: var(--text-secondary);
}

/* La marca en las páginas sin sesión, donde no hay cabecera que la lleve. */
.marca-suelta {
    margin: 0 0 20px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text-primary);
}
.marca-suelta span { color: var(--text-secondary); font-weight: 400; }

.pie-formulario {
    margin: 16px 0 0;
    text-align: center;
    font-size: 12px;
    color: var(--text-secondary);
}
.pie-formulario a { text-decoration: underline; }

section { margin: 0 0 8px; }

/* --- Escritorio ------------------------------------------------------------
   El uso real es el móvil, así que arriba está todo pensado para una columna
   estrecha. Aquí sólo se ensancha lo que gana con el sitio: las páginas de
   trabajo, la cabecera y las tablas. */

@media (min-width: 720px) {
    body { padding: 28px 20px 56px; font-size: 14.5px; }

    .contenido,
    .cabecera,
    .pie { max-width: 760px; }

    .panel { padding: 22px 20px 20px; }

    .lecturas { gap: 16px; }
    .lectura .val { font-size: 24px; }

    .tabla th, .tabla td { padding: 12px 14px; }

    .panel > .tabla-desplaza.sin-marco { margin: 4px -20px -20px; width: calc(100% + 40px); }

    h1 { font-size: 21px; }

    /* Con sitio, el envío principal deja de ocupar todo el ancho. */
    .boton.ancho { width: auto; min-width: 220px; }

    .calendario { border-spacing: 4px; }
    .calendario .numero { font-size: 12px; }
    .calendario .horas { font-size: 9.5px; }
}

@media (min-width: 1040px) {
    .contenido.amplio,
    .cabecera.amplio,
    .pie.amplio { max-width: 1000px; }
}

/* Quien haya pedido menos movimiento, que no lo tenga. */
@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; animation: none !important; }
}
