/*
 * Lo que el NÚCLEO pone en toda página pública, sea cual sea su diseño.
 *
 * Se carga siempre y una web no lo sustituye: el aviso de cookies y el
 * cartel de un vídeo retenido —sin ellos la web no cumple—, el campo
 * trampa de los formularios —visible, quien lo rellenara vería su
 * mensaje descartado sin aviso—, el foco visible, el texto solo para
 * lectores de pantalla, el respeto al movimiento reducido y las zonas
 * del layout `con-aside`, que es una plantilla del núcleo. Y, desde la
 * v1.8, lo que significan las clases que guarda el editor de texto:
 * alinear un párrafo y dar forma a una tabla.
 *
 * El aspecto de SERIE —reset, tipografía, colores del documento— está
 * desde la v1.6 (2026-10-13) en `base.css`, que una web con diseño
 * propio puede sustituir por la suya. Antes vivía todo aquí, desde que
 * esta hoja se escribió el 2026-08-12 al descubrir que la web pública
 * no tenía ni reset ni tipografía.
 *
 * Todo dentro de `@layer` para que cualquier regla que una web escriba
 * sin capa gane sobre esto sin pelear con la especificidad, salvo la
 * geometría del aviso y del campo trampa, que van fuera a propósito
 * (ver cada bloque).
 */

/* `iris.tokens` es la capa del vocabulario (`tokens.css`, desde la v1.1),
 * que se carga antes: nombrarla aquí la deja la más baja aunque un día
 * cambie el orden de carga. `base.css` declara este mismo orden. */
@layer iris.tokens, iris.reset, iris.base, iris.layout, iris.components;

@layer iris.reset {

    /* Directriz de accesibilidad: quien pide menos movimiento, lo obtiene
     * en toda la plataforma, sin que cada módulo tenga que acordarse. */
    @media (prefers-reduced-motion: reduce) {
        *,
        *::before,
        *::after {
            animation-duration: 0.01ms !important;
            animation-iteration-count: 1 !important;
            transition-duration: 0.01ms !important;
            scroll-behavior: auto !important;
        }
    }
}

@layer iris.base {

    /* Texto solo para lectores de pantalla (2026-09-01).
     *
     * Lo estrenan los bloques de galería, logotipos y slider: el enlace
     * de un logotipo no tiene más contenido que el dibujo, y un enlace
     * sin nombre accesible se anuncia como «enlace» y ya. No se usa
     * `display: none`, que lo borraría también para ellos.
     *
     * Vive en la hoja del NÚCLEO y no en la del módulo `html` porque no
     * es de ningún bloque: cualquier módulo con un botón de solo icono
     * la va a necesitar. Es la gemela pública de `.panel-sr`. */
    .iris-visualmente-oculto {
        position: absolute;
        inline-size: 1px;
        block-size: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }

    /* Foco visible SIEMPRE (WCAG 2.2): quitarlo sin sustituirlo es el
     * error de accesibilidad más repetido de la web. */
    :focus-visible {
        outline: 2px solid var(--color-accent, #2563eb);
        outline-offset: 2px;
    }
}

@layer iris.layout {

    /* Zonas del layout 'con-aside' que trae el núcleo. Se adapta sin un
     * solo breakpoint: en cuanto el aside no cabe en su mínimo, las dos
     * columnas se apilan solas. */
    .iris-layout-con-aside {
        display: grid;
        gap: var(--space-4, 1.5rem);
    }

    .iris-layout-cuerpo {
        display: grid;
        gap: var(--space-4, 1.5rem);
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
        align-items: start;
    }

    /* El main ocupa el resto: el aside se queda en su columna mínima y
     * el contenido principal crece. */
    .iris-layout-main {
        grid-column: span 2;
        min-width: 0;
    }

    /* Con una sola columna (móvil), ese `span 2` sobra. */
    @media (width < 45rem) {
        .iris-layout-main {
            grid-column: auto;
        }
    }
}

@layer iris.components {
    /*
     * Aviso de cookies.
     *
     * Nace oculto (`hidden` en el HTML) y lo enseña el JavaScript solo a
     * quien no ha decidido todavía. Al revés —visible y ocultándolo
     * después— habría un parpadeo en cada visita de quien ya aceptó.
     *
     * Solo usa tokens, como todo el CSS del núcleo, así que se tiñe con
     * la identidad de cada web sin tocar una regla.
     */
    /* El cartel de un vídeo retenido hasta que se acepten las cookies
     * (2026-09-08). Sin él, el visitante ve un rectángulo vacío y no
     * tiene forma de saber que falta algo — el aviso de cookies puede
     * estar abajo del todo, o ya cerrado con un «no». */
    .iris-embed-aviso {
        margin-block: var(--space-3, 1rem) 0;
        padding: var(--space-2, 0.5rem) var(--space-3, 1rem);
        border: 1px dashed var(--color-border, #d4d4d8);
        border-radius: var(--radius-md, 0.5rem);
        background: var(--color-surface-alt, #f4f4f5);
        color: var(--color-text-muted, #55555e);
        font-size: 0.9375rem;
    }

    /* Un iframe sin `src` no pinta nada pero sigue ocupando su hueco, y
     * un recuadro vacío al lado del cartel se lee como un fallo. */
    iframe[data-iris-embed] {
        display: none;
    }

    /* La geometría del aviso va FUERA de la capa: ver el bloque de
     * después de esta capa. Aquí queda el aspecto. */
    .iris-cookies {
        background: var(--color-surface, #fff);
        color: var(--color-text, #111);
        border-block-start: 1px solid var(--color-border, #ddd);
        box-shadow: 0 -2px 12px rgb(0 0 0 / 8%);
    }

    .iris-cookies__texto {
        font-size: 0.9375rem;
    }

    /*
     * Los dos botones pesan lo mismo a propósito. Un «rechazar»
     * descolorido o escondido es lo que la AEPD considera consentimiento
     * no válido: si cuesta más decir que no que decir que sí, la elección
     * no ha sido libre. El de aceptar se distingue por el color de
     * marca, no por ser el único que parece un botón.
     *
     * Su alto mínimo de 44px —el área táctil que exige WCAG 2.2— es
     * geometría y va fuera de la capa, con el resto.
     */
    .iris-cookies__btn {
        border: 1px solid var(--color-border, #ddd);
        border-radius: var(--radius-sm, 4px);
        background: transparent;
        color: inherit;
        font: inherit;
        cursor: pointer;
    }

    .iris-cookies__btn--si {
        background: var(--color-accent, #2563eb);
        border-color: var(--color-accent, #2563eb);
        color: var(--color-accent-contrast, #fff);
    }

    .iris-cookies__btn:focus-visible {
        outline: 2px solid var(--color-accent, #2563eb);
        outline-offset: 2px;
    }

    /* Lo que se eligió la última vez, al volver a abrir el aviso
     * (2026-09-28): una línea discreta encima del texto. */
    .iris-cookies__estado {
        color: var(--color-text-muted, #55555e);
        font-size: 0.875rem;
    }

    /* El botón propio del aviso para volver a abrirlo, cuando la página
     * no trae su enlace. Discreto a propósito: está en todas las
     * páginas y no debe competir con el contenido. */
    .iris-cookies-abrir {
        border: 1px solid var(--color-border, #ddd);
        border-radius: 999px;
        background: var(--color-surface, #fff);
        color: var(--color-text, #111);
        box-shadow: 0 2px 8px rgb(0 0 0 / 12%);
        font: inherit;
        font-size: 0.875rem;
        cursor: pointer;
    }

    .iris-cookies-abrir:focus-visible,
    .iris-embed-aviso button:focus-visible {
        outline: 2px solid var(--color-accent, #2563eb);
        outline-offset: 2px;
    }

    /* El botón del cartel de un vídeo retenido se lee como un enlace:
     * va dentro de una frase. */
    .iris-embed-aviso button {
        padding: 0;
        border: 0;
        background: none;
        color: var(--color-accent, #2563eb);
        font: inherit;
        text-decoration: underline;
        cursor: pointer;
    }
}

/* ── Lo que el editor de texto guarda en las tablas (v1.8, 2026-10-16) ─
   El editor no guarda estilos: guarda clases de una lista cerrada
   (`Sanitizer::CLASSES`) y aquí está lo que significan. Dentro de la
   capa, como todo lo que es aspecto: una web que quiera sus tablas de
   otra manera escribe sus reglas sin capa y ganan sin más. Solo tokens,
   así que una tabla se tiñe con los colores de cada web. */
@layer iris.components {
    .iris-tabla {
        margin-block: var(--space-4, 1.5rem);
        border-collapse: collapse;
        font-variant-numeric: tabular-nums;
    }

    .iris-tabla--ancha {
        inline-size: 100%;
    }

    .iris-tabla--centro {
        margin-inline: auto;
    }

    .iris-tabla caption {
        padding-block-end: var(--space-2, 0.5rem);
        font-weight: 600;
        text-align: start;
    }

    .iris-tabla :is(th, td) {
        padding: var(--space-2, 0.5rem) var(--space-3, 1rem);
        border-block-end: 1px solid var(--color-border, #d4d4d8);
        text-align: start;
        vertical-align: top;
    }

    .iris-tabla th {
        font-weight: 600;
    }

    .iris-tabla thead th {
        border-block-end-width: 2px;
    }

    .iris-tabla--todas :is(th, td) {
        border: 1px solid var(--color-border, #d4d4d8);
    }

    .iris-tabla--sin-bordes :is(th, td) {
        border: 0;
    }

    .iris-tabla--cebra tbody tr:nth-child(even) {
        background: var(--color-surface-alt, #f4f4f5);
    }

    /* En el móvil, una tabla de muchas columnas no cabe y empujaría la
       página hacia un lado. No se le cambia el `display` para hacerla
       deslizable, que en algunos lectores de pantalla le quita el ser
       tabla: se deja que las palabras largas se partan, y así encoge. */
    @media (width < 40rem) {
        .iris-tabla :is(th, td) {
            padding-inline: var(--space-2, 0.5rem);
            overflow-wrap: anywhere;
            hyphens: auto;
        }
    }
}

/* ── La alineación de un párrafo, FUERA de la capa y con `!important` ─
   Al revés que la tabla, esto no es aspecto: es lo que quien escribe
   decidió para ESE párrafo. Dentro de la capa, cualquier tema que
   justifique sus párrafos sin capa (`p { text-align: justify }`) se la
   comería sin avisar. Es el mismo trato que dan a sus utilidades de
   alineación los marcos CSS más usados, por la misma razón. */
.iris-alinear-izquierda {
    text-align: left !important;
}

.iris-alinear-centro {
    text-align: center !important;
}

.iris-alinear-derecha {
    text-align: right !important;
}

/* ── La geometría del aviso de cookies, FUERA de la capa (2026-09-28) ─
   Medido en una web sobre una plantilla comprada: el tema trae
   `* { margin: 0; padding: 0 }` sin capa, y como todo el CSS del núcleo
   vive dentro de `@layer`, cualquier hoja sin capa le gana. El aviso
   salía sin un solo píxel de relleno, con el texto pegado al borde y los
   botones del tamaño de su palabra. Un selector de clase gana a `*` por
   especificidad, se cargue lo que se cargue después, así que lo que
   hace que el aviso se lea y se pueda pulsar va aquí. El aspecto
   —colores, bordes, sombra— sigue dentro de la capa: eso sí es cosa del
   sitio. Es el mismo reparto que el lightbox (2026-09-11).

   `z-index` al máximo: el aviso es la ÚNICA salida que tiene el
   visitante hasta que decide, así que no puede quedar debajo de nada.
   Con 100 lo tapaba la pantalla de carga de ese mismo tema (9999), y
   sin poder aceptar, la pantalla de carga no se iba nunca. */
.iris-cookies {
    position: fixed;
    inset-inline: 0;
    inset-block-end: 0;
    z-index: 2147483647;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4, 1.5rem);
    padding: var(--space-4, 1.5rem);
}

/* Tiene que ir aquí y no dentro de la capa: el `display: flex` de
   arriba también vive sin capa, y un selector en `@layer` nunca le
   ganaría, por mucha especificidad que tuviera. */
.iris-cookies[hidden] {
    display: none;
}

.iris-cookies__texto {
    margin: 0;
    flex: 1 1 22rem;
}

.iris-cookies__botones {
    display: flex;
    gap: var(--space-2, 0.5rem);
    flex-wrap: wrap;
}

.iris-cookies__btn {
    min-block-size: 44px;
    padding-inline: var(--space-4, 1.5rem);
}

/* La línea de «lo que elegiste»: encima del texto y a lo ancho, y
   más cerca de él que el hueco que separa el texto de los botones. */
.iris-cookies__estado {
    order: -1;
    flex: 1 1 100%;
    margin: 0 0 calc(var(--space-3, 1rem) * -1);
}

.iris-cookies__estado[hidden] {
    display: none;
}

/* El botón para volver a abrir el aviso: en la esquina de abajo a la
   izquierda —la de la derecha suele tenerla un chat— y justo por
   debajo del aviso, que cuando se abre lo tapa. */
.iris-cookies-abrir {
    position: fixed;
    inset-inline-start: var(--space-3, 1rem);
    inset-block-end: var(--space-3, 1rem);
    z-index: 2147483646;
    min-block-size: 44px;
    margin: 0;
    padding-inline: var(--space-3, 1rem);
}

.iris-cookies-abrir[hidden] {
    display: none;
}

/* ── El campo trampa de los formularios, FUERA de la capa (v1.6) ─────
   Un bot lo rellena y una persona no lo ve: el núcleo descarta en
   silencio el envío que lo trae (`Antispam`). Por eso esconderlo no es
   cosa del diseño. Lo marcan las plantillas de `contacto` y
   `comentarios` con `data-iris-trampa`, un atributo y no una clase:
   una clase es del diseño y una web la cambia al maquetar; el atributo
   es el contrato. Vivía solo en la hoja de cada módulo, y una web que
   la apagara dejaba el campo a la vista.

   Se saca de la pantalla en vez de usar `display: none`, que algunos
   bots reconocen. Fuera de la capa por lo mismo que el aviso de
   cookies: un tema con un `div { position: relative }` sin capa lo
   devolvería a su sitio. */
[data-iris-trampa] {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
