@charset "UTF-8";

/* ============================================================================
   CitaBot — hoja de estilo del panel
   ============================================================================

   La idea de la que sale todo: este panel no se contempla, se consulta. Quien
   lo abre es la recepcionista de una clínica o la dueña de un centro de uñas,
   con alguien esperando delante, y tiene UNA pregunta: "¿hay algo que necesite
   que yo intervenga?". Todo lo demás es ruido.

   ── El raíl ──
   De esa pregunta sale el único recurso visual del proyecto: una barra
   vertical que representa la atención continua del agente. Aparece en la
   navegación, en cada fila de conversación y en cada burbuja de mensaje, y
   siempre significa lo mismo:

       petróleo  →  el bot lo está llevando
       ámbar     →  hace falta una persona

   El color no decora: dice quién está hablando. Por eso son sólo dos, y por
   eso el rojo no aparece — que un cliente pida hablar con alguien no es una
   emergencia, es trabajo normal.

   ── La apuesta ──
   No hay tarjetas con sombra en ningún sitio. Toda la estructura se construye
   con raíles y filetes. Es una restricción incómoda y deliberada: si el raíl
   es el que carga el significado, hacerlo el ÚNICO recurso estructural impide
   que se pierda entre cajas flotantes.

   ── CSP ──
   La política de seguridad prohíbe estilos en línea (`style-src 'self'`, sin
   'unsafe-inline'). Aquí no hay ni un atributo `style=`: todo lo que varía se
   expresa con clases o con atributos `data-`. Si alguna vez hace falta un
   valor calculado, la salida es una clase más, nunca abrir la política.
   ========================================================================= */

:root {
    /* ── Color ─────────────────────────────────────────────────────────── */
    --tinta:        #16202a;   /* texto y estructura: pizarra muy oscura     */
    /* Oscurecido de #47576a: sobre el fondo del menú daba 4,01:1 y el listón
       para texto normal es 4,5. Lo llevaba así desde el principio; se vio al
       medir los dos temas. */
    --tinta-suave:  #3e4b5c;
    /* Un punto más oscuro de lo que pedía el ojo: la hora de un mensaje
       sobre la burbuja de color se quedaba en 4,4987:1. */
    --apagado:      #5c6b79;   /* metadatos, horas, cosas de segundo plano   */
    --papel:        #f1f4f6;   /* fondo: gris frío, no crema                 */
    --superficie:   #ffffff;
    --borde:        #dce3e8;
    --filete:       #e8edf1;

    --petroleo:     #0e5c63;   /* el bot atiende                             */
    --petroleo-luz: #e4f0f1;
    --ambar:        #a35d09;   /* te espera a ti                             */
    --ambar-luz:    #fbf0df;

    /* ── Tipografía ────────────────────────────────────────────────────────
       Sin fuente web, y a propósito: el alojamiento lleva un CDN delante y la
       política de seguridad es cerrada, así que una fuente externa costaría
       una petición más y un agujero en la CSP a cambio de poco. La identidad
       la pone otra cosa: las HORAS, los TELÉFONOS y los IDENTIFICADORES van
       en monoespaciada. En una herramienta de agenda los números son el
       contenido, y en mono se alinean en columna y se leen de un vistazo. */
    --texto: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --dato:  ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace;

    /* ── Ritmo ─────────────────────────────────────────────────────────── */
    --u: 0.5rem;

    /*
     * Tres radios, y ninguno de 3 píxeles.
     *
     * Estaba todo a `--radio: 3px`. Con esa esquina, por mucho que cambie la
     * paleta y por mucha sombra que se ponga, cada tarjeta sigue leyéndose
     * como una celda de tabla: el ojo distingue «panel de administración» de
     * «superficie» sobre todo por la curvatura del canto. Un cristal templado
     * de verdad tiene el canto redondeado, y por eso el efecto no se veía.
     *
     * `--radio` es lo normal —campos, botones, avisos—, `--radio-l` es para
     * las láminas grandes, y `--pastilla` para lo que es una etiqueta y debe
     * leerse como tal.
     */
    --radio: 10px;
    --radio-l: 16px;
    --pastilla: 999px;

    --rail: 3px;
    --nav: 208px;

    /* ── Cristal templado ──────────────────────────────────────────────────
       El lavado de color del fondo y el esmerilado de la barra flotante. Van
       como variables para que el modo oscuro los cambie sin repetir reglas. */
    /* Estaban al 7% y al 6% y sobre el papel claro no se veían: se pintó un
       tratamiento que en el tema que se usa de día no existía. Subidos hasta
       que el suelo tiene color de verdad — sin acercarse al texto, que aquí
       va siempre sobre superficie opaca. */
    --lavado-1: color-mix(in srgb, var(--petroleo) 16%, transparent);
    --lavado-2: color-mix(in srgb, var(--ambar) 14%, transparent);
    --cristal:  color-mix(in srgb, var(--superficie) 74%, transparent);
    --cristal-borde: color-mix(in srgb, var(--tinta) 10%, transparent);
    --lamina:
        0 1px 2px -1px color-mix(in srgb, var(--petroleo) 22%, transparent),
        0 10px 22px -14px color-mix(in srgb, var(--petroleo) 34%, transparent);
    --lamina-1: color-mix(in srgb, var(--petroleo) 6%, transparent);
    --lamina-2: color-mix(in srgb, var(--ambar) 7%, transparent);

    --aviso-mal-texto:  #6f3f06;
    --aviso-bien-texto: #0a474d;
    --boton-tinta:      #ffffff;
    --petroleo-hover:   #0a474d;
}

/* ═══════════════════════ Modo oscuro ═══════════════════════════════════════
   Navy dominante y azul digital de acento, con un cálido de apoyo. El azul
   solo no vale: en este panel el color dice QUÉ PASA —uno «lo lleva el bot»,
   otro «te espera a ti»— y dos tonos de la misma familia fría no se
   distinguen de un vistazo, que es la única forma en que se mira esto.

   No es el claro invertido. Cada token se ha vuelto a elegir: sobre navy, el
   #1A8CFF de la propuesta da 5,9:1 y se lee; sobre blanco daría 3,2:1 y no
   valdría para texto. Por eso el acento del claro sigue siendo el petróleo.

   El tema lo pone PHP en el <html>, así que la página nace ya en su color y
   no parpadea. Ver includes/tema.php. */
[data-tema="oscuro"] {
    --tinta:        #f4f6f9;
    --tinta-suave:  #c6d3e0;
    --apagado:      #8496a6;
    --papel:        #0b132b;   /* el navy dominante                          */
    --superficie:   #0d1b2a;
    --borde:        #22344a;
    --filete:       #1a2a3c;

    --petroleo:     #1A8CFF;   /* el bot atiende                             */
    --petroleo-luz: #102c46;
    --ambar:        #FF9B54;   /* te espera a ti                             */
    --ambar-luz:    #33231a;

    --lavado-1: color-mix(in srgb, var(--petroleo) 10%, transparent);
    --lavado-2: color-mix(in srgb, var(--ambar) 7%, transparent);
    --cristal:  color-mix(in srgb, var(--superficie) 78%, transparent);
    --cristal-borde: color-mix(in srgb, #ffffff 12%, transparent);
    /* En oscuro sí hay canto de luz: sobre navy, un blanco muy bajo dibuja el
       borde de arriba de la lámina. Y la sombra se hace negra, porque una
       sombra azul sobre navy no se ve. */
    --lamina:
        inset 0 1px 0 0 rgb(255 255 255 / 0.06),
        0 1px 2px -1px rgb(0 0 0 / 0.5),
        0 10px 22px -14px rgb(0 0 0 / 0.65);
    /* Sobre navy el lavado tiene que ACLARAR, no teñir: un tinte oscuro sobre
       oscuro no se ve, y uno saturado ensucia. */
    --lamina-1: color-mix(in srgb, var(--petroleo) 9%, transparent);
    --lamina-2: color-mix(in srgb, var(--ambar) 5%, transparent);

    --aviso-mal-texto:  #ffd2ae;
    --aviso-bien-texto: #b6d9ff;
    --boton-tinta:      #06131f;   /* navy sobre azul: 8,1:1 */
    /* Y el hover ACLARA. Oscurecer sobre un fondo oscuro acerca el botón al
       fondo en vez de destacarlo: el gesto tiene que ir siempre hacia el
       contraste, y hacia dónde es eso depende del tema. */
    --petroleo-hover:   #4dabff;

    color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: var(--texto);
    font-size: 15px;
    line-height: 1.55;
    color: var(--tinta);
    background: var(--papel);
    -webkit-font-smoothing: antialiased;
}

a { color: var(--petroleo); }
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible {
    outline: 2px solid var(--petroleo);
    outline-offset: 2px;
    border-radius: 1px;
}

/* ============================ Estructura ================================= */

.armazon {
    display: grid;
    grid-template-columns: var(--nav) minmax(0, 1fr);
    min-height: 100vh;
}

/* ── Navegación ─────────────────────────────────────────────────────────
   Fija a la izquierda. El elemento activo no se marca con fondo sino con el
   raíl, igual que una conversación activa: mismo recurso, mismo significado
   ("aquí es donde está pasando algo"). */
.nav {
    background: var(--superficie);
    border-right: 1px solid var(--borde);
    padding: calc(var(--u) * 3) 0;
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
}

/*
 * La marca: el simbolo y la palabra.
 *
 * En CLARO el simbolo lleva su cuadrado navy, igual que el logo que se manda
 * fuera. En OSCURO el cuadrado se cae y queda la burbuja sola.
 *
 * No es un apano: es la version invertida, la que tiene cualquier sistema de
 * marca. El cuadrado existe para separar la marca de un fondo AJENO -Meta, una
 * factura, la web-; sobre nuestro propio navy no separa de nada, y navy sobre
 * navy sencillamente desaparece.
 *
 * El resplandor azul se reserva para el hover. Encendido siempre, en la
 * esquina que alguien mira ocho horas al dia, es un iman de atencion que no se
 * apaga nunca.
 */
/*
 * `.nav a.marca` y no `.marca` a secas, ni siquiera `a.marca`.
 *
 * `.nav a` es clase + elemento, asi que le gana a una clase suelta. Y `a.marca`
 * empata con ella, con lo que decide el orden del fichero — y este bloque esta
 * ANTES, de modo que perdia igual. Con `.nav a.marca` la regla gana por
 * especificidad y deja de depender de donde este escrita, que es lo unico que
 * no se rompe cuando alguien reordena el CSS.
 *
 * Hay un aviso sobre esta misma trampa al final del fichero, en la regla de
 * movil. Escrito el aviso, y caido en ella dos veces seguidas.
 *
 * El margen se pone a cero a mano: la pastilla de los enlaces del menu lo
 * hereda de `.nav a`, y la marca no es un enlace del menu.
 */
.nav a.marca {
    display: flex;
    align-items: center;
    gap: calc(var(--u) * 1.25);
    margin: 0;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.02em;
    /*
     * Con aire arriba, y no pegada al canto.
     *
     * Antes el relleno superior era cero y bastaba: era una palabra, y una
     * palabra pesa poco. El simbolo es un cuadrado macizo y pesa mucho mas, asi
     * que el mismo hueco se lee apretado. Es lo de siempre con el espaciado:
     * no se mide en pixeles, se mide en cuanto ocupa lo que hay al lado.
     */
    padding: calc(var(--u) * 1.5) calc(var(--u) * 2.5) calc(var(--u) * 3.5);
    color: var(--tinta);
    text-decoration: none;
}

/*
 * La marca NO se ilumina al pasar por encima.
 *
 * `.nav a:hover` le pone fondo a todos los enlaces del menu, y eso esta bien
 * para «Conversaciones» o «Citas» —son sitios a los que vas— pero la marca no
 * es un destino, es la identidad. Encenderla como si fuera una opcion mas la
 * degrada a boton.
 *
 * Lo que si responde al raton es el simbolo, con su resplandor azul. Ahi si
 * tiene sentido: dice «esto es pulsable» sin fingir que es un item del menu.
 */
.nav a.marca:hover { background: none; }
/* Acotado a la palabra: `.marca span` a secas atrapaba tambien los del simbolo. */
.marca-texto span { color: var(--petroleo); }

.marca-simbolo {
    flex: none;
    width: 1.75em;
    height: 1.75em;
    border-radius: 0.34em;
    display: grid;
    place-items: center;
    background-color: #0b132b;
    background-image:
        radial-gradient(52% 48% at 70% 26%, rgba(26, 140, 255, 0.72), transparent 66%);
    transition: box-shadow 0.18s ease;
}

/*
 * La burbuja, con su rabito y su esquina de quien habla.
 *
 * Mas grande dentro del cuadrado que en el icono de 1024 px. La proporcion que
 * respira bien en grande se queda mezquina a 26 px: el ojo necesita mas figura
 * y menos margen cuando hay pocos pixeles. Es el mismo ajuste optico por el que
 * un favicon nunca es el logo reducido.
 */
.marca-burbuja {
    position: relative;
    width: 62%;
    height: 52%;
    background: #f4f6f9;
    border-radius: 24% 24% 0 24%;
}
.marca-burbuja::after {
    content: '';
    position: absolute;
    right: 0;
    bottom: -16%;
    width: 24%;
    height: 16%;
    background: #f4f6f9;
    clip-path: polygon(100% 0, 100% 70%, 50% 100%, 0 0);
}
.marca-burbuja svg {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 54%;
    height: auto;
}

/* En oscuro: fuera el cuadrado, y la burbuja crece para ocupar su sitio. */
[data-tema="oscuro"] .marca-simbolo {
    background-color: transparent;
    background-image: none;
}
[data-tema="oscuro"] .marca-burbuja { width: 82%; height: 70%; }

/*
 * El resplandor, solo al pasar por encima, y distinto en cada tema.
 *
 * En CLARO lleva un filo de 1 px ademas de la luz: hay un cuadrado navy macizo
 * y el filo le cine el canto.
 *
 * En OSCURO el cuadrado no existe, asi que ese mismo filo dibujaba un marco
 * alrededor de nada y se leia como una caja que aparece de golpe. Ahi va solo
 * la luz difusa, que es lo que se queria: que la marca se encienda, no que se
 * enmarque.
 */
.marca:hover .marca-simbolo {
    box-shadow: 0 0 0 1px rgba(26, 140, 255, 0.35), 0 0 14px 1px rgba(26, 140, 255, 0.35);
}
[data-tema="oscuro"] .marca:hover .marca-simbolo {
    box-shadow: 0 0 18px 4px rgba(26, 140, 255, 0.30);
}

.nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1;
}

/*
 * El activo es una pastilla metida hacia dentro, no una franja a sangre.
 *
 * Iba de canto a canto con una barra pegada al borde izquierdo, que es el
 * gesto de una tabla. Recogido y redondeado se lee como lo que es —un botón
 * seleccionado— y deja de pelearse con el canto de la columna.
 */
.nav a {
    display: block;
    margin: 1px calc(var(--u) * 1.25);
    padding: calc(var(--u) * 1.25) calc(var(--u) * 1.5);
    color: var(--tinta-suave);
    text-decoration: none;
    font-size: 0.925rem;
    border-radius: var(--radio);
}
.nav a:hover { color: var(--tinta); background: var(--papel); }
.nav a[aria-current="page"] {
    color: var(--tinta);
    font-weight: 600;
    background: color-mix(in srgb, var(--petroleo) 12%, var(--superficie));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--petroleo) 22%, transparent);
}

.nav-pie {
    padding: calc(var(--u) * 2) calc(var(--u) * 2.5) 0;
    border-top: 1px solid var(--filete);
    font-size: 0.8rem;
    color: var(--apagado);
}
.nav-pie a { color: var(--apagado); }

/* ── Cabecera del contenido ────────────────────────────────────────────── */
.principal { min-width: 0; }

.encabezado {
    background: var(--superficie);
    border-bottom: 1px solid var(--borde);
    padding: calc(var(--u) * 3) calc(var(--u) * 4) calc(var(--u) * 2);
}

.encabezado h1 {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 650;
    letter-spacing: -0.021em;
}

.negocio {
    font-size: 0.8rem;
    color: var(--apagado);
    margin: 0 0 calc(var(--u) * 0.5);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    font-weight: 600;
}

/* ── El estado del turno ────────────────────────────────────────────────
   La tesis del producto, dicha en una línea y en cada página: qué está
   haciendo el bot ahora mismo y cuántos te esperan. Es lo primero que quiere
   saber quien abre esto. */
.turno {
    display: flex;
    flex-wrap: wrap;
    gap: calc(var(--u) * 3);
    margin-top: calc(var(--u) * 2);
    font-size: 0.875rem;
}
.turno span {
    display: inline-flex;
    align-items: baseline;
    gap: calc(var(--u));
    border-left: var(--rail) solid var(--borde);
    padding-left: calc(var(--u) * 1.5);
    color: var(--tinta-suave);
}
.turno .cuenta {
    font-family: var(--dato);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--tinta);
    font-variant-numeric: tabular-nums;
}
.turno .atiende { border-left-color: var(--petroleo); }
.turno .espera  { border-left-color: var(--ambar); }
.turno .espera .cuenta { color: var(--ambar); }

.cuerpo { padding: calc(var(--u) * 4); }

/* ============================ Bloques ==================================== */

/*
 * Las tarjetas son láminas, no cajas.
 *
 * En claro el vidrio no se puede contar con un canto de luz: la tarjeta ya es
 * blanca y un brillo blanco encima no se ve. Se cuenta con la SOMBRA, y teñida
 * del petróleo de la marca en vez de gris — una sombra gris sobre un suelo con
 * color se ve sucia. Dos capas: una corta que asienta el borde y una larga y
 * muy suave que separa la lámina del suelo.
 *
 * El cuerpo se queda OPACO. Dentro hay horas, nombres y teléfonos que se leen
 * cien veces al día, y una superficie translúcida cambia de contraste con lo
 * que pase por debajo.
 */
.bloque {
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio-l);
    margin-bottom: calc(var(--u) * 3);
    box-shadow: var(--lamina);
    /* El redondeo del contenedor tiene que recortar lo de dentro, o la
       cabecera de la tarjeta le saca las esquinas cuadradas por debajo. */
    overflow: hidden;
}

.bloque > h2 {
    margin: 0;
    padding: calc(var(--u) * 2) calc(var(--u) * 3);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--apagado);
    border-bottom: 1px solid var(--filete);
    font-weight: 600;
}

.bloque > .contenido { padding: calc(var(--u) * 3); }

/*
 * `.tarjeta`: la misma lámina que `.bloque` —fondo, borde, radio y sombra—
 * pero sin la cabecera separada ni el envoltorio `.contenido`, porque el
 * retraso no tiene esas dos partes: el `<h2>` y el formulario van directos
 * dentro y se les da el padding aquí mismo. Ninguna variable nueva: son las
 * mismas con las que ya se pintan el resto de tarjetas del panel.
 */
.tarjeta {
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio-l);
    margin-bottom: calc(var(--u) * 3);
    box-shadow: var(--lamina);
    padding: calc(var(--u) * 3);
}

.tarjeta > h2 {
    margin: 0 0 calc(var(--u) * 2);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--apagado);
    font-weight: 600;
}

/* ── El retraso, arriba de «Hoy» ────────────────────────────────────────
   Va con borde marcado a propósito: es lo único de la página que se toca
   con prisa, y tiene que encontrarse sin leer. */
.retraso { border-left: var(--rail) solid var(--petroleo); }

.lista-afectados { list-style: none; margin: calc(var(--u) * 2) 0; padding: 0; }
.lista-afectados li { padding: calc(var(--u) * 0.75) 0; border-bottom: 1px solid var(--borde); }
.lista-afectados label { display: flex; align-items: center; gap: calc(var(--u) * 1); cursor: pointer; }

.etiqueta { font-size: 0.78rem; color: var(--apagado); }

.retrasos-vigentes { list-style: none; margin: calc(var(--u) * 2) 0 0; padding: 0; }
.retrasos-vigentes li { display: flex; align-items: center; gap: calc(var(--u) * 1.5); }
.en-linea { display: inline; }

.explica {
    color: var(--tinta-suave);
    font-size: 0.9rem;
    margin: 0 0 calc(var(--u) * 2);
    max-width: 62ch;
}

/* ── Lista de conversaciones ────────────────────────────────────────────
   Aquí es donde el raíl gana su sueldo: se puede recorrer la lista con la
   vista y saber cuáles necesitan una persona sin leer una palabra. */
.hilos { list-style: none; margin: 0; padding: 0; }

.hilos li { border-bottom: 1px solid var(--filete); }
.hilos li:last-child { border-bottom: 0; }

/*
 * El raíl es una marca metida hacia dentro, no un borde del elemento.
 *
 * Como `border-left` se cortaba contra el canto redondeado de la tarjeta y se
 * veía como una costura suelta, sobre todo el discontinuo. Puesto como barra
 * propia, con sus extremos redondeados, se lee como lo que es: una marca al
 * margen de la fila.
 */
.hilo {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: calc(var(--u) * 2);
    padding: calc(var(--u) * 2) calc(var(--u) * 3);
    text-decoration: none;
    color: inherit;
}
.hilo::before {
    content: '';
    position: absolute;
    left: calc(var(--u) * 1.25);
    top: calc(var(--u) * 1.5);
    bottom: calc(var(--u) * 1.5);
    width: var(--rail);
    border-radius: var(--pastilla);
    background: var(--petroleo);
}
.hilo:hover { background: var(--papel); }

/* Bot desactivado: el raíl se interrumpe. La atención continua se ha roto y
   hay alguien esperando a una persona. */
.hilo.a-mano { background: var(--ambar-luz); }
.hilo.a-mano::before {
    background: repeating-linear-gradient(
        to bottom, var(--ambar) 0 6px, transparent 6px 11px);
}
.hilo.a-mano:hover { background: #f8e9d2; }

/* Nombre y último mensaje van apilados, no en la misma línea: son dos datos
   distintos y en una sola línea el mensaje parece parte del nombre. */
.hilo .quien,
.hilo .ultimo { display: block; }

.hilo .quien { font-weight: 600; }
.hilo .ultimo {
    color: var(--apagado);
    font-size: 0.9rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hilo .cuando {
    font-family: var(--dato);
    font-size: 0.8rem;
    color: var(--apagado);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ============================ La bandeja ================================= */

.bandeja {
    display: grid;
    grid-template-columns: 21rem minmax(0, 1fr);
    gap: calc(var(--u) * 3);
    align-items: start;
}

.lista-hilos {
    max-height: calc(100vh - 14rem);
    overflow-y: auto;
    position: sticky;
    top: calc(var(--u) * 3);
}

/* El hilo abierto se marca con el raíl más grueso, no con otro color: sigue
   diciendo quién lo lleva, y además que es el que estás mirando. */
.hilo.abierta {
    background: var(--papel);
    border-left-width: 6px;
}

.hilo-abierto {
    display: flex;
    flex-direction: column;
    min-height: calc(100vh - 14rem);
}

.hilo-cabecera {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: calc(var(--u) * 2);
    flex-wrap: wrap;
    padding: calc(var(--u) * 2) calc(var(--u) * 3);
    border-bottom: 1px solid var(--filete);
}
.hilo-cabecera .mono { color: var(--apagado); font-size: 0.85rem; }
.hilo-cabecera form { margin: 0; }

/* Sólo aparece en móvil, donde la lista se esconde al abrir un hilo. */
.volver-lista { display: none; margin-right: calc(var(--u)); font-size: .9rem; }

/* ── Las burbujas ──────────────────────────────────────────────────────
   Quien escribe se distingue por el color del raíl, igual que en la lista y
   por lo mismo: petróleo cuando lo lleva el bot, ámbar cuando hay una
   persona detrás. El cliente no lleva raíl — no está "atendiendo", está
   hablando. */
.burbujas {
    flex: 1;
    overflow-y: auto;
    padding: calc(var(--u) * 3);
    display: flex;
    flex-direction: column;
    gap: calc(var(--u) * 1.5);
    max-height: calc(100vh - 22rem);
}

.burbujas .dia {
    align-self: center;
    margin: calc(var(--u) * 1.5) 0 calc(var(--u) * 0.5);
    font-family: var(--dato);
    font-size: 0.75rem;
    color: var(--apagado);
    background: var(--papel);
    padding: 2px calc(var(--u) * 1.5);
    border-radius: var(--pastilla);
}

.burbuja {
    max-width: min(74%, 27rem);
    padding: calc(var(--u) * 1.5) calc(var(--u) * 2);
    /* Redondeada salvo la esquina de quien habla: es lo que hace que se lea
       como un bocadillo y no como una fila. La dirección la pone cada clase. */
    border-radius: var(--radio-l);
    /*
     * `pre-line` y no `pre-wrap`, y la diferencia se veía a simple vista: con
     * pre-wrap se conservaba también la sangría de la propia plantilla PHP, y
     * la primera línea de cada mensaje salía metida hacia dentro. `pre-line`
     * colapsa esos espacios sobrantes pero respeta los saltos de línea que
     * escribió el cliente, que es exactamente lo que hace falta.
     *
     * Además evita tener que convertirlos a <br>, o sea, evita construir HTML
     * con texto de un desconocido.
     */
    white-space: pre-line;
    overflow-wrap: anywhere;
    font-size: 0.94rem;
    line-height: 1.5;
    position: relative;
}

/* Un mensaje que no llegó. Va dentro de la burbuja, pegado a lo que no se
   entregó, y en el color de aviso: puesto en otro sitio habría que buscar a
   cuál de los mensajes se refiere. */
.no-llego {
    display: block;
    margin-top: calc(var(--u) * 0.5);
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--aviso-mal-texto);
    background: var(--ambar-luz);
    border-radius: var(--pastilla);
    padding: 2px calc(var(--u) * 1.25);
}

.burbuja .hora {
    display: block;
    margin-top: calc(var(--u) * 0.5);
    font-family: var(--dato);
    font-size: 0.7rem;
    color: var(--apagado);
}

/*
 * Quién habla se dice con el LADO y con el relleno, no con un filete.
 *
 * Cada burbuja llevaba una barra de 3px pegada al canto derecho. Con la
 * esquina redondeada esa barra se corta a media curva y se ve como un
 * desconchón; y además no aportaba nada: el lado ya dice si es el cliente o
 * la casa, el color ya dice si es el bot o una persona, y el mensaje humano
 * lleva encima su «TÚ» escrito. Tres señales para lo mismo eran dos de más.
 */
.burbuja.contacto {
    align-self: flex-start;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-bottom-left-radius: calc(var(--u) * 0.75);
}

.burbuja.bot {
    align-self: flex-end;
    background: var(--petroleo-luz);
    border-bottom-right-radius: calc(var(--u) * 0.75);
}

.burbuja.humano {
    align-self: flex-end;
    background: var(--ambar-luz);
    border-bottom-right-radius: calc(var(--u) * 0.75);
}
/*
 * Los avisos automáticos (recordatorio, cita movida o anulada, retraso) van
 * del lado de la casa pero sin el «tú»: no los escribió el dueño. Hasta el
 * 12-oct-2026 se guardaban como `humano` y salían firmados por él.
 */
.burbuja.sistema {
    align-self: flex-end;
    background: var(--superficie);
    border: 1px dashed var(--borde);
    border-bottom-right-radius: calc(var(--u) * 0.75);
}
.burbuja.sistema::after {
    content: 'aviso automático';
    position: absolute;
    top: calc(var(--u) * 0.5);
    right: calc(var(--u) * 1.5);
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--apagado);
    font-weight: 700;
}
.burbuja.humano::after {
    content: 'tú';
    position: absolute;
    top: calc(var(--u) * 0.5);
    right: calc(var(--u) * 1.5);
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ambar);
    font-weight: 700;
}

.responder {
    border-top: 1px solid var(--filete);
    padding: calc(var(--u) * 2) calc(var(--u) * 3);
}
.responder form {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: calc(var(--u) * 1.5);
    align-items: end;
}
.responder textarea { min-height: 3.5rem; }
.responder .aviso { margin-bottom: 0; }

/* Para lectores de pantalla, sin ocupar sitio. */
.oculto-visual {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ============================ La semana ================================== */

.semana-barra {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: calc(var(--u) * 2);
    flex-wrap: wrap;
    padding: calc(var(--u) * 2) calc(var(--u) * 3);
    border-bottom: 1px solid var(--filete);
}
.semana-titulo { text-align: center; }
.semana-titulo .dato {
    display: block;
    font-size: 0.78rem;
    color: var(--apagado);
    font-family: var(--dato);
}

.semana {
    display: grid;
    grid-template-columns: repeat(7, minmax(9rem, 1fr));
    min-width: 63rem;
}

.dia-columna {
    border-right: 1px solid var(--filete);
    padding: calc(var(--u) * 1.5);
    min-height: 12rem;
}
.dia-columna:last-child { border-right: 0; }

/* Hoy se marca con el raíl, igual que todo lo demás que está pasando. */
.dia-columna.es-hoy {
    background: var(--papel);
    border-top: var(--rail) solid var(--petroleo);
}

.dia-cabecera {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin: 0 0 calc(var(--u) * 1.5);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--apagado);
    font-weight: 600;
}
.dia-cabecera .dato {
    font-family: var(--dato);
    font-size: 1rem;
    color: var(--tinta);
}

/* Decorativo: va con aria-hidden en el marcado, así que el mínimo de
   contraste no le aplica. Si algún día dijera algo, tendría que subir. */
.dia-vacio { color: var(--borde); margin: 0; text-align: center; }

.cita-tarjeta {
    display: block;
    text-decoration: none;
    color: inherit;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-left: var(--rail) solid var(--petroleo);
    border-radius: var(--radio);
    padding: calc(var(--u)) calc(var(--u) * 1.25);
    margin-bottom: calc(var(--u));
    font-size: 0.85rem;
}
.cita-tarjeta:hover { border-color: var(--petroleo); }
.cita-tarjeta .dato {
    display: block;
    font-family: var(--dato);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.cita-tarjeta .cita-quien {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cita-tarjeta .cita-servicio {
    display: block;
    color: var(--apagado);
    font-size: 0.78rem;
}

/* Una cita cancelada se deja a la vista, tachada, en vez de esconderla: dice
   algo que esconderla no dice — que ahí hubo algo y se cayó. Es lo mismo que
   hace CartaQR con un plato agotado. */
.cita-tarjeta.cancelada {
    border-left-color: var(--borde);
    opacity: 0.65;
}
.cita-tarjeta.cancelada .cita-quien { text-decoration: line-through; }
.cita-tarjeta.completada { border-left-color: var(--apagado); }

/* Un día cerrado: ni petróleo ni ámbar. El raíl dice quién ATIENDE, y aquí no
   atiende nadie — así que gris, y con el fondo rayado para que se distinga de
   un día simplemente vacío. */
.dia-columna.cerrado {
    background: repeating-linear-gradient(
        45deg,
        var(--papel), var(--papel) 6px,
        var(--filete) 6px, var(--filete) 12px
    );
}
.banda-cerrado {
    margin: 0 0 calc(var(--u));
    padding: calc(var(--u) * 0.5) calc(var(--u));
    background: var(--superficie);
    border-left: var(--rail) solid var(--apagado);
    border-radius: var(--radio);
    font-size: 0.78rem;
    color: var(--tinta-suave);
    font-weight: 600;
}

/* Como la banda de «cerrado», pero en el color de acento: no es una
   incidencia que impida trabajar, es un dato del día. */
.banda-retraso {
    font-size: 0.75rem;
    text-align: center;
    padding: calc(var(--u) * 0.5);
    color: var(--petroleo);
    border: 1px solid var(--petroleo);
    border-radius: 6px;
    margin-bottom: calc(var(--u) * 0.75);
}

/* Varios campos en una línea, para los formularios de fecha + hora. */
.fila-campos {
    display: flex;
    flex-wrap: wrap;
    gap: calc(var(--u) * 2);
}
.fila-campos .campo { flex: 1 1 12rem; max-width: 20rem; }

.casillas {
    display: flex;
    flex-wrap: wrap;
    gap: calc(var(--u) * 3);
    margin: calc(var(--u) * 2) 0;
    font-size: 0.92rem;
}
.casillas label { display: inline-flex; align-items: center; gap: calc(var(--u)); }

/* ── La ficha de una cita ──────────────────────────────────────────────
   Se abre con `:target`, sin JavaScript. El enlace apunta a #cita-N y esta
   regla la enseña; cualquier otro enlace la cierra. Encaja con una política
   que prohíbe scripts en línea, y de propina la ficha tiene URL propia. */
.ficha { display: none; }

.ficha:target {
    display: grid;
    place-items: center;
    position: fixed;
    inset: 0;
    z-index: 20;
    padding: calc(var(--u) * 3);
}

.ficha-fondo {
    position: absolute;
    inset: 0;
    background: rgba(22, 32, 42, 0.45);
}

.ficha-caja {
    position: relative;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio-l);
    box-shadow: var(--lamina);
    width: min(100%, 34rem);
    max-height: 90vh;
    overflow-y: auto;
}
.ficha-caja .contenido { padding: calc(var(--u) * 3); }
.ficha-caja hr { border: 0; border-top: 1px solid var(--filete); margin: calc(var(--u) * 3) 0; }

.ficha-cabecera {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: calc(var(--u) * 2);
    padding: calc(var(--u) * 2.5) calc(var(--u) * 3);
    border-bottom: 1px solid var(--filete);
}
.ficha-cabecera .negocio { margin-bottom: calc(var(--u) * 0.25); }

/* ── Etiquetas de estado ───────────────────────────────────────────────── */
.marca-estado {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 2px calc(var(--u) * 1.25);
    border-radius: var(--pastilla);
    border: 1px solid;
}
.marca-estado.activa    { background: var(--petroleo-luz); color: var(--petroleo); border-color: var(--petroleo); }
.marca-estado.atencion  { background: var(--ambar-luz);    color: var(--ambar);    border-color: var(--ambar); }
.marca-estado.neutra    { background: var(--papel);        color: var(--apagado);  border-color: var(--borde); }

/* ── Tablas ────────────────────────────────────────────────────────────── */
.tabla { width: 100%; border-collapse: collapse; font-size: 0.925rem; }
.tabla th {
    text-align: left;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--apagado);
    font-weight: 600;
    padding: calc(var(--u)) calc(var(--u) * 1.5);
    border-bottom: 1px solid var(--borde);
}
.tabla td {
    padding: calc(var(--u) * 1.5);
    border-bottom: 1px solid var(--filete);
    vertical-align: middle;
}
.tabla tr:last-child td { border-bottom: 0; }
.tabla .dato { font-family: var(--dato); font-variant-numeric: tabular-nums; font-size: 0.875rem; }

.envoltorio-tabla { overflow-x: auto; }

/* ── Formularios ───────────────────────────────────────────────────────── */
.campo { margin-bottom: calc(var(--u) * 2.5); max-width: 34rem; }
.campo.ancho { max-width: 52rem; }

/* Un campo pegado justo debajo de una tabla se lee como si fuera parte de
   ella. Un poco de aire y deja de confundirse. */
.envoltorio-tabla + .campo,
.envoltorio-tabla + form,
.tabla + .campo { margin-top: calc(var(--u) * 3); }

/* Las celdas de hora y de minutos: lo justo para el dato, y así la tabla de
   horarios cabe entera sin desbordar. */
.celda-corta { width: 7rem; }
.celda-corta input { text-align: center; }

.campo label {
    display: block;
    font-weight: 600;
    font-size: 0.875rem;
    margin-bottom: calc(var(--u) * 0.75);
}

/*
 * El texto de ayuda SIEMPRE en su propia línea, esté o no dentro de un .campo.
 *
 * Estaba limitado a .campo, así que el que va detrás de un botón salía en línea
 * y se enredaba alrededor de él: media frase a la derecha del botón y el resto
 * por debajo, cruzándolo. Una explicación que hay que reconstruir con la vista
 * no se lee.
 */
.ayuda {
    display: block;
    font-weight: 400;
    font-size: 0.8rem;
    color: var(--apagado);
    margin-top: calc(var(--u) * 0.5);
}

input[type="text"], input[type="email"], input[type="password"],
input[type="date"], select, textarea {
    width: 100%;
    padding: calc(var(--u) * 1.25) calc(var(--u) * 1.5);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    font-family: inherit;
    font-size: 0.95rem;
    color: var(--tinta);
    background: var(--superficie);
}
input:focus, select:focus, textarea:focus { border-color: var(--petroleo); }
textarea { min-height: 8rem; resize: vertical; line-height: 1.6; }

.mono { font-family: var(--dato); font-size: 0.875rem; }

/* ── Botones ───────────────────────────────────────────────────────────── */
.boton {
    display: inline-block;
    padding: calc(var(--u) * 1.25) calc(var(--u) * 2.5);
    background: var(--petroleo);
    /* En token, no «#fff». Sobre el petróleo del claro el blanco da 7,4:1, y
       sobre el azul digital del oscuro se queda en 3,18: el azul es MUCHO más
       luminoso, así que ahí la tinta tiene que ser oscura. Un color escrito a
       mano dentro del componente es lo que impide tener dos temas. */
    color: var(--boton-tinta);
    border: 1px solid var(--petroleo);
    border-radius: var(--radio);
    font-family: inherit;
    font-size: 0.925rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
}
.boton:hover { background: var(--petroleo-hover); border-color: var(--petroleo-hover); }

.boton.segundo {
    background: var(--superficie);
    color: var(--tinta);
    border-color: var(--borde);
}
.boton.segundo:hover { background: var(--papel); }

.boton.discreto {
    background: none;
    border-color: transparent;
    color: var(--tinta-suave);
    padding-left: 0;
    padding-right: 0;
    text-decoration: underline;
}

/* ── Avisos ────────────────────────────────────────────────────────────
   Un error dice qué pasó y qué hacer. No pide perdón y no es vago. */
.aviso {
    padding: calc(var(--u) * 1.75) calc(var(--u) * 2.5);
    border-radius: var(--radio);
    border-left: var(--rail) solid;
    margin-bottom: calc(var(--u) * 3);
    font-size: 0.925rem;
}
/* El color del texto va en un token y no escrito aquí. Estaba fijo —#6f3f06
   sobre el tinte claro— y en oscuro daba 1,71:1: texto marrón sobre fondo
   marrón, ilegible. Un color escrito a mano dentro de un componente es
   exactamente lo que impide tener dos temas. */
.aviso.mal   { background: var(--ambar-luz);    border-color: var(--ambar);    color: var(--aviso-mal-texto); }
.aviso.bien  { background: var(--petroleo-luz); border-color: var(--petroleo); color: var(--aviso-bien-texto); }
.aviso.dato  { background: var(--papel);        border-color: var(--borde);    color: var(--tinta-suave); }

/*
 * Un enlace dentro de un aviso lleva la tinta del aviso, no la azul de los
 * enlaces. El azul sobre el ámbar del aviso se quedaba en 4,47:1 en oscuro:
 * por debajo del mínimo, pero por tan poco que a ojo no se ve — que es la peor
 * forma de fallar. Heredando la tinta el contraste es el del propio aviso, que
 * ya está medido, y el subrayado sigue diciendo que es un enlace.
 */
.aviso a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* ── Cuando no hay nada ────────────────────────────────────────────────
   Una pantalla vacía es una invitación a hacer algo, no un hueco. */
.vacio {
    padding: calc(var(--u) * 6) calc(var(--u) * 3);
    text-align: center;
    color: var(--apagado);
}
.vacio p { margin: 0 0 calc(var(--u) * 2); }

/* ── Barra de suplantación ─────────────────────────────────────────────
   Cuando el administrador está dentro de la cuenta de un cliente, tiene que
   saberlo en todo momento: es una cuenta ajena con los datos de un negocio
   real dentro. */
.suplantando {
    background: var(--ambar);
    color: #fff;
    padding: calc(var(--u)) calc(var(--u) * 4);
    font-size: 0.875rem;
    display: flex;
    justify-content: space-between;
    gap: var(--u);
    flex-wrap: wrap;
}
.suplantando a { color: #fff; font-weight: 600; }

/* ============================ Entrada ==================================== */

.entrada {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: calc(var(--u) * 3);
}
.entrada-caja {
    width: 100%;
    max-width: 23rem;
    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio-l);
    box-shadow: var(--lamina);
    padding: calc(var(--u) * 5);
}
.entrada-caja h1 {
    margin: 0 0 calc(var(--u) * 0.5);
    font-size: 1.5rem;
    letter-spacing: -0.025em;
}
.entrada-caja h1 span { color: var(--petroleo); }
.entrada-caja .explica { margin-bottom: calc(var(--u) * 4); }
.entrada-caja .boton { width: 100%; }
.entrada-legal {
    margin-top: calc(var(--u) * 3);
    font-size: 0.8rem;
    color: var(--apagado);
    text-align: center;
}

/* ============================ Adaptable ================================== */

@media (max-width: 860px) {
    .armazon { grid-template-columns: 1fr; }

    /* En móvil la navegación baja a una barra fija: quien mira esto entre
       cliente y cliente lo hace con el teléfono en una mano. */
    .nav {
        position: fixed;
        bottom: 0;
        top: auto;
        left: 0;
        right: 0;
        height: auto;
        flex-direction: row;
        align-items: center;
        padding: 0;
        border-right: 0;
        border-top: 1px solid var(--borde);
        z-index: 10;
    }
    /* `a.marca` y no `.marca` a secas: la regla base `.nav a` tiene más
       especificidad (clase + elemento) que una clase suelta, así que un
       `.marca { display: none }` aquí no llegaría a aplicarse nunca. Es el
       fallo clásico de CSS que se cancela a sí mismo. */
    a.marca, .nav-pie { display: none; }

    /* Con cinco o seis secciones no caben en 390px sin romper las palabras,
       así que la barra se desliza en horizontal en vez de apretarlas. */
    .nav ul {
        display: flex;
        width: 100%;
        overflow-x: auto;
        scrollbar-width: none;
    }
    .nav ul::-webkit-scrollbar { display: none; }
    .nav li { flex: 1 0 auto; }
    .nav a {
        text-align: center;
        padding: calc(var(--u) * 1.5) calc(var(--u) * 1.75);
        font-size: 0.78rem;
        white-space: nowrap;
        border-left: 0;
        border-top: var(--rail) solid transparent;
    }
    .nav a[aria-current="page"] {
        border-left: 0;
        border-top-color: var(--petroleo);
    }

    .principal { padding-bottom: 4.5rem; }
    .encabezado { padding: calc(var(--u) * 2.5) calc(var(--u) * 2.5) calc(var(--u) * 2); }
    .cuerpo { padding: calc(var(--u) * 2.5); }
    .hilo { grid-template-columns: minmax(0, 1fr); }
    .hilo .cuando { grid-row: 1; justify-self: start; }

    /* En el móvil la bandeja no se parte en dos: no cabe. Se apila, y si hay
       una conversación abierta se esconde la lista — quien ha entrado a un
       hilo quiere ver el hilo, no la lista otra vez debajo. El :has() es
       progresivo: donde no exista se ven las dos apiladas, que también vale. */
    .bandeja { grid-template-columns: minmax(0, 1fr); }
    .lista-hilos { position: static; max-height: 60vh; }
    .bandeja:has(.hilo-abierto) .lista-hilos { display: none; }

    .hilo-abierto { min-height: auto; }
    .burbujas { max-height: 60vh; padding: calc(var(--u) * 2); }
    .burbuja { max-width: 88%; }
    .hilo-cabecera { padding: calc(var(--u) * 2); }
    .volver-lista { display: inline; }
    .responder { padding: calc(var(--u) * 2); }
    .responder form { grid-template-columns: minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* Impresión: para la hoja de citas del día pegada en el mostrador. */
@media print {
    .nav, .suplantando, .boton { display: none; }
    body { background: #fff; }
    .bloque { border-color: #999; }
}

/*
 * Las horas del cierre sólo cuando se cierran horas.
 *
 * Se hace con CSS y no con JavaScript porque la política de seguridad de
 * contenido es `script-src 'self'` sin 'unsafe-inline': un `onchange=` en el
 * HTML obligaría a abrirla, y no vale la pena abrir la CSP por esconder dos
 * campos.
 *
 * La regla ESCONDE cuando está marcado «días completos», en vez de MOSTRAR
 * cuando está marcado «horas», y es a propósito. Si un navegador no entiende
 * :has(), descarta la regla entera y los campos se quedan visibles —molesto,
 * pero usable. Al revés se quedarían escondidos para siempre y el cierre por
 * horas sería imposible de rellenar. Cuando una regla se puede caer, que se
 * caiga hacia el lado que no rompe nada.
 */
.casillas:has(#tipo_dia:checked) + .fila-campos.solo-horas {
    display: none;
}

/*
 * La barra de guardar, pegada abajo.
 *
 * El formulario de personalización mide casi 3.000 píxeles —instrucciones,
 * tono, servicios, horario, cierres, datos del negocio— y el botón estaba
 * sólo al final. Quien escribía en el primer campo no tenía a la vista
 * ninguna forma de guardar, y lo lógico es pensar que no se guarda.
 *
 * `position: sticky` y no un script: la CSP es `script-src 'self'`, y un
 * botón de guardar que dependa de que cargue un JavaScript es un botón que
 * algún día no está. Así funciona aunque falle todo lo demás.
 *
 * Los márgenes negativos son para que la barra llegue de borde a borde: va
 * dentro de un contenedor con padding, y a media anchura parecería un botón
 * flotando en vez de una barra.
 */
.barra-guardar {
    position: sticky;
    bottom: 0;
    z-index: 5;

    display: flex;
    align-items: center;
    gap: calc(var(--u) * 2);
    flex-wrap: wrap;

    /*
     * Margen arriba Y abajo, el mismo que separa los bloques entre sí.
     *
     * Sin el de abajo la barra quedaba pegada a la tarjeta siguiente — dos
     * rectángulos blancos con una raya en medio, que se lee como si el botón
     * perteneciera al bloque de abajo en vez de cerrar el de arriba.
     */
    margin: calc(var(--u) * 3) 0;
    padding: calc(var(--u) * 2) calc(var(--u) * 3);

    background: var(--superficie);
    border: 1px solid var(--borde);
    border-radius: var(--radio);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, .08);
}

.barra-guardar span {
    font-size: 0.85rem;
    color: var(--tenue);
}

/* En móvil la frase sobra: el botón solo ya ocupa la barra. */
@media (max-width: 40rem) {
    .barra-guardar span { display: none; }
    .barra-guardar .boton { width: 100%; }
}

/* ───────────────────────── Pestañas de secciones ─────────────────────────
   Sólo las usa /personalizacion.php, que tenía siete bloques seguidos: lo que
   más se toca —horario y quién atiende— quedaba a dos pantallas por debajo de
   lo que se configura una vez y no se vuelve a mirar.

   Van con `:target` y sin JavaScript, igual que la ficha de cita de citas.php.
   Cada pestaña tiene URL propia, el botón de atrás funciona, y sin scripts la
   página sigue siendo utilizable: se ven todas las secciones seguidas, que es
   exactamente como estaba antes.

   Las reglas son explícitas por sección y no genéricas. Se podría hacer más
   corto, pero CSS no tiene bucles y lo que quedaría sería más listo que claro.
   Son siete y no cambian a menudo. */

.pestanas {
    display: flex;
    flex-wrap: wrap;
    gap: calc(var(--u) * 0.5);
    margin-bottom: calc(var(--u) * 3);
    border-bottom: 1px solid var(--borde);
}

.pestanas a {
    /* 44px de alto mínimo: es un objetivo táctil, no sólo un enlace. */
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 calc(var(--u) * 2);
    color: var(--tinta-suave);
    text-decoration: none;
    font-size: 0.925rem;
    white-space: nowrap;
    border-bottom: var(--rail) solid transparent;
    /* El desplazamiento del rail no debe mover el texto. */
    margin-bottom: -1px;
}

.pestanas a:hover { color: var(--tinta); background: var(--papel); }

/* El activo: mismo lenguaje que el menú lateral, con el rail abajo en vez de
   al lado. Y en negrita además de en color, porque el color solo no lo ve
   quien no distingue ese tono. */
/* ── Qué se ve ──
   Por defecto sólo la primera. Cuando hay una apuntada por la URL, sólo ésa. */
/* Al saltar a una pestaña, el navegador pega el panel al borde de arriba y la
   propia barra de pestañas se sale de la pantalla: para cambiar de sección
   había que subir a buscarla. Con este margen de desplazamiento, el salto deja
   sitio para la barra. */
.secciones .panel { scroll-margin-top: 5rem; }

.secciones .panel { display: none; }
.secciones .panel:target { display: block; }
.secciones:not(:has(.panel:target)) #habla { display: block; }

/* El activo de la pestaña, sección por sección. */
.pestanas a[data-pestana="habla"]      { border-bottom-color: var(--petroleo); color: var(--tinta); font-weight: 600; }
body:has(.panel:target) .pestanas a[data-pestana="habla"] { border-bottom-color: transparent; color: var(--tinta-suave); font-weight: 400; }
body:has(#habla:target)     .pestanas a[data-pestana="habla"],
body:has(#servicios:target) .pestanas a[data-pestana="servicios"],
body:has(#horario:target)   .pestanas a[data-pestana="horario"],
body:has(#faq:target)       .pestanas a[data-pestana="faq"],
body:has(#equipo:target)    .pestanas a[data-pestana="equipo"],
body:has(#probar:target)    .pestanas a[data-pestana="probar"],
body:has(#sector:target)    .pestanas a[data-pestana="sector"] {
    color: var(--tinta);
    font-weight: 600;
    border-bottom-color: var(--petroleo);
}

/* ── La barra de guardar ──
   Está dentro del formulario y guarda sus cuatro secciones. En las tres que
   no son del formulario no pinta nada: un botón «Guardar» junto a algo que no
   guarda es una promesa falsa. */
body:has(#equipo:target) .barra-guardar,
body:has(#probar:target) .barra-guardar,
body:has(#sector:target) .barra-guardar { display: none; }

/* ── Con un error, todo a la vista ──
   Si el rechazo viene de un campo que está en otra pestaña, esconderlo obliga
   a buscarlo una por una. Se abren todas y el aviso de arriba vuelve a tener
   sentido. */
.secciones.con-error .panel { display: block; }

/* Sin :has() —navegadores viejos— se ven todas las secciones seguidas, que es
   como estaba esta página antes de las pestañas. Se pierde la comodidad, no
   el acceso. */
@supports not selector(:has(*)) {
    .secciones .panel { display: block; }
    .pestanas { display: none; }
}

/* ─────────────────── El horario en una pantalla estrecha ───────────────────
   Medido a 375px antes de tocar nada: el envoltorio daba 285px, la tabla se
   comprimía a 364 y cada campo de hora quedaba en 32px — «09:00» no cabía y
   salía recortado. La tabla podía desplazarse de lado, pero rellenar cuatro
   horas por día en siete días arrastrando en horizontal no lo hace nadie.

   Así que en móvil deja de ser tabla y pasa a ser una tarjeta por día. No hace
   falta marcado nuevo: cada campo YA tenía su etiqueta —«Lunes abre»— escondida
   para lectores de pantalla, y aquí sólo se dejan ver. El trabajo de
   accesibilidad que ya estaba hecho es lo que permite esta vista.

   Se cambia la presentación, no la semántica: para un lector de pantalla la
   tabla sigue siendo una tabla en cualquier anchura. */
@media (max-width: 40rem) {
    .tabla-horario,
    .tabla-horario tbody,
    .tabla-horario tr,
    .tabla-horario td { display: block; width: auto; }

    /* La cabecera sobra: cada campo lleva ya su propia etiqueta. */
    .tabla-horario thead { display: none; }

    .tabla-horario tr {
        border: 1px solid var(--borde);
        border-radius: var(--radio);
        margin-bottom: calc(var(--u) * 2);
        padding: calc(var(--u) * 1.5);
    }

    /* El día, de título de la tarjeta. */
    .tabla-horario tbody th {
        display: block;
        border-bottom: 1px solid var(--filete);
        padding: 0 0 var(--u);
        margin-bottom: var(--u);
    }

    .tabla-horario td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--u);
        border-bottom: 0;
        padding: calc(var(--u) * 0.5) 0;
    }

    /* La etiqueta que estaba escondida para lectores de pantalla, ahora a la
       vista: es lo que dice cuál de las cuatro horas es cada campo. */
    .tabla-horario td .oculto-visual {
        position: static;
        width: auto; height: auto;
        margin: 0;
        clip: auto;
        overflow: visible;
        font-size: 0.875rem;
        color: var(--tinta-suave);
    }

    /* Ancho de sobra para «09:00», y alto de dedo. */
    .tabla-horario td input {
        width: 6rem;
        min-height: 44px;
        text-align: center;
    }

    /* Ya no hay nada que desplazar de lado. */
    .tabla-horario { min-width: 0; }
}

/* ════════════════════ Cristal templado ══════════════════════════════════
   El tratamiento elegido. La idea es dar sensación de material SIN poner
   nada translúcido detrás de un texto: aquí se leen horas y nombres muchas
   veces al día, y un fondo que cambia cambia el contraste con él.

   Sólo dos gestos, y los dos donde no estorban. */

/* 1. Un lavado de color muy tenue en el fondo de la página. Va detrás de
      todo y no toca ninguna superficie de lectura: las tarjetas siguen
      siendo sólidas. `fixed` para que no se desplace con el scroll, que es
      lo que lo delata como truco. */
body {
    background-image:
        radial-gradient(72rem 44rem at 10% -10%, var(--lavado-1), transparent 66%),
        radial-gradient(58rem 40rem at 100% 2%, var(--lavado-2), transparent 68%);
    background-attachment: fixed;
    background-repeat: no-repeat;
}

/* 1 bis. El lavado en diagonal DENTRO de la lámina.
      El del fondo de la página apenas se ve, porque las tarjetas tapan casi
      todo el suelo. Puesto también dentro de cada tarjeta, la superficie deja
      de ser un blanco plano y coge el aire de un vidrio con luz de lado: un
      soplo de petróleo por arriba a la izquierda y uno de ámbar por abajo a la
      derecha. Muy flojo a propósito — debajo hay texto, y esto es lo único del
      tratamiento que queda debajo de una letra. Medido con bin/contraste.mjs. */
.bloque {
    background-image:
        linear-gradient(135deg, var(--lamina-1) 0%, transparent 44%),
        linear-gradient(315deg, var(--lamina-2) 0%, transparent 38%);
}

/* 2. La barra de guardar, esmerilada. Es lo ÚNICO que flota de verdad por
      encima del contenido —es sticky— así que es el único sitio donde el
      desenfoque describe algo real: hay cosas debajo. */
.barra-guardar {
    background: var(--cristal);
    border-radius: var(--radio-l) var(--radio-l) 0 0;
    backdrop-filter: blur(14px) saturate(1.25);
    -webkit-backdrop-filter: blur(14px) saturate(1.25);
    border-top: 1px solid var(--cristal-borde);
}

/* Sin backdrop-filter, la barra se vuelve sólida en vez de translúcida. Una
   barra medio transparente sin desenfoque deja leer el texto de debajo a
   través, que es peor que no tener efecto. */
@supports not (backdrop-filter: blur(1px)) {
    .barra-guardar { background: var(--superficie); }
}

/* El botón del tema, en el pie del menú. Sin icono a propósito: dice en qué
   estado está, que es lo que no se puede deducir de una luna. */
.cambia-tema { font-variant-numeric: tabular-nums; }

/* ── Lo que el modo oscuro necesita además de tokens ──
   Las sombras claras no se ven sobre navy y las imágenes deslumbran. */
[data-tema="oscuro"] .maqueta,
[data-tema="oscuro"] .bloque {
    box-shadow: 0 1px 2px rgba(0, 0, 0, .4);
}
[data-tema="oscuro"] img { filter: brightness(.92); }
