/* =====================================================================
   Forja · Tema «familia QBK»
   public/css/tema-forja.css  ·  2026-10-22

   Solo los VALORES de Forja para las variables --fq-* (la brasa naranja
   sobre azul noche) y sus dos familias de letra. Todo lo que usa estas
   variables vive en familia-qbk.css, que es idéntico al de BRÚJULA y no se
   edita aquí; por eso en esta tarea no hay reglas de componentes, solo
   variables, letras y la base. Las secciones propias de Forja (fondo
   «Ciudad de noche», vidrio, impresión…) se agregan debajo, una por tarea.

   Cómo se elige el modo (igual que el resto de Forja, ver el <head> del layout):
     - Oscuro es el modo por defecto            → :root
     - Claro explícito (forja_theme = light)    → :root[data-theme="light"]
     - Claro por preferencia del sistema, si la persona no eligió oscuro
                                                → @media (prefers-color-scheme: light)
                                                  :root:not([data-theme="dark"])
   El script del <head> pone data-theme="light" o "dark" en <html> según
   localStorage `forja_theme`; sin elección guardada manda el sistema.

   Contraste (WCAG AA manda sobre la tabla de la spec):
     - --fq-acento es el color de la marca: adornos, bordes, iconos, cifras
       grandes (>= 3:1 sobre el fondo).
     - --fq-acento-texto es el acento para TEXTO y para FONDO DE BOTÓN con
       texto (>= 4,5:1 sobre el fondo y con --fq-sobre-acento encima).
       En oscuro coincide con el acento (#F2A050 llega a 8,8:1). En claro
       el acento de la tabla (#C2541C) solo llega a 4,2:1 sobre #F4F5F8,
       así que el texto usa el mismo naranja oscurecido (#A94511, 4,8:1
       incluso bajo la mancha más pesada de la aurora).
   La aurora (--fq-a1/a2/a3) también cuenta: el texto y --fq-acento-texto se
   miden contra el fondo mezclado con cada mancha a su alfa completo.
   tests/Feature/DisenoTemaTest.php vigila estas cuentas y que los valores
   coincidan con la spec.
   ===================================================================== */

/* ============================== Variables ============================== */

/* ---------------------------- OSCURO (defecto) ---------------------------- */
:root {
    /* Letras (heredadas por el claro: solo se declaran aquí) */
    --fq-titulo: 'Bricolage Grotesque', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --fq-texto: 'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;

    --fq-fondo: #0D1322;
    --fq-tinta: #EEF0F4;
    --fq-suave: rgba(238,240,244,.62);
    --fq-acento: #F2A050;
    --fq-acento2: #E46A2E;
    --fq-acento-texto: #F2A050;
    --fq-sobre-acento: #1A0E05;
    --fq-brasa: linear-gradient(135deg, #E46A2E, #F2A050, #FFD49A);

    --fq-vidrio: rgba(255,255,255,.045);
    --fq-vidrio-solido: #181E2C;       /* vidrio sobre el fondo, ya mezclado: respaldo sin backdrop-filter */
    --fq-borde: rgba(242,160,80,.18);
    --fq-brillo: rgba(255,255,255,.09);
    --fq-linea: rgba(242,160,80,.11);
    --fq-foco: rgba(242,160,80,.15);   /* luz que sigue al cursor dentro del vidrio */
    --fq-lado: rgba(8,13,26,.55);      /* barra lateral de vidrio */

    /* Aurora: brasa, azul y brasa clara */
    --fq-a1: rgba(228,106,46,.28);
    --fq-a2: rgba(60,84,150,.40);
    --fq-a3: rgba(242,160,80,.13);
}

/* ------------------------------ CLARO (elegido) ------------------------------ */
:root[data-theme="light"] {
    --fq-fondo: #F4F5F8;
    --fq-tinta: #0D1322;
    --fq-suave: rgba(13,19,34,.62);
    --fq-acento: #C2541C;
    --fq-acento2: #E07A34;
    --fq-acento-texto: #A94511;
    --fq-sobre-acento: #FFF6EE;
    --fq-brasa: linear-gradient(135deg, #C2541C, #E07A34, #F0A866);

    --fq-vidrio: rgba(255,255,255,.72);
    --fq-vidrio-solido: #FBFCFD;
    --fq-borde: rgba(13,19,34,.09);
    --fq-brillo: rgba(255,255,255,.95);
    --fq-linea: rgba(13,19,34,.08);
    --fq-foco: rgba(224,122,52,.14);
    --fq-lado: rgba(255,255,255,.55);

    --fq-a1: rgba(240,168,102,.20);
    --fq-a2: rgba(190,205,245,.26);
    --fq-a3: rgba(255,214,170,.28);
}

/* --------------- CLARO (por preferencia del sistema, sin elección) --------------- */
/* Mismos valores que el bloque de arriba; el navegador no permite compartirlos. */
@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) {
        --fq-fondo: #F4F5F8;
        --fq-tinta: #0D1322;
        --fq-suave: rgba(13,19,34,.62);
        --fq-acento: #C2541C;
        --fq-acento2: #E07A34;
        --fq-acento-texto: #A94511;
        --fq-sobre-acento: #FFF6EE;
        --fq-brasa: linear-gradient(135deg, #C2541C, #E07A34, #F0A866);

        --fq-vidrio: rgba(255,255,255,.72);
        --fq-vidrio-solido: #FBFCFD;
        --fq-borde: rgba(13,19,34,.09);
        --fq-brillo: rgba(255,255,255,.95);
        --fq-linea: rgba(13,19,34,.08);
        --fq-foco: rgba(224,122,52,.14);
        --fq-lado: rgba(255,255,255,.55);

        --fq-a1: rgba(240,168,102,.20);
        --fq-a2: rgba(190,205,245,.26);
        --fq-a3: rgba(255,214,170,.28);
    }
}

/* ================================ Base ================================ */
/* Las letras de la v3 (forja.css) salen de --font-title y --font-body: se
   apuntan a las de la familia y todo lo que ya las usa cambia sin tocarlo. */
:root {
    --font-title: var(--fq-titulo);
    --font-body: var(--fq-texto);
}
/* Títulos: la v3 los deja en 600 y forja.css los define en --font-title; todos
   pasan a Bricolage Grotesque 700, igual que h1-h3. Son títulos o nombres
   (columna, tarea, fase, lote, producto, cifra de carga, nombre en tabla/mensajes),
   ninguno es texto corrido. Se repite .tbl .nm y .mg .nm porque forja.css les da
   peso con más especificidad que .nm solo. */
h1, h2, h3,
.col-t, .tr-t, .phase-h b, .lotc b, .prod, .load-i b, .nm,
.tbl .nm, .mg .nm {
    font-weight: 700;
}

/* =====================================================================
   Fondo ciudad  ·  «Ciudad de noche» (capa fija, partials/fondo-ciudad.blade.php)

   Fondo 3 de la maqueta fondos.html: un halo, las calles de un plano y luces
   que las recorren despacio. Detrás de toda la app, en oscuro y en claro.

   - Colores: solo variables del tema que ya cambian con el modo. Las calles son
     --fq-linea (brasa tenue en oscuro, tinta tenue en claro), las luces son
     --fq-acento y --fq-acento2 (la brasa; en claro quedan más oscuras y se
     leen sobre el papel) y el halo reutiliza --fq-a2 y --fq-a1 (la aurora),
     cuyo contraste con el texto ya vigila DisenoTemaTest. Nada de colores fijos.
   - Movimiento: solo CSS y solo stroke-dashoffset (el rayo de luz es un trazo
     discontinuo que se desplaza). Nada de JS, de desenfoque ni de filter: el
     resplandor de la maqueta (drop-shadow) se hace con un segundo trazo ancho y
     muy tenue debajo del núcleo, que no obliga a repintar cada cuadro. Son 8
     luces; solo se anima el <g> de cada una y sus dos trazos lo heredan.
   - Las duraciones son el doble de largas que las de la maqueta (14/18/22 s en
     vez de 7/9/11 s): allá la capa medía 300 px, acá ocupa toda la pantalla y la
     misma duración se vería a toda prisa.
   - .fq-fondo vive aquí y no en familia-qbk.css (que es idéntico al de BRÚJULA);
     la pausa con la pestaña oculta ya la hace familia-qbk.css con todo, y aquí
     se repite para dejar escrito el contrato del fondo.
   - z-index: -1 y pointer-events: none: queda debajo del contenido, de los
     modales y del Copilot y no atrapa clics. Tiene su propio color de base
     (--fq-fondo) porque el fondo del <body> de la v3 todavía es el gris viejo.
   ===================================================================== */
.fq-fondo {
    position: fixed;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
    background: var(--fq-fondo);
}
.fq-fondo .fq-halo {
    position: absolute;
    inset: -30%;
    background:
        radial-gradient(40% 35% at 70% 10%, var(--fq-a2), transparent 70%),
        radial-gradient(38% 34% at 15% 95%, var(--fq-a1), transparent 70%);
}
.fq-fondo .fq-calles {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

/* Anchos en unidades del dibujo (viewBox 400 x 260, escala pareja): ~1 px la calle, ~2 px el núcleo. */
.fq-fondo .fq-calle {
    fill: none;
    stroke: var(--fq-linea);
    stroke-width: .25;
}
.fq-fondo .fq-luz-brillo,
.fq-fondo .fq-luz-nucleo {
    fill: none;
    stroke: var(--fq-acento);
    stroke-linecap: round;
    /* pathLength="1": el trazo mide 1; la luz es un tramo corto y el resto es hueco. */
    stroke-dasharray: .06 1.3;
}
.fq-fondo .fq-luz-brillo {
    stroke-width: 1.6;
    stroke-opacity: .16;
}
.fq-fondo .fq-luz-nucleo {
    stroke-width: .5;
    stroke-opacity: .9;
}
.fq-fondo .fq-luz {
    /* Antes de moverse (y sin animación) el tramo queda fuera del trazo: no se ve ninguna luz suelta. */
    stroke-dashoffset: .06;
}
.fq-fondo .fq-luz--b .fq-luz-brillo,
.fq-fondo .fq-luz--b .fq-luz-nucleo {
    stroke: var(--fq-acento2);
}
.fq-fondo .fq-luz--a { animation: fq-ciudad-viaja 14s linear infinite; }
.fq-fondo .fq-luz--b { animation: fq-ciudad-viaja 18s linear infinite; }
.fq-fondo .fq-luz--c { animation: fq-ciudad-viaja 22s linear infinite; }
/* Desfases negativos: las luces ya van a medio camino al abrir la página y no salen todas juntas. */
.fq-fondo .fq-luces > :nth-child(1) { animation-delay: -3s; }
.fq-fondo .fq-luces > :nth-child(2) { animation-delay: -6s; }
.fq-fondo .fq-luces > :nth-child(3) { animation-delay: -12s; }
.fq-fondo .fq-luces > :nth-child(4) { animation-delay: -4s; }
.fq-fondo .fq-luces > :nth-child(5) { animation-delay: -10s; }
.fq-fondo .fq-luces > :nth-child(6) { animation-delay: -16s; }
.fq-fondo .fq-luces > :nth-child(7) { animation-delay: -9s; }
.fq-fondo .fq-luces > :nth-child(8) { animation-delay: -14s; }

@keyframes fq-ciudad-viaja {
    from { stroke-dashoffset: .06; }
    to   { stroke-dashoffset: -1; }
}

/* Pestaña oculta: las luces se quedan quietas (FamiliaQbk.pausarFondo pone .fq-pausa en <html>). */
html.fq-pausa .fq-fondo * {
    animation-play-state: paused;
}

/* «Reducir movimiento»: el plano queda quieto y sin luces. */
@media (prefers-reduced-motion: reduce) {
    .fq-fondo .fq-luz {
        animation: none;
        display: none;
    }
}

/* En papel no va fondo: gasta tinta y ensucia el texto. */
@media print {
    .fq-fondo {
        display: none;
    }
}

/* =====================================================================
   Barra lateral  ·  vidrio con indicador (partials/menu.blade.php)

   La barra es una superficie única, así que es la única que lleva
   desenfoque (backdrop-filter). Deja ver el fondo «Ciudad de noche» en
   oscuro y en claro. Las tarjetas repetidas del resto de la app no.

   - El vidrio va en un PSEUDOELEMENTO (.side::before), no en .side. Un
     backdrop-filter (igual que filter o transform) convierte al elemento
     en el bloque contenedor de sus descendientes con position: fixed, y la
     lista de la campanita (.side .camp-panel, forja-app.css) es fixed: con
     el desenfoque en .side quedaría recortada dentro de la barra
     (overflow: hidden) en vez de salir a la derecha de ella.
   - Especificidad: forja.css (la v3) pone fondo con !important en .side y
     colores con (0,2,0) en las opciones; aquí llevan `.shell` o `.side`
     delante en vez de repetir !important, salvo donde la v3 ya lo usa.
   - Contraste AA: el texto del menú es --fq-tinta / --fq-suave sobre el
     vidrio (--fq-lado, translúcido) y sobre el fondo y las manchas del
     halo que haya detrás. BarraLateralTest vigila las cuentas, peor caso
     incluido (las dos manchas juntas). El cajón del celular es sólido.
   - El indicador .fq-ind (familia-qbk.css) lo coloca forja-familia.js con
     FamiliaQbk.indicador(): mide con offsetTop contra el nav (position:
     relative) y se desliza con el resorte de la familia. Las opciones van
     encima (position: relative; z-index: 1) y la activa queda sin fondo
     propio para que se vea el indicador.
   ===================================================================== */
.shell .side {
    background: transparent !important;
    border-right: 1px solid var(--fq-linea);
    color: var(--fq-tinta);
}
.shell .side::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;                  /* detrás del contenido de la barra, dentro de su propio contexto (z-index: 40) */
    pointer-events: none;
    background: var(--fq-lado);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
}
/* Sin backdrop-filter el vidrio no se vería: se usa su color sólido equivalente. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .shell .side::before {
        background: var(--fq-vidrio-solido);
    }
}

/* ------------------------------ Cabecera y pie ------------------------------ */
.side .prod {
    color: var(--fq-tinta);
}
.side .prod span {
    color: var(--fq-suave);
}
.side .st-row .ib {
    background: var(--fq-vidrio);
    border-color: var(--fq-borde);
    border-radius: 11px;
    color: var(--fq-tinta);
    transition: border-color .25s, background .25s;
}
.side .st-row .ib:hover {
    border-color: var(--fq-acento);
}

/* Cabecera en dos filas (ruling P6). Fila 1: el logo solo (150 px). Fila 2: Buscar (ocupa lo que sobre), modo y
   campanita. En una sola fila no cabían: en los 226 px útiles de la barra (262 - 2 × 18) el logo, el botón con su
   «Ctrl K» y dos botones de 36 px suman ~370 px, y .side recorta lo que se pasa. La fila 2 mide ~218 px, así que
   queda con holgura. La lista de la campanita es position: fixed (forja-app.css), no depende de la fila. */
.side .st-logo {
    margin: 0 0 12px;
}
.side .st-row {
    gap: 8px;
}
.side .st-row > span {
    flex: none;                   /* modo y campanita conservan su tamaño */
}
.side .st-row .fq-buscar-btn {
    flex: 1 1 0;
    min-width: 0;                 /* si algún día falta sitio, encoge el botón y no se corta la campanita */
    justify-content: flex-start;
    gap: 6px;
    padding: 0 7px 0 10px;
}
.side .st-row .fq-buscar-txt {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.side .st-row .fq-buscar-kbd {
    margin-left: auto;            /* la combinación de teclas queda pegada al borde derecho del botón */
}
@media (max-height: 760px) {
    .side .st-logo {
        margin-bottom: 8px;
    }
}
.side .side-foot {
    border-top: 1px solid var(--fq-linea) !important;
}
.side .side-foot .who,
.side .side-foot .small {
    color: var(--fq-suave);
}
.side .side-foot .btn-link {
    color: var(--fq-acento-texto);
}
.side :focus-visible {
    outline-color: var(--fq-acento);
}

/* --------------------------------- Menú --------------------------------- */
.shell .snav {
    position: relative;           /* el indicador se mide contra este elemento */
}
.snav .fq-ind {
    left: 10px;                   /* el relleno lateral del nav (forja.css: 6px 10px) */
    right: 10px;
}
.side .sg {
    color: var(--fq-suave);
    opacity: 1;                   /* la v3 la baja a .8 y eso le quita contraste */
}
.side .si {
    position: relative;
    z-index: 1;                   /* por encima del indicador (z-index: 0) */
    border-radius: 11px;          /* como el indicador */
    color: var(--fq-suave);
    transition: color .25s, background .25s;
}
.side .si:hover {
    background: var(--fq-vidrio);
    color: var(--fq-tinta);
}
.side .si.on {
    background: transparent;      /* el fondo de la opción activa es el indicador */
    color: var(--fq-tinta);
}
.side .si.on .ic {
    color: var(--fq-acento-texto);
}
.side .cnt-b,
.side .si.on .cnt-b {
    background: var(--fq-acento-texto);
    color: var(--fq-sobre-acento);
}

/* ---------------------------------------------------------------------
   Celular (<= 899 px, el corte de forja.css): la barra es un cajón que
   entra desde la izquierda. Va con fondo sólido sobre la capa oscura (sin
   desenfoque) y se desplaza por dentro: con el teléfono horizontal el menú
   no cabe y las últimas opciones y «Salir» quedarían cortadas. Ese
   desplazamiento no se pasa a la página de atrás (overscroll-behavior) y la
   altura es la de la pantalla visible (dvh: sin la barra del navegador;
   donde no existe queda el vh de antes). El nav deja de desplazarse solo y
   crece con su contenido, así todo el cajón corre junto. El indicador no
   está: la opción activa lleva su propio fondo.
   --------------------------------------------------------------------- */
@media (max-width: 899px) {
    .shell .side {
        bottom: auto;
        height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
        height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
        overflow-y: auto !important;
        overscroll-behavior: contain;
        background: var(--fq-vidrio-solido) !important;
    }
    .shell .side::before {
        display: none;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
    .shell .snav {
        flex: 1 0 auto !important;
        overflow: visible;
    }
    .snav .fq-ind {
        display: none;
    }
    .side .si.on {
        background: color-mix(in srgb, var(--fq-acento) 14%, transparent);
    }
}

/* En el cajón del celular sobra sitio: el botón conserva la palabra «Buscar» (familia-qbk.css la esconde por debajo de
   640 px y deja solo la lupa); «Ctrl K» sigue oculto, en el teléfono no hay teclado que anunciar. */
@media (max-width: 640px) {
    .side .st-row .fq-buscar-btn {
        padding: 0 12px 0 11px;
    }
    .side .st-row .fq-buscar-btn .fq-buscar-txt {
        display: inline;
    }
}

/* «Reducir movimiento»: el menú y los botones cambian de color sin transición. */
@media (prefers-reduced-motion: reduce) {
    .side .si,
    .side .st-row .ib {
        transition: none;
    }
}

/* En papel no va la barra lateral: el contenido ocupa toda la hoja. */
@media print {
    .shell .side,
    .shell .scrim {
        display: none;
    }
}

/* =====================================================================
   Componentes  ·  tarjetas, botones, etiquetas, campos, ventanas… (tarea 5)

   Las clases de siempre de la v3 (.card, .btn, .tag, .chip, .modal, .toast,
   .cop, .cal-*…) pasan al sistema «familia QBK»: vidrio, bordes y radios de
   la familia, y la brasa (--fq-acento-texto) como color de lo principal. El
   HTML casi no cambia; cambia cómo se ve. forja.css y forja-app.css cargan
   antes que este archivo: aquí se gana por orden de carga y por igual o mayor
   especificidad, nunca con !important.

   - Atajo: las variables de la v3 (--ink, --muted, --line, --surface…) se
     apuntan al tema (--fq-*) en un solo bloque (`:root:root`, igual o mayor
     especificidad que los bloques de modo de la v3). Así todo lo que ya las
     usa —cientos de reglas— cambia con el modo sin tocarlo. Los colores de
     significado (--ok, --warn, --bad, --info y sus --*-soft) se dejan como
     están: son información y la v3 ya los eligió con contraste en los dos modos.
   - Vidrio: backdrop-filter SOLO en superficies únicas (tabla, chat, ventana,
     Copilot, lista de avisos, aviso emergente, barra superior del celular).
     Lo que se repite —tarjetas, lotes, indicadores, tareas, días, etiquetas—
     NO lleva desenfoque (con el fondo animado, cada uno se redibujaría en
     cada cuadro) y usa un fondo translúcido al 82 %: se ve casi igual.
   - Contraste: ComponentesTest vigila los pares (botón sobre acento, etiqueta
     sobre su color, texto suave sobre la tarjeta bajo cada mancha de la
     aurora, campos, aviso, barra superior). El botón de peligro se queda
     ROJO: rojo de significado en texto y borde, sobre su fondo suave.
   ===================================================================== */

/* ------------------------------ Variables ------------------------------ */
:root {
    /* Fondo de las piezas de vidrio únicas: brillo diagonal + vidrio + el fondo del tema al 55 %
       (la base que asegura el contraste del texto aunque pase una mancha de la aurora). */
    /* El reflejo diagonal es el brillo del tema al 55 %: el brillo entero (blanco al 9 % en oscuro) aclara
       la esquina de la tarjeta y el texto suave dejaba de llegar a 4,5:1 bajo las manchas más pesadas. */
    --fq-reflejo: color-mix(in srgb, var(--fq-brillo) 55%, transparent);
    --fq-cristal:
        linear-gradient(160deg, var(--fq-reflejo), transparent 42%),
        linear-gradient(var(--fq-vidrio), var(--fq-vidrio)),
        color-mix(in srgb, var(--fq-fondo) 55%, transparent);
    /* Lo mismo para lo que se repite (sin desenfoque): el fondo del tema al 82 %. */
    --fq-cristal-plano:
        linear-gradient(160deg, var(--fq-reflejo), transparent 42%),
        linear-gradient(var(--fq-vidrio), var(--fq-vidrio)),
        color-mix(in srgb, var(--fq-fondo) 82%, transparent);
    /* Fondo opaco de campos y listas desplegables (un <select> abierto no puede quedar translúcido). */
    --fq-campo: color-mix(in srgb, var(--fq-fondo) 90%, var(--fq-tinta));
    --fq-sombra: 0 10px 34px rgba(0, 0, 0, .16);
    --fq-sombra-chica: 0 6px 20px rgba(0, 0, 0, .12);
    accent-color: var(--fq-acento-texto);   /* casillas, radios y barras nativos */
}

/* Las variables de la v3 salen del tema. `:root:root` (0,2,0) empata con los bloques de modo
   de forja.css (`:root[data-theme="dark"]`, `:root:not([data-theme="light"])`) y gana por ir después. */
:root:root {
    --bg: var(--fq-fondo);
    --surface: color-mix(in srgb, var(--fq-fondo) 82%, transparent);
    --surface-2: color-mix(in srgb, var(--fq-tinta) 6%, transparent);
    --ink: var(--fq-tinta);
    --on-ink: var(--fq-fondo);       /* texto sobre lo que la v3 pinta con --ink (insignias, avisos…) */
    --muted: var(--fq-suave);
    --line: var(--fq-borde);
}

:focus-visible {
    outline: 2px solid var(--fq-acento-texto);
    outline-offset: 2px;
}
input[type=checkbox],
input[type=radio] {
    accent-color: var(--fq-acento-texto);
}

/* ------------------------- Tarjetas y bloques de vidrio ------------------------- */
/* Lo que se repite: sin desenfoque, fondo translúcido al 82 %. Solo fondo, radio y sombra: el borde
   ya sale de --line (= --fq-borde) y lo de cada pieza (ancho, lado de color) lo sigue poniendo la v3. */
.card,
.docs,
.log,
.phase,
.lotc,
.load-i,
.stage,
.tr.cur,
.cop-q,
.cop-otro {
    background: var(--fq-cristal-plano);
    border-radius: var(--fq-radio);
    box-shadow: var(--fq-sombra-chica);
}
/* La v3 pega los indicadores del panel en una sola franja (fondo --line + celdas sin borde). Aquí cada
   uno es su tarjeta; el borde (que la v3 fija con !important) se dibuja como anillo de sombra. */
.load {
    gap: 10px;
    background: none;
    border: 0;
    border-radius: 0;
    overflow: visible;
}
.load-i {
    box-shadow: 0 0 0 1px var(--fq-borde), var(--fq-sombra-chica);
}
.load-i:hover {
    background: var(--fq-cristal-plano);
    box-shadow: 0 0 0 1px var(--fq-acento), var(--fq-sombra-chica);
}
.lotc:hover {
    border-color: var(--fq-acento);
    box-shadow: var(--fq-sombra);
}
.card.empty {
    border-style: dashed;
    box-shadow: none;
}

/* Superficies únicas y grandes: la tabla y el chat sí llevan desenfoque. */
.tbl-w,
.chat-app {
    background: var(--fq-cristal);
    border-radius: var(--fq-radio);
    box-shadow: var(--fq-sombra);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
}
.tbl tbody tr.go:hover {
    background: color-mix(in srgb, var(--fq-acento) 8%, transparent);
}
/* El hueco de la puerta del tablero tapa la línea de puntos: casi opaco para que el texto se lea. */
.gate span {
    background: color-mix(in srgb, var(--fq-fondo) 90%, transparent);
}

/* ----------------------------------- Botones ----------------------------------- */
.btn {
    font-family: var(--fq-texto);
    border-color: color-mix(in srgb, var(--fq-tinta) 24%, transparent);
    border-radius: 12px;
    background: var(--fq-vidrio);
    color: var(--fq-tinta);
    transition: border-color .25s, background-color .25s, box-shadow .25s;
}
.btn:hover {
    border-color: var(--fq-acento);
    background: color-mix(in srgb, var(--fq-acento) 10%, transparent);
}
.btn:focus-visible {
    outline: 2px solid var(--fq-acento-texto);
    outline-offset: 2px;
}
/* Principal: la brasa en su versión para texto (AA) con el texto «sobre acento». */
.btn-primary {
    background: var(--fq-acento-texto);
    border-color: var(--fq-acento-texto);
    color: var(--fq-sobre-acento);
}
.btn-primary:hover {
    background: var(--fq-acento-texto);
    border-color: var(--fq-acento-texto);
    box-shadow: 0 8px 24px color-mix(in srgb, var(--fq-acento) 38%, transparent);
    opacity: 1;
}
/* Peligro: SIGUE ROJO. Va después de .btn (si no, el borde de .btn le ganaba y perdía el rojo):
   texto y borde del rojo de significado sobre su fondo suave; al acercarse, un poco más de rojo. */
.btn-danger {
    color: var(--bad);
    border-color: var(--bad);
    background: var(--bad-soft);
}
.btn-danger:hover {
    border-color: var(--bad);
    background: color-mix(in srgb, var(--bad) 8%, var(--bad-soft));
}
.btn-link {
    color: var(--fq-acento-texto);
}
.thm:hover,
.ib:hover,
.ib-s:hover,
.cop-chip:hover,
.th.add:hover,
.mvb:not(:disabled):hover {
    border-color: var(--fq-acento);
}

/* Filtros, segmentos y pestañas: lo elegido va en brasa sólida (AA con el texto «sobre acento»). */
.chip {
    font-family: var(--fq-texto);
    background: var(--fq-vidrio);
    border-color: var(--fq-borde);
    color: var(--fq-suave);
    transition: border-color .25s, color .25s, background-color .25s;
}
.chip:hover {
    border-color: var(--fq-acento);
    background: color-mix(in srgb, var(--fq-acento) 8%, transparent);
    color: var(--fq-tinta);
}
.chip.on {
    background: var(--fq-acento-texto);
    border-color: var(--fq-acento-texto);
    color: var(--fq-sobre-acento);
}
.seg,
.mini {
    background: var(--fq-vidrio);
    border-color: var(--fq-borde);
}
.seg button.on,
.mini button.on,
.seg-o.on {
    background: var(--fq-acento-texto);
    color: var(--fq-sobre-acento);
}
.seg-o:focus-within {
    outline-color: var(--fq-tinta);   /* la opción elegida ya es del color del acento: el aro va en tinta */
}
.tabs button.on {
    color: var(--fq-tinta);
    border-bottom-color: var(--fq-acento);
}
.fo.on {
    border-color: var(--fq-acento);
}
.ib-s.on {
    background: var(--fq-acento-texto);
    border-color: var(--fq-acento-texto);
    color: var(--fq-sobre-acento);
}

/* ---------------------------- Etiquetas e insignias ---------------------------- */
.badge,
.tag,
.code {
    font-family: var(--fq-texto);
}
.b-acc::before,
.dia,
.task.gate-row .gm {
    background: var(--fq-acento);
}
.unb,
.tr-now {
    background: var(--fq-acento-texto);
    color: var(--fq-sobre-acento);
}
/* Contadores rojos: el blanco fijo no pasaba AA sobre el rojo claro del modo oscuro. */
.camp .cnt-dot,
.tr.cur.off .tr-now {
    color: var(--on-ink);
}
.av {
    background: var(--fq-acento-texto);
    color: var(--fq-sobre-acento);
}
/* El fondo es el color del área (en línea, background-color). Blanco solo no llega a 4,5:1 sobre los colores claros
   (turquesa, verde, ámbar…): una capa de negro al 30 % los oscurece SOLO en el avatar y el blanco pasa en todas. */
.av.av-area {
    background-image: linear-gradient(rgba(0, 0, 0, .3), rgba(0, 0, 0, .3));
    color: #fff;
}
.bar {
    background: color-mix(in srgb, var(--fq-tinta) 11%, transparent);
}
.bar > i,
.tr.cur .bar > i {
    background: var(--fq-acento);
}
.th.on {
    border-color: var(--fq-acento);
    box-shadow: 0 0 0 1px var(--fq-acento);
}

/* ---------------------------------- Avisos ---------------------------------- */
.note {
    background: color-mix(in srgb, var(--fq-acento) 10%, var(--fq-vidrio-solido));
    border: 1px solid color-mix(in srgb, var(--fq-acento) 38%, transparent);
    color: var(--fq-tinta);
}
.note.note-bad {
    background: var(--bad-soft);
    border-color: color-mix(in srgb, var(--bad) 40%, transparent);
}
.stage.acc {
    border-left-color: var(--fq-acento);
}
.hv-est li.ult,
.msg.new,
.tr.cur {
    border-color: var(--fq-acento);
}
.hv-est li.ult {
    border-left-color: var(--fq-acento);
}
.tr.cur.off {
    border-color: var(--bad);
}

/* ------------------------------- Campos y formularios ------------------------------- */
/* Fondo apenas distinto del vidrio y borde con 3:1 de contraste (WCAG 1.4.11): en claro el borde del
   vidrio es casi invisible. `.t-ctl` (forja.css) deja sus controles transparentes hasta que se usan. */
input,
select,
textarea {
    background: var(--fq-campo);
    border-color: color-mix(in srgb, var(--fq-tinta) 40%, transparent);
    border-radius: 11px;
    color: var(--fq-tinta);
    font-family: var(--fq-texto);
    transition: border-color .25s, box-shadow .25s;
}
input:focus,
select:focus,
textarea:focus {
    border-color: var(--fq-acento-texto);
    box-shadow: 0 0 0 3px var(--fq-foco);
}
/* Controles discretos de las tareas (.t-ctl): la v3 les pone --surface (ahora translúcido) al acercarse o enfocar. */
.t-ctl select:hover,
.t-ctl input:hover,
.t-ctl select:focus,
.t-ctl input:focus {
    background: var(--fq-campo);
    color: var(--fq-tinta);
}
/* La lista desplegable se pinta con el fondo del <select>; los transparentes (.t-ctl, .etq-sel) la dejaban clara. */
select option,
select optgroup {
    background-color: var(--fq-campo);
    color: var(--fq-tinta);
}
input::placeholder,
textarea::placeholder {
    color: var(--fq-suave);
    opacity: 1;
}
label.f {
    font-family: var(--fq-texto);
}

/* ---------------------------------- Ventanas ---------------------------------- */
.overlay {
    background: rgba(0, 0, 0, .45);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
}
.modal {
    background: linear-gradient(160deg, var(--fq-brillo), transparent 42%), color-mix(in srgb, var(--fq-vidrio-solido) 92%, transparent);
    border: 1px solid var(--fq-borde);
    border-radius: 18px 18px 0 0;
    -webkit-backdrop-filter: blur(22px) saturate(140%);
    backdrop-filter: blur(22px) saturate(140%);
    color: var(--fq-tinta);
    box-shadow: 0 30px 80px rgba(0, 0, 0, .42);
}
@media (min-width: 720px) {
    .modal {
        border-radius: 18px;
    }
}
.toast {
    background: linear-gradient(160deg, var(--fq-brillo), transparent 60%), var(--fq-vidrio-solido);
    border: 1px solid var(--fq-borde);
    border-radius: 14px;
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
    color: var(--fq-tinta);
    box-shadow: 0 18px 40px rgba(0, 0, 0, .28);
}
/* Barra superior del celular: vidrio al 70 % (el menú y el logo se leen bajo cualquier mancha). */
.mbar {
    background: color-mix(in srgb, var(--fq-fondo) 70%, transparent);
    border-bottom-color: var(--fq-linea);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
}

/* ------------------------- Copilot y lista de avisos ------------------------- */
.cop,
.camp-panel {
    background: linear-gradient(160deg, var(--fq-brillo), transparent 42%), color-mix(in srgb, var(--fq-vidrio-solido) 92%, transparent);
    border-color: var(--fq-borde);
    -webkit-backdrop-filter: blur(22px) saturate(140%);
    backdrop-filter: blur(22px) saturate(140%);
    color: var(--fq-tinta);
}
.cop {
    border-radius: 18px;
    box-shadow: 0 30px 80px rgba(0, 0, 0, .42);
}
.camp-panel {
    border-radius: 14px;
    box-shadow: 0 18px 40px rgba(0, 0, 0, .28);
}
.camp-panel .av-i.nuevo {
    background: color-mix(in srgb, var(--fq-acento) 10%, transparent);
}
.cop-fab {
    background: var(--fq-acento-texto);
    color: var(--fq-sobre-acento);
    box-shadow: 0 8px 26px color-mix(in srgb, var(--fq-acento) 40%, transparent);
}
.chat-msgs,
.cop-msgs {
    background: color-mix(in srgb, var(--fq-tinta) 3%, transparent);
}
.cm.u .cb,
.mg.me .bub {
    background: color-mix(in srgb, var(--fq-acento) 14%, var(--fq-vidrio-solido));
    border-color: color-mix(in srgb, var(--fq-acento) 30%, transparent);
    color: var(--fq-tinta);
}
.cop-chip-ayuda {
    border-color: var(--fq-borde);
}

/* ------------------------------------ Calendario ------------------------------------ */
.cal-d.hoy {
    border-color: var(--fq-acento);
    box-shadow: inset 0 0 0 1px var(--fq-acento);
}
.cal-d.hoy .cal-n {
    color: var(--fq-acento-texto);
}
.cal-e {
    border-left-color: var(--fq-acento);
}
.cal-e:hover {
    background: color-mix(in srgb, var(--fq-acento) 12%, transparent);
}

/* ------------------- Piezas que antes llevaban style="…" en las vistas ------------------- */
/* Vista previa de la imagen que se va a subir (era style="max-height:220px" en la vista). */
.modal .prev {
    max-height: 220px;
}
.camp-h {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 14px;
    border-bottom: 1px solid var(--fq-linea);
}
.lbl-vis {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--fq-suave);
}

/* Sin backdrop-filter el vidrio no se vería: se usa su color sólido equivalente. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .tbl-w,
    .chat-app,
    .modal,
    .cop,
    .camp-panel,
    .toast,
    .mbar {
        background: var(--fq-vidrio-solido);
    }
}

/* =====================================================================
   Componentes · utilidades (u-…)

   Lo que antes iba en style="…" en las vistas, una clase por declaración
   (nombre = abreviatura de la propiedad + valor: u-mt-12 es margin-top: 12px).
   `:root:root` (0,3,0) les gana a las reglas de componente de la v3, como
   les ganaba el estilo en línea. Los valores que salen de la base (el color
   de un área, el ancho de una barra de avance) siguen en línea en la vista:
   son datos, no diseño.
   ===================================================================== */
:root:root .u-ai-center { align-items: center; }
:root:root .u-d-block { display: block; }
:root:root .u-d-flex { display: flex; }
:root:root .u-d-grid { display: grid; }
:root:root .u-d-inline-flex { display: inline-flex; }
:root:root .u-flex-1 { flex: 1; }
:root:root .u-fs-11_5 { font-size: 11.5px; }
:root:root .u-fs-12 { font-size: 12px; }
:root:root .u-fs-12_5 { font-size: 12.5px; }
:root:root .u-fs-13 { font-size: 13px; }
:root:root .u-fs-13_5 { font-size: 13.5px; }
:root:root .u-fw-400 { font-weight: 400; }
:root:root .u-fw-600 { font-weight: 600; }
:root:root .u-gap-12 { gap: 12px; }
:root:root .u-gap-6 { gap: 6px; }
:root:root .u-gc-1s-1 { grid-column: 1/-1; }
:root:root .u-jc-flex-start { justify-content: flex-start; }
:root:root .u-m-0 { margin: 0; }
:root:root .u-m-0-0-10 { margin: 0 0 10px; }
:root:root .u-m-0-0-12 { margin: 0 0 12px; }
:root:root .u-m-0-0-8 { margin: 0 0 8px; }
:root:root .u-m-10-0-4 { margin: 10px 0 4px; }
:root:root .u-m-10-2-0 { margin: 10px 2px 0; }
:root:root .u-m-14-0-6 { margin: 14px 0 6px; }
:root:root .u-m-16-0-0 { margin: 16px 0 0; }
:root:root .u-m-16-0-6 { margin: 16px 0 6px; }
:root:root .u-m-18-0-10 { margin: 18px 0 10px; }
:root:root .u-m-18-0-8 { margin: 18px 0 8px; }
:root:root .u-m-2-0-8 { margin: 2px 0 8px; }
:root:root .u-m-8-0-0 { margin: 8px 0 0; }
:root:root .u-m-auto { margin: auto; }
:root:root .u-m-n4-0-10 { margin: -4px 0 10px; }
:root:root .u-mb-10 { margin-bottom: 10px; }
:root:root .u-mb-12 { margin-bottom: 12px; }
:root:root .u-mb-6 { margin-bottom: 6px; }
:root:root .u-minw-110 { min-width: 110px; }
:root:root .u-minw-120 { min-width: 120px; }
:root:root .u-minw-150 { min-width: 150px; }
:root:root .u-minw-160 { min-width: 160px; }
:root:root .u-minw-170 { min-width: 170px; }
:root:root .u-minw-190 { min-width: 190px; }
:root:root .u-minw-560 { min-width: 560px; }
:root:root .u-minw-600 { min-width: 600px; }
:root:root .u-minw-640 { min-width: 640px; }
:root:root .u-minw-760 { min-width: 760px; }
:root:root .u-ml-6 { margin-left: 6px; }
:root:root .u-mr-6 { margin-right: 6px; }
:root:root .u-mr-auto { margin-right: auto; }
:root:root .u-mt-10 { margin-top: 10px; }
:root:root .u-mt-12 { margin-top: 12px; }
:root:root .u-mt-14 { margin-top: 14px; }
:root:root .u-mt-16 { margin-top: 16px; }
:root:root .u-mt-2 { margin-top: 2px; }
:root:root .u-mt-4 { margin-top: 4px; }
:root:root .u-mt-6 { margin-top: 6px; }
:root:root .u-mt-8 { margin-top: 8px; }
:root:root .u-p-0-12-6 { padding: 0 12px 6px; }
:root:root .u-p-14 { padding: 14px; }
:root:root .u-p-24-16 { padding: 24px 16px; }
:root:root .u-p-4-12-4-0 { padding: 4px 12px 4px 0; }
:root:root .u-pos-relative { position: relative; }
:root:root .u-wb-break-all { word-break: break-all; }
:root:root .u-wb-break-word { word-break: break-word; }
:root:root .u-ws-nowrap { white-space: nowrap; }
:root:root .u-bad { color: var(--bad); }

/* =====================================================================
   Componentes · papel (imprimir)

   En papel va siempre el claro, con fondo blanco y tinta oscura, aunque la
   pantalla esté en oscuro. Las variables de la v3 siguen a las del tema, así
   que basta con cambiar las --fq-*; los colores de significado (verde, ámbar,
   rojo, azul) vuelven a sus valores claros porque en oscuro son pálidos y
   sobre papel no se leen. Las superficies de vidrio quedan transparentes y
   sin desenfoque ni sombras (Chrome las imprime como imagen y el texto sale
   borroso); la barra lateral, el fondo y la paleta se apagan en sus secciones.
   `:root:root:root` (0,3,0) le gana a los bloques de modo de arriba.
   ===================================================================== */
@media print {
    :root:root:root {
        color-scheme: light;

        --fq-fondo: #FFFFFF;
        --fq-tinta: #0D1322;
        --fq-suave: rgba(13,19,34,.70);
        --fq-acento: #C2541C;
        --fq-acento2: #E07A34;
        --fq-acento-texto: #A94511;
        --fq-sobre-acento: #FFF6EE;
        --fq-vidrio: transparent;
        --fq-vidrio-solido: #FFFFFF;
        --fq-borde: rgba(13,19,34,.25);
        --fq-brillo: transparent;
        --fq-linea: rgba(13,19,34,.14);
        --fq-foco: transparent;
        --fq-lado: transparent;
        --fq-a1: transparent;
        --fq-a2: transparent;
        --fq-a3: transparent;

        --ok: #1E7A4F;
        --ok-soft: #EBF6F0;
        --warn: #8A5E00;
        --warn-soft: #FBF3E0;
        --bad: #B3261E;
        --bad-soft: #FCECEA;
        --info: #1F4F99;
        --info-soft: #EEF3FB;
    }
    :root:root:root .invert-dark {
        filter: none;
    }
    /* Ninguna pieza lleva desenfoque ni sombra en papel. */
    :root:root:root *,
    :root:root:root *::before,
    :root:root:root *::after {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        box-shadow: none;
        text-shadow: none;
    }
    /* Piezas flotantes y de navegación: no se imprimen. */
    .mbar,
    .scrim,
    .cop,
    .cop-fab,
    .toast,
    .overlay {
        display: none;
    }
    /* Superficies de vidrio: transparentes (el papel es el fondo). */
    .card,
    .docs,
    .log,
    .phase,
    .lotc,
    .load-i,
    .stage,
    .tr.cur,
    .cop-q,
    .cop-otro,
    .tbl-w,
    .chat-app,
    .modal {
        background: transparent;
    }
    /* El anillo de sombra de los indicadores era su borde: en papel se pasa a contorno. */
    .load-i {
        outline: 1px solid var(--fq-borde);
        outline-offset: -1px;
    }
    /* Los colores con significado, las barras y todo texto claro sobre brasa salen aunque el navegador no imprima fondos
   (sin el fondo, el texto claro quedaba casi invisible sobre el papel). */
    .bar,
    .bar > i,
    .dot,
    .badge,
    .tag,
    .btn-primary,
    .chip.on,
    .seg button.on,
    .mini button.on,
    .seg-o.on,
    .ib-s.on,
    .av,
    .unb,
    .tr-now {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
}

/* =====================================================================
   Ficha del lote  ·  fases en brasa y tareas que se tachan en brasa (tarea 6)
   La fase actual brilla como metal caliente (.fq-brasa) y las terminadas quedan
   tibias (.fq-tibia). Las pone la vista (ficha-lote.blade.php) con la misma
   lógica con que ya decide la etapa actual y las fases completas.
   Todo es adorno: el texto sigue en --fq-tinta / --ok sobre el fondo de siempre
   (AA), la brasa va en una franja y en el contorno, nunca detrás de las letras.
   Son siete piezas repetidas: nada de backdrop-filter.
   ===================================================================== */
.tr.fq-brasa,
.tr.fq-tibia {
    position: relative;
    overflow: hidden;
}
/* Franja de brasa en el borde de arriba. */
.tr.fq-brasa::before,
.tr.fq-tibia::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: var(--fq-brasa);
    background-size: 300% 100%;
    pointer-events: none;
}
/* Fase actual: contorno y resplandor de la brasa. */
.tr.fq-brasa {
    border-color: var(--fq-acento);
    box-shadow: var(--fq-sombra-chica), 0 0 22px var(--fq-foco);
}
/* Fase terminada: la misma franja, ya apagada, y un contorno tenue. Mismo tamaño que la actual para que no salte la fila. */
.tr.fq-tibia {
    padding: 8px 10px;
    border: 1px solid color-mix(in srgb, var(--fq-acento) 30%, transparent);
    border-radius: var(--fq-radio);
}
.tr.fq-tibia::before {
    opacity: .4;
}
/* La franja corre despacio solo si la persona no pidió reducir el movimiento (con la pestaña oculta
   familia-qbk.css la pausa sola). */
@media (prefers-reduced-motion: no-preference) {
    .tr.fq-brasa::before {
        animation: fq-brasa-corre 3.5s linear infinite;
    }
}
@keyframes fq-brasa-corre {
    to {
        background-position: -300% 0;
    }
}

/* Tarea hecha: se tacha con el color de la brasa (el texto sigue en --muted). */
.task.done .t-title {
    text-decoration-color: var(--fq-acento);
    text-decoration-thickness: 2px;
}

/* La casilla es el ancla de las chispas (forja-familia.js las agrega dentro de ella). */
.chk {
    position: relative;
}

@media print {
    .tr.fq-brasa::before,
    .tr.fq-tibia::before {
        display: none;
    }
    .tr.fq-brasa,
    .tr.fq-tibia {
        border-color: #999;
    }
}

/* =====================================================================
   Aprobaciones  ·  el sello «APROBADO» que golpea (tarea 7)
   Lo estampa forja-familia.js (alAprobar) cuando el servidor confirma que guardó una
   decisión «aprobado». El cuadro de decisión se cierra al decidir, así que el sello no
   vive dentro de él: va en .fq-sello-zona, una capa fija de la pantalla que pone
   modal-decision.blade.php (con wire:ignore, para que Livewire no la repinte), por
   encima del cuadro (z-index 50) y de los avisos (60).
   Secuencia (~1,2 s): el sello cae girando, la tarjeta de la etapa (.stage) tiembla y
   saltan chispas (las pone familia-qbk.js). Con «reducir movimiento» no hay
   animaciones: queda el sello quieto, y el JS lo retira solo.
   Contraste: el sello es una pieza OPACA (--fq-vidrio-solido), así que su texto no
   depende de lo que haya debajo. Oscuro: acento-texto #F2A050 sobre #181E2C = 7,9:1 y
   tinta 14,6:1. Claro: acento-texto #A94511 sobre #FBFCFD = 5,8:1 y tinta 18:1.
   Una sola pieza a la vez: sin backdrop-filter.
   ===================================================================== */
.fq-sello-zona {
    position: fixed;
    inset: 0;
    display: grid;
    place-items: center;
    pointer-events: none;
    z-index: 70;
}
.fq-sello {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 10px 22px;
    background: var(--fq-vidrio-solido);
    border: 3px solid var(--fq-acento);
    border-radius: 12px;
    box-shadow: var(--fq-sombra), 0 0 26px var(--fq-foco);
    transform: rotate(-8deg);
}
.fq-sello-t {
    font-family: var(--fq-titulo);
    font-weight: 700;
    font-size: 30px;
    letter-spacing: .08em;
    line-height: 1.1;
    color: var(--fq-acento-texto);
}
.fq-sello-p {
    font-family: var(--fq-texto);
    font-weight: 600;
    font-size: 13px;
    letter-spacing: .04em;
    color: var(--fq-tinta);
}

/* El golpe y el temblor solo existen si la persona no pidió reducir el movimiento. */
@media (prefers-reduced-motion: no-preference) {
    .fq-sello-golpe {
        animation: fq-sello-golpe 1.2s both;
    }
    .fq-temblor {
        animation: fq-tiembla .3s;
    }
}
/* Cae grande y girado, golpea (rebote corto), se queda a la vista y se apaga hacia el final. */
@keyframes fq-sello-golpe {
    0% {
        transform: rotate(-8deg) scale(2.4);
        opacity: 0;
        animation-timing-function: cubic-bezier(.5, 0, .75, 0);
    }
    32% {
        transform: rotate(-8deg) scale(1);
        opacity: 1;
    }
    38% {
        transform: rotate(-8deg) scale(1.07);
    }
    44% {
        transform: rotate(-8deg) scale(1);
    }
    82% {
        transform: rotate(-8deg) scale(1);
        opacity: 1;
    }
    100% {
        transform: rotate(-8deg) scale(1);
        opacity: 0;
    }
}
@keyframes fq-tiembla {
    20% {
        transform: translate(-3px, 1px);
    }
    40% {
        transform: translate(3px, -1px);
    }
    60% {
        transform: translate(-2px, 1px);
    }
    80% {
        transform: translate(1px, 0);
    }
}

/* En papel no hay sello (es un adorno de pantalla). */
@media print {
    .fq-sello-zona {
        display: none;
    }
}

/* =====================================================================
   Calendario y Copilot  ·  eventos que caen y respuesta que se escribe (tarea 8)
   Calendario: cada .cal-e trae style="--fq-i: N" (N = su orden en el mes, tope 19 → máximo 20 escalones); el retardo
   es N × 60 ms, así que la cascada dura como mucho ~1,1 s aunque el mes tenga cien tareas. Es solo CSS: la animación
   corre cuando el nodo ENTRA en la página. Cada evento lleva wire:key (calendario.blade.php): al cambiar de mes los
   nodos son otros y vuelven a caer; al cambiar el filtro o con un aviso, los que siguen no se repintan y no parpadean.
   Copilot: la respuesta recién llegada se descubre de arriba abajo con una máscara (forja-familia.js le pone
   .fq-revelando y la duración en --fq-rev-dur); el texto ya está entero en el DOM. Los tres puntos de «pensando» son
   los <i> que Livewire muestra con wire:loading.
   Sin backdrop-filter: los eventos se repiten decenas de veces. Todo se apaga con «reducir movimiento».
   ===================================================================== */

/* ------------------------------------ Calendario: caen en su día ------------------------------------ */
@keyframes fq-cae {
    from {
        opacity: 0;
        transform: translateY(-14px) scale(.96);
    }
    to {
        opacity: 1;
        transform: none;
    }
}
@media screen and (prefers-reduced-motion: no-preference) {
    .cal-e {
        /* «backwards»: invisible durante el retardo, pero al terminar no deja opacity ni transform fijos. */
        animation: fq-cae .5s var(--fq-ease) backwards;
        animation-delay: calc(var(--fq-i, 0) * 60ms);
    }
}

/* ------------------------------------ Copilot: «pensando» (tres puntos) ------------------------------------ */
.cop-pts {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}
.cop-think i {
    background: var(--fq-acento);
    opacity: .7;
    animation: fq-punto 1.1s ease-in-out infinite;
}
.cop-think i:nth-child(2) {
    animation-delay: .16s;
}
.cop-think i:nth-child(3) {
    animation-delay: .32s;
}
@keyframes fq-punto {
    0%,
    70%,
    100% {
        transform: translateY(0);
        opacity: .35;
    }
    35% {
        transform: translateY(-4px);
        opacity: 1;
    }
}
@media (prefers-reduced-motion: reduce) {
    .cop-think i {
        animation: none;
        opacity: .7;
    }
}

/* ------------------------------------ Copilot: la respuesta nueva se escribe ------------------------------------ */
/* La máscara mide 3 veces la altura de la burbuja: el tercio de arriba es opaco y la franja de borde (~8 % de la altura)
   es el filo que baja. De 54 % a 0 % la máscara se corre y el filo recorre la burbuja de arriba abajo. */
@keyframes fq-revela {
    from {
        -webkit-mask-position: 0 54%;
        mask-position: 0 54%;
    }
    to {
        -webkit-mask-position: 0 0;
        mask-position: 0 0;
    }
}
@media screen and (prefers-reduced-motion: no-preference) {
    .cb.fq-revelando {
        -webkit-mask-image: linear-gradient(to bottom, #000 33.3%, transparent 36%);
        mask-image: linear-gradient(to bottom, #000 33.3%, transparent 36%);
        -webkit-mask-size: 100% 300%;
        mask-size: 100% 300%;
        -webkit-mask-repeat: no-repeat;
        mask-repeat: no-repeat;
        /* Al terminar queda todo descubierto; el JS quita la clase poco después y la máscara desaparece. */
        animation: fq-revela var(--fq-rev-dur, 1400ms) linear both;
    }
}

/* En papel: sin puntos ni máscara (la respuesta sale entera). */
@media print {
    .cop-pts,
    .cop-think {
        display: none !important;
    }
    .cb.fq-revelando {
        -webkit-mask-image: none;
        mask-image: none;
        animation: none;
    }
    .cal-e {
        animation: none;
    }
}

/* =====================================================================
   Marca de Forja  ·  logos oficiales (tarea 9)
   El logo completo va arriba de la barra lateral y en /entrar: negro en claro y blanco en oscuro (respeta data-theme y,
   sin él, la preferencia del sistema; en papel sale siempre el negro). El logo QBK queda pequeño en el pie del menú.
   Los íconos de pestaña (favicon.svg, favicon-32.png, apple-touch-icon.png) los carga partials/favicon.blade.php.
   ===================================================================== */
.fq-logo-pair {
    display: block;
    width: 150px;
    flex: 0 0 150px;
}
.fq-logo {
    display: block;
    width: 100%;
    height: auto;
}
.fq-logo-negro {
    display: none;
}
:root[data-theme="light"] .fq-logo-negro {
    display: block;
}
:root[data-theme="light"] .fq-logo-blanco {
    display: none;
}
@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) .fq-logo-negro {
        display: block;
    }
    :root:not([data-theme="dark"]) .fq-logo-blanco {
        display: none;
    }
}
.entrar-marca .fq-logo-pair {
    width: min(240px, 78vw);
    flex-basis: auto;
    margin-bottom: 10px;
}
.fq-logo-qbk {
    display: block;
    width: 74px;
    height: auto;
    margin: 6px 0 0 auto;
    opacity: .76;
}
@media (max-width: 899px) {
    .side-top .fq-logo-pair {
        width: 116px;
        flex-basis: 116px;
    }
}
/* Barra superior del celular: el logo de Forja en vez del de QBK (decisión de Santiago, 2026-10-26). */
.mbar .mlogo-forja {
    width: 104px;
    flex: 0 0 104px;
}
@media print {
    :root:root:root .fq-logo-blanco {
        display: none;
    }
    :root:root:root .fq-logo-negro {
        display: block;
    }
}

/* =====================================================================
   Tarjetas de lote  ·  luz que sigue al cursor (tarea 9)
   Las tarjetas del tablero (.lotc) llevan también .fq-vidrio para recibir la luz del cursor: familia-qbk.js
   (FamiliaQbk.focos) pone --mx / --my en la .fq-vidrio bajo el puntero y familia-qbk.css enciende su ::after.
   Pero .fq-vidrio trae además desenfoque, relleno y fondo propios, y una tarjeta que se repite decenas de veces no
   puede llevar backdrop-filter. Aquí se queda solo con la luz: se devuelve el fondo plano al 82 % de siempre y se
   apaga el desenfoque. Con «reducir movimiento» la luz no sale.
   ===================================================================== */
.lotc.fq-vidrio {
    padding: 14px;
    overflow: visible;
    background: var(--fq-cristal-plano);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    transition: border-color .25s, box-shadow .25s;
}
.lotc.fq-vidrio::after {
    border-radius: inherit;       /* la luz respeta las esquinas sin necesitar overflow: hidden */
}
@media (prefers-reduced-motion: reduce) {
    .lotc.fq-vidrio::after {
        display: none;
    }
}

/* =====================================================================
   Pantallas secundarias  ·  repaso final de legibilidad (tarea 11)
   Mis tareas, Mensajes, Usuarios, Roles, Plantillas, Reglas, Bitácora, Carga masiva, Puente,
   Bandeja de BRÚJULA, Consumo del Copilot, Calendario y la ficha del lote con sus pestañas
   ya usan el sistema común (tarjetas, tablas, campos, etiquetas de «Componentes») y la entrada
   estándar (.fq-e … .fq-e5, que pone la vista). Aquí queda lo que esas pantallas necesitaban
   para leerse en los dos modos, medido contra el fondo liso y bajo cada mancha de la aurora:
     - Atenuar con opacity bajaba el texto suave por debajo de 4,5:1 (en claro el texto suave al
       55 % de opacidad llega a 2,2:1). Tareas bloqueadas o que no aplican, lotes descartados o
       en pausa y filas en pausa se quedan con opacidad completa; el estado se distingue por el
       texto suave del título, una marca en el borde y el texto que ya traían («En pausa»,
       el motivo del bloqueo, «No aplica»).
     - El verde de «hecho» (--ok) sobre la página, sin tarjeta debajo, llegaba a 4,3:1 en claro bajo
       la mancha más pesada: para texto se mezcla con la tinta del tema (--fq-ok-texto).
     - La etapa «acc» de la ficha conservaba el fondo de la v3 (tinta al 6 %, casi transparente):
       vuelve a ser una tarjeta como las demás etapas.
   Colores solo por variables del tema; sin desenfoque (todo esto se repite).
   ===================================================================== */

/* Texto de estado "hecho" que cae directo sobre la página (el tracker de la ficha no tiene tarjeta). */
:root:root {
    --fq-ok-texto: color-mix(in srgb, var(--ok) 85%, var(--fq-tinta));
}
.st-ok,
.tr.done .tr-n {
    color: var(--fq-ok-texto);
}

/* Estados atenuados sin bajar el contraste: opacidad completa y otra señal. */
.task.locked,
.task.na,
.lotc.off,
.lotc.pausa,
.lotc.pausa:hover,
tr.pausa,
tr.pausa:hover {
    opacity: 1;
}
.task.locked .t-title,
.task.na .t-title {
    color: var(--fq-suave);
}
/* Marca en el borde izquierdo (sombra interior: no mueve nada). La puerta ya trae su propia raya. */
.task.locked:not(.gate-row),
.task.na,
tr.pausa td:first-child {
    box-shadow: inset 3px 0 0 color-mix(in srgb, var(--fq-tinta) 30%, transparent);
}
.lotc.off,
.lotc.pausa {
    border-style: dashed;
}

/* Etapa «acc» de la ficha: tarjeta de vidrio como las demás (la v3 la dejaba en tinta al 6 %). */
.stage.acc {
    background: var(--fq-cristal-plano);
}

/* =====================================================================
   Cifras que ruedan  ·  arreglo visto en el navegador (2026-10-26)
   forja.css pone a todo «.load-i span» letra de 12,5 px y display:flex;
   las columnas del odómetro también son <span>, así que los dígitos
   quedaban más chicos que la ventana de 1em y se veían corridos.
   ===================================================================== */
.load-i .fq-odo span {
    font-size: inherit;
    color: inherit;
    gap: 0;
}
