/* ═══════════════════════════════════════════════════════════════════════════
   Campus — LA PUERTA: la pantalla de acceso de la web (index.php) y la de la
   app (app_login_page.php). Diseño T2 «editorial», aprobado por el dueño el
   29-sep-2026 sobre la captura t2-editorial-oscuro.

   ÚNICA fuente de los tokens `--acc-*`, de las @font-face y de los componentes
   de la puerta. Las dos páginas la enlazan con asset_url(); el trámite
   (forgot_password, reset_password, verify_2fa, admin/login) la enlaza SÓLO
   por la letra.

   ☠️ CONTRATOS — cada uno existe porque romperlo ya se midió o se pagó:

   1. TODO componente cuelga de `.acc`, y `.acc` va en el <html> de la página
      (`<html lang="…" class="acc">`; la app añade `acc--app`). El trámite enlaza
      esta hoja y NO lleva `.acc`: ninguna regla de aquí le pinta nada, ni el
      autorrelleno. En `:root` sólo hay PROPIEDADES PERSONALIZADAS: ni
      `color-scheme` ni un solo color aplicado. El `color-scheme` se aplica en
      `.acc` a través de `--acc-esquema`.

   2. ☠️☠️ NINGUNA regla de esta hoja fija `font-size` ni el atajo `font:` a un
      campo: ni a input/textarea/select, ni a #email/#password, ni a un [type…],
      ni a un comodín. La letra de los campos (16 px) vive en el <style> EN LÍNEA
      de cada página, que es lo único que mide LoginCamposSinZoomIosTest (iOS
      amplía la página al enfocar un campo de menos de 16 px). Una regla de aquí
      con más especificidad le ganaría y la suite seguiría VERDE: es el punto
      ciego que cierra la regla (f) de PaginasDeAccesoSinTercerosTest. Por eso
      los campos reciben `font-family` suelta, nunca `font: inherit`.

   3. `url('fonts/…')` RELATIVA a esta hoja: el producto vive en varias
      instalaciones del mismo docroot (edu, staging…) y staging se sirve SIN
      /edu. Una ruta raíz-absoluta da 404 y el navegador cae a la reserva sin
      decir nada (precedente: assets/campus-brand.css, 16-ago-2026).

   4. Las fuentes llevan la VERSIÓN EN EL NOMBRE (newsreader-v26-…,
      sourcesans3-v19-…, firma-r1): /assets se sirve `immutable` un año
      (.htaccess) y el service worker las guarda cache-first por URL. Un
      fichero cambiado con el mismo nombre no llegaría a nadie en un año.

   5. NO crear `acceso.min.css`: asset_url() lo preferiría EN SILENCIO y un
      arreglo aquí dejaría de servirse.

   6. Tema: OSCURO por defecto en `:root`; claro con
      `@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) }`
      y con `:root[data-theme="light"]`. ⚠️ El `:not([data-theme="dark"])` NO
      se quita al «deduplicar»: sin él, quien eligió oscuro con el sistema en
      claro vería claro. Los dos bloques claros son la MISMA lista, a propósito
      (no se pueden fundir en una sola regla).

   7. La FIRMA en itálica es un SUBCONJUNTO: sólo trae los caracteres de las
      cadenas de firma de es.php y en.php (claves `acc_firma*`). Un carácter
      nuevo caería a Georgia letra a letra. Si cambia una firma, se regenera:
        python3 -m fontTools.subset newsreader-italic-400-latin.woff2 \
          --text-file=<unión de las firmas es+en> --layout-features='*' \
          --name-IDs='*' --flavor=woff2 \
          --output-file=assets/fonts/newsreader-v26-italic-400-firma-rN.woff2
      (hace falta `pip install --user brotli`; la fuente de partida es la
      Newsreader itálica 400 latin de Google Fonts v26), se sube la N del nombre
      y se reescribe su `unicode-range` aquí abajo. La guarda compara ese
      unicode-range con las cadenas de es.php/en.php.

   8. Source Sans 3 NO se recorta: su OFL reserva el nombre «Source» y una copia
      recortada por nosotros sería una Versión Modificada. Va tal cual la sirve
      Google (latin y latin-ext). Newsreader no tiene nombre reservado.

   9. «ESCRITORIO» es UNA condición, escrita IGUAL en todos sus sitios: las
      @media de escritorio de aquí abajo (la escena, el panel IB y la de
      portátiles, que le añade la altura), el `media` de la precarga de la
      primera foto y el matchMedia() del JS de index.php:
        (min-width: 900px) and (hover: hover) and (pointer: fine)
      Por ancho sólo, un teléfono APAISADO (932×430, 915×412) pasaba de 900 px:
      veía el panel de fotos y las DESCARGABA (medido el 30-sep-2026), contra
      la decisión del dueño. Si una de las cuatro difiere, la hoja pinta un
      panel que el JS no llena, o el JS descarga lo que la hoja no enseña.
      Lo exige PuertaDeAccesoDecisionesTest.

   ⚖️ LICENCIAS (SIL OFL 1.1, exigen acompañar la fuente): assets/fonts/
      OFL-Newsreader.txt y OFL-SourceSans3.txt, copiadas verbatim de google/fonts.

   CLASES QUE USAN LAS PÁGINAS (todas bajo `.acc`):
     .acc-fondo                    capa fija del fondo (aria-hidden)
     .acc-escena[.acc-escena--panel]  envoltorio: panel de fotos o panel IB +
                                   columna (--panel: hay panel IB)
     .visual[.fallback] .slides .slide[.on] .seam
                                   panel de FOTOS del colegio (sólo ≥900 px; los
                                   nombres los fija LoginPhotosTest); .fallback
                                   = sin fotos ⇒ no se pinta nada
     .acc-fotos-velo .acc-puntos   velo y puntos del panel de fotos
     .acc-panel .acc-panel-cuerpo .acc-panel-roseta .acc-panel-antetitulo
     .acc-panel-titular .acc-panel-roles .acc-panel-rol .acc-panel-quien
     .acc-panel-que .acc-panel-tramo .acc-panel-pie
                                   panel IB (sólo escritorio y sin fotos; lo pinta
                                   includes/components/acceso_panel.php)
     .acc-pantalla                 la columna (440 px)
     .acc-barra .acc-idioma .acc-idioma-op[aria-current] .acc-idioma-sep
     .acc-tema .acc-tema-sol .acc-tema-luna   interruptor 🌙/☀️ (el icono sale
                                   del tema EFECTIVO, sin JS)
     .acc-marca …                  lo pinta includes/components/acceso_marca.php
     .acc-tarjeta .acc-cabecera .acc-titulo .acc-entradilla
     .acc-aviso[.acc-aviso--nota|.is-note] .acc-aviso-texto .acc-aviso-titulo
                                   .acc-aviso-cuerpo  (el icono es ::before: un
                                   textContent sobre el aviso no lo borra)
     .acc-campo[.is-invalid] .acc-control[.acc-control--clave] .acc-ico-guia
     .acc-revelar[aria-pressed] .acc-ojo-si .acc-ojo-no
     .acc-meta .acc-enlace
     .acc-boton[.is-bloqueado] .acc-giro .acc-flecha  ·  .acc-boton-fantasma
                                   .acc-boton-fantasma-cuerpo
     .acc-separador .acc-google
     .acc-colegios-titulo .acc-colegios-entradilla .acc-colegios-lista
     .acc-colegio .acc-colegio-nombre .acc-colegio-rol   (lista TRAS autenticar)
     .acc-pie .acc-cifrada .acc-legal .acc-legal-sep .acc-copy
     .acc-arranque[.is-out] .acc-arranque-sello .acc-arranque-dial
     .acc-arranque-anillo .acc-arranque-titulo .acc-arranque-sub
     .acc-arranque-firma .acc-arranque-marca     capa de arranque de la app
     .acc-ico .acc-sr .acc-sube .acc-d2 .acc-d3  utilidades
   ═══════════════════════════════════════════════════════════════════════════ */


/* ── Fuentes propias (ninguna petición a Google) ─────────────────────────────
   Newsreader (Production Type) — serif de texto con eje de tamaño óptico
   6–72: roman 500 para la marca y los titulares, itálica 400 sólo para la
   firma. Source Sans 3 (Adobe) variable 200–900 para toda la interfaz.
   Mismos unicode-range que Google: latin-ext sólo se descarga si aparece uno
   de sus caracteres. `font-weight` = lo que el fichero contiene de verdad; con
   `font-synthesis: none` un peso que no existe se pintaría con el más cercano,
   nunca con una negrita falsa.
   ────────────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/newsreader-v26-roman-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/newsreader-v26-roman-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
/* La FIRMA: subconjunto de 19 caracteres, la unión EXACTA de
   «by Clase Privada», «en Campus · by Clase Privada» y «on Campus · by Clase
   Privada» (claves acc_firma / acc_firma_colegio, es y en). 7.412 B frente a
   los 63.212 B de la itálica latin completa. Contrato 7 arriba. */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/newsreader-v26-italic-400-firma-r1.woff2') format('woff2');
  unicode-range: U+20, U+43, U+50, U+61-62, U+64-65, U+69, U+6C-70, U+72-73,
    U+75-76, U+79, U+B7;
}
@font-face {
  font-family: 'Source Sans 3';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('fonts/sourcesans3-v19-var-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Source Sans 3';
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url('fonts/sourcesans3-v19-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Caras de RESERVA ajustadas ──────────────────────────────────────────────
   Con `swap` se pinta primero la fuente del sistema y luego la propia. Sin
   ajuste, el titular cambia de ancho un 6 % y la firma un 18 % al llegar la
   fuente, y el titular puede saltar de línea. Valores medidos el 29-sep-2026
   (método de next/font: size-adjust = ancho medio propio / ancho medio de la
   reserva sobre las cadenas reales; overrides = métrica hhea / UPM /
   size-adjust) y comprobados en Chromium: el salto de ancho queda por debajo
   del 0,8 %.
     roman 500 (titular 28 px)  vs Georgia         93,60 / 78,52 / 28,31 / 0
     itálica 400 (firma 19 px)  vs Georgia Italic  84,77 / 86,71 / 31,26 / 0
     Source Sans 3 400          vs Arial           93,17 / 109,90 / 42,93 / 0
     Source Sans 3 600          vs Arial Bold      88,81 / 115,30 / 45,04 / 0
   ⚠️ NO MEDIDO en Android: allí no hay Georgia ni Arial (cae a Noto Serif /
      Roboto SIN ajuste). No se añade local('Noto Serif')/local('Roboto')
      mientras no se mida en un dispositivo o emulador que casan y con qué
      métricas: unos valores sacados de las copias de Google Fonts, aplicados a
      ciegas, podrían empeorar el salto en vez de quitarlo.
   ────────────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Newsreader Reserva';
  font-style: normal;
  font-weight: 500;
  src: local('Georgia');
  size-adjust: 93.6%;
  ascent-override: 78.52%;
  descent-override: 28.31%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Newsreader Reserva';
  font-style: italic;
  font-weight: 400;
  src: local('Georgia Italic'), local('Georgia-Italic');
  size-adjust: 84.77%;
  ascent-override: 86.71%;
  descent-override: 31.26%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Source Sans 3 Reserva';
  font-style: normal;
  font-weight: 200 500;
  src: local('Arial'), local('ArialMT');
  size-adjust: 93.17%;
  ascent-override: 109.9%;
  descent-override: 42.93%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Source Sans 3 Reserva';
  font-style: normal;
  font-weight: 600 900;
  src: local('Arial Bold'), local('Arial-BoldMT');
  size-adjust: 88.81%;
  ascent-override: 115.3%;
  descent-override: 45.04%;
  line-gap-override: 0%;
}


/* ── Tokens ──────────────────────────────────────────────────────────────────
   OSCURO por defecto (continúa el splash nativo). Contrastes WCAG medidos
   sobre estos hex el 29-sep-2026: tinta 15,9:1 · tinta-3 7,1:1 · marcador
   del campo 5,63:1 · firma dorada 8,98:1 · borde del campo 3,40:1 · botón
   11,5–14,2:1. Claro: tinta-3 5,44:1 · marcador 4,83:1 · firma 5,53:1 ·
   borde 3,19:1.
   ────────────────────────────────────────────────────────────────────────── */
:root {
  --acc-serif: 'Newsreader', 'Newsreader Reserva', Georgia, 'Times New Roman', serif;
  --acc-sans: 'Source Sans 3', 'Source Sans 3 Reserva', Arial, system-ui, -apple-system,
    'Segoe UI', Roboto, sans-serif;
  --acc-curva: cubic-bezier(.2, .7, .2, 1);

  /* Escala: tercera mayor sobre 16 px, redondeada a píxel entero. Nada de lo
     que se lee baja de 15 px (se escribe pensando en profesores mayores). */
  --acc-fs-marca: 48px;
  --acc-fs-titulo: 28px;
  --acc-fs-firma: 19px;
  --acc-fs-cuerpo: 17px;
  --acc-fs-ui: 15px;
  --acc-fs-pie: 15px;

  /* FIJOS: no cambian con el tema, a propósito. */
  --acc-fijo-marino: #0C1222;        /* splash nativo + barra de estado del APK (docs/BRAND.md) */
  --acc-fijo-marfil: #F3EDE2;
  --acc-fijo-oro: #C9A24B;
  --acc-fijo-azulejo: #FFFDF8;       /* azulejo del logo del colegio: un logo oscuro o
                                        transparente desaparecería sobre el marino */
  --acc-fijo-arranque-sub: #A3ACBD;
  --acc-fijo-arranque-firma: #CDAE68;
  --acc-fijo-arranque-marca: #E9E2D3;
  --acc-fijo-google-bg: #FFFFFF;     /* botón de Google: blanco ESTÁNDAR en los dos temas */
  --acc-fijo-google-linea: #DADCE0;  /* (sus normas de marca no admiten restilarlo) */
  --acc-fijo-google-tinta: #3C4043;

  /* Oscuro */
  --acc-esquema: dark;
  --acc-bg: #0A1326;
  --acc-bg-app: #0C1222;             /* la app, EXACTO el del splash y la barra de estado */
  --acc-fondo-escena:
    radial-gradient(140% 62% at 50% -14%, rgba(37, 84, 170, .55) 0%, rgba(37, 84, 170, 0) 60%),
    radial-gradient(90% 45% at 50% 112%, rgba(201, 162, 75, .08) 0%, rgba(201, 162, 75, 0) 70%),
    linear-gradient(180deg, #0B1731 0%, #0A1326 52%, #0A1224 100%);
  /* La app: el MISMO fondo que la web (la captura aprobada), pero la fila de arriba es
     #0C1222 exacto (sin costura con la barra de estado nativa) y la base acaba en #0C1222.
     La banda es de 56 px: con 96 px (etapa 1) el halo azul de arriba quedaba visiblemente
     más plano que en la captura. Medido el 30-sep-2026 a 412×915: fila 0 = #0C1222 y, por
     debajo de la banda, diferencia media 0,00/255 con t2-editorial-oscuro.png. */
  --acc-fondo-escena-app:
    linear-gradient(180deg, #0C1222 0, rgba(12, 18, 34, 0) 56px),
    radial-gradient(140% 62% at 50% -14%, rgba(37, 84, 170, .55) 0%, rgba(37, 84, 170, 0) 60%),
    radial-gradient(90% 45% at 50% 112%, rgba(201, 162, 75, .08) 0%, rgba(201, 162, 75, 0) 70%),
    linear-gradient(180deg, #0B1731 0%, #0A1326 52%, #0C1222 100%);
  --acc-velo: 10, 19, 38;            /* rgb del velo del panel de fotos */
  --acc-tinta: #F3EDE2;
  --acc-tinta-2: #C3C8D2;
  --acc-tinta-3: #97A1B2;
  --acc-ph: #8490A3;
  --acc-acento: #D4B062;             /* dorado para TEXTO e iconos */
  --acc-acento-linea: #C9A24B;       /* dorado para LÍNEAS */
  --acc-acento-subrayado: rgba(212, 176, 98, .5);
  --acc-halo: rgba(59, 130, 246, .30);
  --acc-roseta-op: .13;
  --acc-tarjeta-bg: linear-gradient(180deg, rgba(21, 36, 68, .78) 0%, rgba(12, 21, 40, .78) 100%);
  --acc-tarjeta-linea: rgba(201, 162, 75, .17);
  --acc-tarjeta-sombra: 0 40px 80px -40px rgba(0, 0, 0, .85), inset 0 1px 0 rgba(255, 255, 255, .04);
  --acc-campo-bg: #0B1529;
  --acc-campo-bg-foco: #0D1830;
  --acc-campo-linea: #636B7C;
  --acc-campo-linea-hover: #7D8597;
  --acc-anillo: rgba(201, 162, 75, .22);
  --acc-cta-bg: linear-gradient(180deg, #F6EFE1 0%, #E7D8B3 100%);
  --acc-cta-tinta: #0A1F45;
  --acc-cta-linea: rgba(201, 162, 75, .85);
  --acc-cta-sombra: inset 0 1px 0 rgba(255, 255, 255, .65), 0 16px 32px -14px rgba(201, 162, 75, .45);
  --acc-fantasma-linea: rgba(201, 162, 75, .55);
  --acc-err-bg: rgba(255, 122, 99, .08);
  --acc-err-linea: rgba(255, 138, 117, .38);
  --acc-err-tinta: #FFC1B6;
  --acc-err-tinta-2: #F2B3A7;
  --acc-err-campo: #F08A76;
  --acc-err-anillo: rgba(240, 138, 118, .22);
  --acc-nota-bg: rgba(201, 162, 75, .07);
  --acc-nota-linea: rgba(201, 162, 75, .32);
  --acc-nota-tinta: #E9E2D3;
  --acc-mono-bg: rgba(201, 162, 75, .08);
  --acc-sello-bg: rgba(10, 19, 38, .25);
  --acc-azulejo-sombra: 0 14px 30px -12px rgba(0, 0, 0, .6);
  --acc-tema-sol: block;             /* en oscuro se ofrece pasar a claro */
  --acc-tema-luna: none;
}

/* Claro: «papel de diploma» — marfil, tinta marino, dorado oscurecido para texto.
   ⚠️ Esta lista y la de :root[data-theme="light"] son IDÉNTICAS (contrato 6). */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --acc-esquema: light;
    --acc-bg: #F5F1E8;
    --acc-bg-app: #F5F1E8;
    --acc-fondo-escena:
      radial-gradient(140% 60% at 50% -14%, rgba(201, 162, 75, .20) 0%, rgba(201, 162, 75, 0) 60%),
      linear-gradient(180deg, #F2ECDF 0%, #F6F2EA 50%, #F4F0E7 100%);
    --acc-fondo-escena-app:
      radial-gradient(140% 60% at 50% -14%, rgba(201, 162, 75, .20) 0%, rgba(201, 162, 75, 0) 60%),
      linear-gradient(180deg, #F2ECDF 0%, #F6F2EA 50%, #F4F0E7 100%);
    --acc-velo: 245, 241, 232;
    --acc-tinta: #0A1F45;
    --acc-tinta-2: #34425E;
    --acc-tinta-3: #56627A;
    --acc-ph: #687288;
    --acc-acento: #7A5C17;
    --acc-acento-linea: #B08A34;
    --acc-acento-subrayado: rgba(122, 92, 23, .45);
    --acc-halo: rgba(201, 162, 75, .22);
    --acc-roseta-op: .16;
    --acc-tarjeta-bg: #FFFDF8;
    --acc-tarjeta-linea: rgba(138, 106, 31, .20);
    --acc-tarjeta-sombra: 0 30px 60px -36px rgba(10, 31, 69, .30), 0 1px 0 rgba(255, 255, 255, .8) inset;
    --acc-campo-bg: #FFFFFF;
    --acc-campo-bg-foco: #FFFFFF;
    --acc-campo-linea: #9A8F7A;
    --acc-campo-linea-hover: #7F7562;
    --acc-anillo: rgba(176, 138, 52, .22);
    --acc-cta-bg: linear-gradient(180deg, #143675 0%, #0A1F45 100%);
    --acc-cta-tinta: #F7F1E3;
    --acc-cta-linea: rgba(201, 162, 75, .75);
    --acc-cta-sombra: inset 0 1px 0 rgba(255, 255, 255, .14), 0 16px 30px -16px rgba(10, 31, 69, .55);
    --acc-fantasma-linea: rgba(138, 106, 31, .55);
    --acc-err-bg: #FCEEEA;
    --acc-err-linea: #EDC2B8;
    --acc-err-tinta: #8E2618;
    --acc-err-tinta-2: #9A2A1C;
    --acc-err-campo: #C2412D;
    --acc-err-anillo: rgba(194, 65, 45, .16);
    --acc-nota-bg: #F8F0DC;
    --acc-nota-linea: #E3CF9C;
    --acc-nota-tinta: #3D3218;
    --acc-mono-bg: rgba(176, 138, 52, .08);
    --acc-sello-bg: rgba(255, 253, 248, .7);
    --acc-azulejo-sombra: 0 10px 24px -14px rgba(10, 31, 69, .45);
    --acc-tema-sol: none;
    --acc-tema-luna: block;
  }
}
:root[data-theme="light"] {
  --acc-esquema: light;
  --acc-bg: #F5F1E8;
  --acc-bg-app: #F5F1E8;
  --acc-fondo-escena:
    radial-gradient(140% 60% at 50% -14%, rgba(201, 162, 75, .20) 0%, rgba(201, 162, 75, 0) 60%),
    linear-gradient(180deg, #F2ECDF 0%, #F6F2EA 50%, #F4F0E7 100%);
  --acc-fondo-escena-app:
    radial-gradient(140% 60% at 50% -14%, rgba(201, 162, 75, .20) 0%, rgba(201, 162, 75, 0) 60%),
    linear-gradient(180deg, #F2ECDF 0%, #F6F2EA 50%, #F4F0E7 100%);
  --acc-velo: 245, 241, 232;
  --acc-tinta: #0A1F45;
  --acc-tinta-2: #34425E;
  --acc-tinta-3: #56627A;
  --acc-ph: #687288;
  --acc-acento: #7A5C17;
  --acc-acento-linea: #B08A34;
  --acc-acento-subrayado: rgba(122, 92, 23, .45);
  --acc-halo: rgba(201, 162, 75, .22);
  --acc-roseta-op: .16;
  --acc-tarjeta-bg: #FFFDF8;
  --acc-tarjeta-linea: rgba(138, 106, 31, .20);
  --acc-tarjeta-sombra: 0 30px 60px -36px rgba(10, 31, 69, .30), 0 1px 0 rgba(255, 255, 255, .8) inset;
  --acc-campo-bg: #FFFFFF;
  --acc-campo-bg-foco: #FFFFFF;
  --acc-campo-linea: #9A8F7A;
  --acc-campo-linea-hover: #7F7562;
  --acc-anillo: rgba(176, 138, 52, .22);
  --acc-cta-bg: linear-gradient(180deg, #143675 0%, #0A1F45 100%);
  --acc-cta-tinta: #F7F1E3;
  --acc-cta-linea: rgba(201, 162, 75, .75);
  --acc-cta-sombra: inset 0 1px 0 rgba(255, 255, 255, .14), 0 16px 30px -16px rgba(10, 31, 69, .55);
  --acc-fantasma-linea: rgba(138, 106, 31, .55);
  --acc-err-bg: #FCEEEA;
  --acc-err-linea: #EDC2B8;
  --acc-err-tinta: #8E2618;
  --acc-err-tinta-2: #9A2A1C;
  --acc-err-campo: #C2412D;
  --acc-err-anillo: rgba(194, 65, 45, .16);
  --acc-nota-bg: #F8F0DC;
  --acc-nota-linea: #E3CF9C;
  --acc-nota-tinta: #3D3218;
  --acc-mono-bg: rgba(176, 138, 52, .08);
  --acc-sello-bg: rgba(255, 253, 248, .7);
  --acc-azulejo-sombra: 0 10px 24px -14px rgba(10, 31, 69, .45);
  --acc-tema-sol: none;
  --acc-tema-luna: block;
}


/* ═════════════ Base ═════════════
   ⚠️ El fondo va SÓLO en el <html> (.acc), nunca también en el <body>: la capa
   .acc-fondo es fija con z-index -1 y se pinta ENCIMA del fondo del elemento
   raíz pero DEBAJO del de cualquier bloque en flujo. Con fondo en el <body>, el
   degradado desaparecería. */
.acc {
  color-scheme: var(--acc-esquema);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  font-synthesis: none;             /* sin negritas ni itálicas falsas: sólo existe lo que se carga */
  font-kerning: normal;
  font-optical-sizing: auto;        /* Newsreader: tamaño óptico = tamaño en px */
  background: var(--acc-bg);
}
.acc.acc--app { background: var(--acc-bg-app); }
.acc *, .acc *::before, .acc *::after { box-sizing: border-box; margin: 0; padding: 0; }
.acc body {
  min-height: 100vh;
  min-height: 100dvh;
  font-family: var(--acc-sans);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.45;
  font-variant-ligatures: common-ligatures contextual;
  font-variant-numeric: lining-nums proportional-nums;
  color: var(--acc-tinta);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
.acc [hidden] { display: none !important; }
.acc button, .acc a { -webkit-tap-highlight-color: transparent; }
.acc button { font: inherit; color: inherit; }
/* Los campos NO heredan la familia por sí solos. Se les da suelta: el atajo
   `font:` arrastraría también el tamaño (contrato 2). */
.acc input { font-family: inherit; font-weight: inherit; color: inherit; }
.acc ::selection { background: rgba(201, 162, 75, .35); }
/* El icono de Campus va en <picture> (WebP de 9 KB, PNG de respaldo): la caja es la del <img>. */
.acc picture { display: contents; }
.acc .acc-fondo {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0;
  z-index: -1;
  background: var(--acc-fondo-escena);
  pointer-events: none;
}
.acc.acc--app .acc-fondo { background: var(--acc-fondo-escena-app); }
.acc .acc-ico {
  width: 20px; height: 20px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
.acc .acc-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* ═════════════ Escena y columna ═════════════ */
.acc .acc-escena { position: relative; min-height: 100vh; min-height: 100dvh; }
.acc .acc-pantalla {
  position: relative;
  width: 100%;
  max-width: 440px;
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0 auto;
  padding: 0 20px;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  overflow-x: clip;                 /* la roseta no abre scroll lateral a 320 px */
}


/* ═════════════ Barra: idioma + tema ═════════════ */
.acc .acc-barra {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  padding-top: calc(env(safe-area-inset-top, 0px) + 6px);
}
.acc .acc-idioma { display: flex; align-items: center; }
/* ES/EN: la única pieza en mayúsculas de la pantalla (dos CÓDIGOS, no texto).
   Son ENLACES ?lang=… (recargan), no botones: el formulario tiene un solo envío. */
.acc .acc-idioma-op {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; height: 44px;
  padding: 0 .06em 0 .12em;         /* compensa el tracking para centrar */
  border-radius: 10px;
  font-size: var(--acc-fs-ui); font-weight: 600; letter-spacing: .06em;
  color: var(--acc-tinta-3);
  text-decoration: none;
}
.acc .acc-idioma-op[aria-current="true"],
.acc .acc-idioma-op[aria-current="page"] { color: var(--acc-tinta); }
.acc .acc-idioma-op[aria-current="true"]::after,
.acc .acc-idioma-op[aria-current="page"]::after {
  content: '';
  position: absolute; left: 50%; bottom: 8px;
  width: 16px; height: 1px; margin-left: -8px;
  background: var(--acc-acento-linea);
}
.acc .acc-idioma-sep { width: 1px; height: 14px; background: var(--acc-tarjeta-linea); }
.acc .acc-tema {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 0; border-radius: 10px;
  background: none;
  color: var(--acc-tinta-3);
  cursor: pointer;
}
.acc .acc-tema:active { background: var(--acc-mono-bg); }
.acc .acc-tema .acc-tema-sol { display: var(--acc-tema-sol); }
.acc .acc-tema .acc-tema-luna { display: var(--acc-tema-luna); }


/* ═════════════ Marca: sello + nombre + firma (includes/components/acceso_marca.php) ═════════════ */
.acc .acc-marca { position: relative; text-align: center; padding: 4px 0 30px; }
.acc .acc-sello {
  position: relative;
  display: flex; justify-content: center;
  width: -webkit-max-content; width: max-content;
  min-width: 86px; height: 86px;
  margin: 0 auto;
}
.acc .acc-roseta {
  position: absolute; left: 50%; top: 50%;
  width: 270px; height: 270px;
  transform: translate(-50%, -50%);
  color: var(--acc-acento-linea);
  opacity: var(--acc-roseta-op);
  pointer-events: none;
  -webkit-mask-image: radial-gradient(closest-side, #000 52%, transparent 100%);
          mask-image: radial-gradient(closest-side, #000 52%, transparent 100%);
}
.acc .acc-sello::before {
  content: '';
  position: absolute; top: -36px; right: -36px; bottom: -36px; left: -36px;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--acc-halo), transparent);
  pointer-events: none;
}
.acc .acc-azulejo {
  position: relative;
  width: 86px; height: 86px;
  padding: 6px;
  border-radius: 23px;
  border: 1px solid var(--acc-acento-linea);
  background: var(--acc-sello-bg);
}
.acc .acc-azulejo img {
  display: block;
  width: 72px; height: 72px;
  border-radius: 16px;
  box-shadow: 0 14px 30px -10px rgba(0, 0, 0, .7);
}
/* Co-marca: el logo del colegio, entero (contain), sobre marfil en los dos temas. */
.acc .acc-azulejo--marfil {
  background: var(--acc-fijo-azulejo);
  box-shadow: var(--acc-azulejo-sombra);
}
.acc .acc-azulejo--marfil img {
  object-fit: contain;
  border-radius: 10px;
  box-shadow: none;
  background: var(--acc-fijo-azulejo);
}
/* Logo ancho (proporción ≥ 1,6 medida con getimagesize): el azulejo crece a lo
   ancho; la altura no cambia, para que nombre y tarjeta no se muevan. */
.acc .acc-azulejo--ancho { width: auto; min-width: 86px; }
.acc .acc-azulejo--ancho img { width: auto; max-width: 200px; }

.acc .acc-marca-nombre {
  position: relative;
  margin-top: 20px;
  font-family: var(--acc-serif);
  font-weight: 500;
  font-size: var(--acc-fs-marca);
  line-height: .95;
  letter-spacing: -.015em;
  color: var(--acc-tinta);
}
.acc .acc-firma {
  position: relative;
  margin-top: 10px;
  font-family: var(--acc-serif);
  font-style: italic;
  font-weight: 400;
  font-size: var(--acc-fs-firma);
  line-height: 1.2;
  letter-spacing: .005em;
  color: var(--acc-acento);
}
/* En el subdominio del colegio manda SU nombre, en 1-3 líneas equilibradas. */
.acc .acc-marca--colegio .acc-marca-nombre {
  max-width: 360px;
  margin-left: auto; margin-right: auto;
  font-size: clamp(30px, 8.4vw, 40px);
  line-height: 1.05;
  text-wrap: balance;
  overflow-wrap: break-word;
}
.acc .acc-marca--colegio .acc-firma { font-size: 17px; }


/* ═════════════ Tarjeta ═════════════ */
.acc .acc-tarjeta {
  position: relative;
  padding: 28px 22px 24px;
  border-radius: 24px;
  border: 1px solid var(--acc-tarjeta-linea);
  background: var(--acc-tarjeta-bg);
  box-shadow: var(--acc-tarjeta-sombra);
}
.acc .acc-tarjeta::before {        /* luz dorada en el canto superior */
  content: '';
  position: absolute; top: -1px; left: 50%;
  width: 140px; height: 1px; margin-left: -70px;
  background: linear-gradient(90deg, transparent, var(--acc-acento-linea), transparent);
}
.acc .acc-cabecera { text-align: center; margin-bottom: 24px; }
.acc .acc-titulo {
  font-family: var(--acc-serif);
  font-weight: 500;
  font-size: var(--acc-fs-titulo);
  line-height: 1.1;
  letter-spacing: -.008em;
  color: var(--acc-tinta);
  text-wrap: balance;
}
.acc .acc-entradilla {
  margin-top: 8px;
  font-size: var(--acc-fs-cuerpo);
  line-height: 1.4;
  color: var(--acc-tinta-2);
  text-wrap: pretty;
}


/* ═════════════ Avisos ═════════════
   Error por defecto; `--nota` (o la clase `is-note`, cómoda desde JS con
   classList) para lo informativo. El icono es ::before y no un <svg> dentro:
   la app escribe el aviso con textContent, que borraría cualquier hijo. */
.acc .acc-aviso {
  display: flex; gap: 12px; align-items: flex-start;
  margin-bottom: 20px;
  padding: 13px 14px;
  border-radius: 12px;
  border: 1px solid var(--acc-err-linea);
  background: var(--acc-err-bg);
  color: var(--acc-err-tinta);
  font-size: var(--acc-fs-ui);
  line-height: 1.4;
  text-align: left;
  overflow-wrap: break-word;
  animation: acc-cae .24s var(--acc-curva) both;
}
.acc .acc-aviso::before {
  content: '!';
  content: '!' / '';                /* el lector de pantalla no lee el icono */
  flex: none;
  width: 20px; height: 20px;
  margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  border: 1.6px solid currentColor;
  border-radius: 50%;
  font-family: var(--acc-sans);
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
}
.acc .acc-aviso--nota,
.acc .acc-aviso.is-note {
  border-color: var(--acc-nota-linea);
  background: var(--acc-nota-bg);
  color: var(--acc-nota-tinta);
}
.acc .acc-aviso--nota::before,
.acc .acc-aviso.is-note::before {
  content: 'i';
  content: 'i' / '';
  color: var(--acc-acento);
}
.acc .acc-aviso-texto { min-width: 0; text-wrap: pretty; }
.acc .acc-aviso-titulo { display: block; font-weight: 600; }
.acc .acc-aviso-cuerpo { display: block; color: var(--acc-err-tinta-2); }
.acc .acc-aviso--nota .acc-aviso-cuerpo,
.acc .acc-aviso.is-note .acc-aviso-cuerpo { color: inherit; }


/* ═════════════ Campos ═════════════
   ☠️ Aquí NO va font-size (contrato 2): los 16 px están en el <style> en línea
   de cada página. */
.acc .acc-campo + .acc-campo { margin-top: 18px; }
.acc .acc-campo label {
  display: block;
  margin-bottom: 7px;
  font-size: var(--acc-fs-ui);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: .005em;
  color: var(--acc-tinta-2);
  transition: color .2s;
}
.acc .acc-control { position: relative; }
.acc .acc-control .acc-ico-guia {
  position: absolute; left: 16px; top: 50%;
  margin-top: -10px;
  color: var(--acc-tinta-3);
  pointer-events: none;
  transition: color .2s;
}
.acc .acc-control input {
  display: block;
  width: 100%;
  height: 54px;
  padding: 0 16px 0 48px;
  border-radius: 14px;
  border: 1px solid var(--acc-campo-linea);
  background: var(--acc-campo-bg);
  color: var(--acc-tinta);
  caret-color: var(--acc-acento-linea);
  font-family: var(--acc-sans);
  font-weight: 400;
  letter-spacing: 0;
  outline: none;
  -webkit-appearance: none;
          appearance: none;
  transition: border-color .2s, box-shadow .2s, background-color .2s;
}
.acc .acc-control input::placeholder { color: var(--acc-ph); opacity: 1; }
.acc .acc-control input:hover { border-color: var(--acc-campo-linea-hover); }
.acc .acc-control input:focus {
  border-color: var(--acc-acento-linea);
  background: var(--acc-campo-bg-foco);
  box-shadow: 0 0 0 4px var(--acc-anillo);
}
.acc .acc-control input:disabled { opacity: .6; cursor: not-allowed; }
.acc .acc-campo:focus-within label { color: var(--acc-tinta); }
.acc .acc-control:focus-within .acc-ico-guia { color: var(--acc-acento); }
/* Los puntos de la clave OCULTA: en Source Sans 3 miden 3,9 px a 16 px, y una persona
   mayor no los cuenta para saber si tecleó bien (revisión visual, 30-sep-2026). Verdana
   (Windows, macOS, iOS) los da de 5,8 px y Tahoma de 5,5; donde no hay ninguna (Android)
   queda la sans. Sólo la FAMILIA: el tamaño sigue siendo el de la página (contrato 2).
   El texto de ayuda vuelve a la sans; al mostrar la clave, type="text" ya no casa. */
.acc .acc-control input[type="password"] { font-family: Verdana, Tahoma, var(--acc-sans); letter-spacing: .08em; }
.acc .acc-control input[type="password"]::placeholder { font-family: var(--acc-sans); letter-spacing: 0; }
.acc .acc-control--clave input { padding-right: 56px; }

/* Autorrelleno de Android/Chrome: sin el fondo amarillo/azul del sistema.
   Bajo .acc: en el trámite (sin .acc) no pinta un campo marino en una tarjeta blanca. */
.acc .acc-control input:-webkit-autofill,
.acc .acc-control input:-webkit-autofill:hover {
  -webkit-text-fill-color: var(--acc-tinta);
  -webkit-box-shadow: 0 0 0 100px var(--acc-campo-bg) inset;
  transition: background-color 9999s ease-out 0s;
}
.acc .acc-control input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--acc-tinta);
  -webkit-box-shadow: 0 0 0 100px var(--acc-campo-bg-foco) inset, 0 0 0 4px var(--acc-anillo);
}

.acc .acc-campo.is-invalid .acc-control input,
.acc .acc-control input[aria-invalid="true"] { border-color: var(--acc-err-campo); }
.acc .acc-campo.is-invalid .acc-control input:focus,
.acc .acc-control input[aria-invalid="true"]:focus { box-shadow: 0 0 0 4px var(--acc-err-anillo); }
.acc .acc-campo.is-invalid .acc-ico-guia { color: var(--acc-err-campo); }
.acc .is-busy .acc-control { opacity: .72; }

/* Mostrar/ocultar la contraseña: el ojo lo decide aria-pressed, sin JS de iconos. */
.acc .acc-revelar {
  position: absolute; right: 5px; top: 5px;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 0; border-radius: 10px;
  background: none;
  color: var(--acc-tinta-3);
  cursor: pointer;
  transition: color .2s, background-color .2s;
}
.acc .acc-revelar:active { background: var(--acc-mono-bg); }
.acc .acc-revelar[aria-pressed="true"] { color: var(--acc-acento); }
.acc .acc-revelar .acc-ojo-no,
.acc .acc-revelar[aria-pressed="true"] .acc-ojo-si { display: none; }
.acc .acc-revelar[aria-pressed="true"] .acc-ojo-no { display: block; }


/* ═════════════ Enlaces ═════════════ */
.acc .acc-meta { display: flex; justify-content: flex-end; margin: 4px 0 10px; }
/* «¿Olvidaste tu contraseña?» (.acc-meta) va entre los campos y el botón en las DOS pantallas: la
   web y, desde el 3-oct-2026, la app. Si una pantalla lo quita, el botón no se pega al campo:
   medido el 30-sep-2026, sin esta regla quedaban a 0 px. */
.acc .acc-campo + .acc-boton { margin-top: 26px; }
.acc .acc-enlace {
  display: inline-flex; align-items: center;
  min-height: 44px;
  padding: 0 2px;
  border-radius: 6px;
  font-size: var(--acc-fs-ui);
  font-weight: 400;
  color: var(--acc-acento);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  text-decoration-skip-ink: auto;
  text-decoration-color: var(--acc-acento-subrayado);
  transition: text-decoration-color .2s;
}
.acc .acc-enlace:hover,
.acc .acc-enlace:active { text-decoration-color: var(--acc-acento); }


/* ═════════════ Botones ═════════════ */
.acc .acc-boton {
  width: 100%;
  min-height: 56px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 0 16px;
  border-radius: 14px;
  border: 1px solid var(--acc-cta-linea);
  background: var(--acc-cta-bg);
  color: var(--acc-cta-tinta);
  font-size: var(--acc-fs-cuerpo);
  font-weight: 600;
  letter-spacing: .01em;
  cursor: pointer;
  box-shadow: var(--acc-cta-sombra);
  transition: transform .14s var(--acc-curva), filter .2s;
}
.acc .acc-boton .acc-flecha { transition: transform .25s var(--acc-curva); }
.acc .acc-boton:active:not(:disabled) { transform: translateY(1px) scale(.992); filter: brightness(.97); }
.acc .acc-boton:hover:not(:disabled) .acc-flecha,
.acc .acc-boton:active:not(:disabled) .acc-flecha { transform: translateX(3px); }
.acc .acc-boton:disabled { cursor: progress; }
.acc .acc-boton.is-bloqueado { cursor: not-allowed; opacity: .72; filter: saturate(.6); }

.acc .acc-boton-fantasma {
  width: 100%;
  min-height: 48px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin: -4px 0 20px;
  border-radius: 12px;
  border: 1px solid var(--acc-fantasma-linea);
  background: transparent;
  color: var(--acc-tinta);
  font-size: var(--acc-fs-ui);
  font-weight: 600;
  cursor: pointer;
}
.acc .acc-boton-fantasma .acc-ico { width: 18px; height: 18px; color: var(--acc-acento); }
/* El contenido va en UN envoltorio inline-flex: la app muestra «Reintentar» con
   style.display = 'block' (lo fija AppLoginPageConservaTokenTest), y en bloque el icono
   caía a la línea base del texto y perdía el hueco. Medido el 30-sep-2026. */
.acc .acc-boton-fantasma-cuerpo { display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.acc .acc-boton-fantasma:active { background: var(--acc-mono-bg); }

.acc .acc-giro {
  width: 18px; height: 18px;
  flex: none;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-right-color: transparent;
  opacity: .8;
  animation: acc-gira .8s linear infinite;
}

/* «o» + Entrar con Google (blanco estándar en los dos temas). */
.acc .acc-separador {
  display: flex; align-items: center; gap: 12px;
  margin: 20px 0 14px;
  font-size: var(--acc-fs-ui);
  color: var(--acc-tinta-3);
}
.acc .acc-separador::before,
.acc .acc-separador::after { content: ''; flex: 1; height: 1px; background: var(--acc-tarjeta-linea); }
.acc .acc-google {
  width: 100%;
  min-height: 52px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 0 16px;
  border-radius: 14px;
  border: 1px solid var(--acc-fijo-google-linea);
  background: var(--acc-fijo-google-bg);
  color: var(--acc-fijo-google-tinta);
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
}
.acc .acc-google svg { width: 18px; height: 18px; flex: none; }

.acc .acc-boton:focus-visible,
.acc .acc-boton-fantasma:focus-visible,
.acc .acc-google:focus-visible,
.acc .acc-revelar:focus-visible,
.acc .acc-enlace:focus-visible,
.acc .acc-idioma-op:focus-visible,
.acc .acc-tema:focus-visible,
.acc .acc-legal a:focus-visible,
.acc .acc-colegio:focus-visible {
  outline: 2px solid var(--acc-acento-linea);
  outline-offset: 3px;
}


/* ═════════════ Lista de colegios TRAS autenticar (app) ═════════════
   Sale sólo cuando el MISMO correo y clave casan en 2 o más colegios
   (api/auth/app_login.php devuelve multiple). Cada colegio es un <button>:
   teclado y lector de pantalla sin esfuerzo. Textos con textContent. */
.acc .acc-colegios-titulo {
  font-family: var(--acc-serif);
  font-weight: 500;
  font-size: 24px;
  line-height: 1.15;
  text-align: center;
  color: var(--acc-tinta);
}
.acc .acc-colegios-entradilla {
  margin: 6px 0 18px;
  font-size: var(--acc-fs-ui);
  line-height: 1.4;
  text-align: center;
  color: var(--acc-tinta-2);
}
.acc .acc-colegios-lista { display: flex; flex-direction: column; gap: 10px; }
.acc .acc-colegio {
  position: relative;
  width: 100%;
  min-height: 64px;
  padding: 12px 44px 12px 16px;
  display: block;
  text-align: left;
  border-radius: 14px;
  border: 1px solid var(--acc-campo-linea);
  background: var(--acc-campo-bg);
  color: var(--acc-tinta);
  cursor: pointer;
  transition: border-color .2s, background-color .2s;
}
.acc .acc-colegio::after {          /* chevrón › dibujado con bordes (sin emoji) */
  content: '';
  position: absolute; right: 20px; top: 50%;
  width: 8px; height: 8px;
  margin-top: -4px;
  border-top: 1.6px solid var(--acc-acento);
  border-right: 1.6px solid var(--acc-acento);
  transform: rotate(45deg);
}
.acc .acc-colegio:hover { border-color: var(--acc-campo-linea-hover); background: var(--acc-campo-bg-foco); }
.acc .acc-colegio:disabled { cursor: progress; opacity: .72; }
.acc .acc-colegio-nombre {
  display: block;
  font-size: var(--acc-fs-cuerpo);
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: break-word;
}
.acc .acc-colegio-rol {
  display: block;
  margin-top: 2px;
  font-size: var(--acc-fs-ui);
  color: var(--acc-tinta-3);
}


/* ═════════════ Pie ═════════════ */
.acc .acc-pie {
  margin-top: auto;
  padding: 28px 0 calc(22px + env(safe-area-inset-bottom, 0px));
  text-align: center;
  font-size: var(--acc-fs-pie);
  line-height: 1.4;
  color: var(--acc-tinta-3);
}
.acc .acc-cifrada { display: inline-flex; align-items: center; gap: 7px; }
.acc .acc-cifrada .acc-ico { width: 16px; height: 16px; color: var(--acc-acento); }
.acc .acc-legal {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  margin-top: 2px;
}
.acc .acc-legal a {
  display: inline-flex; align-items: center;
  min-height: 44px;
  padding: 0 8px;
  border-radius: 6px;
  color: var(--acc-tinta-2);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--acc-tarjeta-linea);
}
.acc .acc-legal a:hover { text-decoration-color: var(--acc-tinta-2); }
.acc .acc-legal-sep { color: var(--acc-tinta-3); }
.acc .acc-copy { margin-top: 2px; }


/* ═════════════ Panel de FOTOS del colegio — sólo escritorio ═════════════
   Decisión del dueño (29-sep-2026): las fotos se ven SÓLO en escritorio (desde
   900 px de ancho, con ratón: contrato 9), como panel junto a la columna; en el
   teléfono NO, tampoco apaisado, y no se descargan: la página las pone con
   el.style.backgroundImage sólo si matchMedia() da la misma condición.
   Sin fotos (.fallback) no se pinta nada: columna centrada sobre el marino. */
.acc .visual { display: none; }
.acc .slides { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
.acc .slide {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  background-color: var(--acc-fijo-marino);
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 1.2s ease;
}
.acc .slide.on { opacity: 1; }
.acc .acc-fotos-velo {
  position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(var(--acc-velo), 0) 60%, rgba(var(--acc-velo), .5) 100%),
    linear-gradient(0deg, rgba(var(--acc-velo), .6) 0%, rgba(var(--acc-velo), 0) 32%);
}
.acc .acc-puntos { position: absolute; left: 32px; bottom: 28px; display: flex; gap: 8px; }
.acc .acc-puntos span {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: rgba(243, 237, 226, .5);
  transition: background-color .3s, transform .3s;
}
.acc .acc-puntos span.on { background: var(--acc-fijo-oro); transform: scale(1.25); }
.acc .seam {                         /* costura: un filo dorado entre foto y columna */
  position: absolute; top: 0; right: 0; bottom: 0;
  width: 1px;
  background: linear-gradient(180deg, rgba(201, 162, 75, 0), rgba(201, 162, 75, .6) 50%, rgba(201, 162, 75, 0));
}


/* ═════════════ Panel IB — sólo escritorio y sólo SIN fotos ═════════════
   Aprobado por el dueño el 30-sep-2026 (maqueta «Para cada quien»). QUÉ dice lo decide
   includes/components/acceso_panel.php (cada frase, con su módulo encendido); la hoja decide DÓNDE:
   · Fuera de escritorio (contrato 9) NO existe: display:none, ni caja ni lector de pantalla. En el
     teléfono la página es la de siempre, pixel a pixel. Y si esta hoja no llega (datos móviles), lo
     esconde la 2.ª regla del <style> en línea de index.php: sin ella, el teléfono lo pintaba entero.
   · Con fotos tampoco: index.php ni lo pinta, y aquí sólo se enseña tras un .visual.fallback.
   · Va DESPUÉS de .acc-pantalla en el DOM (teclado y lector llegan antes al formulario) y se pinta a
     la izquierda con order:-1. .acc-escena--panel (la pone index.php cuando hay panel) aparta la
     columna a la derecha: el hueco libre se reparte a los dos lados del conjunto.
   · Anclado ARRIBA como la columna, sin sticky: el antetítulo a la altura del nombre de la marca, a
     cualquier alto de ventana. La roseta del sello, a la altura del sello, llena el hueco de arriba a
     la izquierda (detrás del texto: isolation + z-index -1).
   · Tamaños que no le disputan la página a la tarjeta: el titular nunca pasa al nombre de la marca
     (48/36 px Campus, 40/30 px el colegio: 34 px aquí, 28 px en portátil) y la frase de cada bloque
     (20/18 px, --acc-tinta-2) queda por debajo del título de la tarjeta (28/24 px). Lo vigila (j7t) de
     PuertaDeAccesoDecisionesTest, con la cascada de esta hoja en cada vista de escritorio.
   · Tokens --acc-* y la letra de la puerta. Nada en itálica (la itálica cargada es el SUBCONJUNTO de
     la firma: caería a Georgia letra a letra), nada en mayúsculas, nada por debajo de 15 px.
   · Los TRAMOS (.acc-panel-tramo) van en bloque: el corte de línea cae entre tramos y, si uno no cabe
     (el inglés es más largo), se parte por dentro en vez de salirse de la columna. */
.acc .acc-panel { display: none; }

@media (min-width: 900px) and (hover: hover) and (pointer: fine) {
  .acc .visual.fallback ~ .acc-panel {
    --pn-ancho: clamp(372px, 22vw + 152px, 452px);
    --pn-hueco: clamp(52px, 11vw - 52px, 96px);
    --pn-arriba: 172px;               /* el antetítulo, a la altura del nombre de la marca */
    --pn-roseta-x: 44px;              /* centro de la roseta, desde el arranque del texto */
    --pn-roseta-y: -67px;             /* …y a la altura del centro del sello */
    display: block;
    order: -1;
    align-self: flex-start;
    /* Puede ceder: con barras de desplazamiento CLÁSICAS (Windows, 17 px) a 900-904 px el hueco útil
       es 883 px y panel + hueco + columna suman 884 fijos: 1 px de scroll horizontal, que a su vez
       traía uno vertical (medido por la revisión del 30-sep-2026 con Chromium y barras de 17 px; el
       headless las oculta). Cede el panel, no la columna: 391 px en vez de 392, y desde 905 px nada. */
    flex: 0 1 auto;
    min-width: 0;
    width: calc(var(--pn-ancho) + 20px);
    /* 20 px a la izquierda = el relleno de la columna a la derecha de la tarjeta: los dos
       márgenes que SE VEN quedan iguales. */
    padding: var(--pn-arriba) 0 48px 20px;
    margin: 0 var(--pn-hueco) 0 auto;
    color: var(--acc-tinta);
  }
  .acc .acc-escena--panel .visual.fallback ~ .acc-pantalla {
    flex: 0 0 440px;
    margin: 0 auto 0 0;
  }
  .acc .acc-panel-cuerpo { position: relative; isolation: isolate; }
  /* Filete dorado vertical entre el panel y la tarjeta, en mitad del hueco que se ve. */
  .acc .acc-panel-cuerpo::after {
    content: '';
    position: absolute;
    top: 4px; bottom: 4px;
    right: calc((var(--pn-hueco) + 20px) / -2);
    width: 1px;
    background: linear-gradient(180deg, transparent, var(--acc-acento-linea) 20%, var(--acc-acento-linea) 80%, transparent);
    opacity: .45;
  }
  /* La roseta del sello (la misma pieza, el mismo tamaño y la misma opacidad): dentro, .acc-roseta
     se centra sola (left/top 50 % + translate) y la regla de portátil la baja a 200 px. */
  .acc .acc-panel-roseta {
    position: absolute;
    z-index: -1;
    left: calc(var(--pn-roseta-x) - 135px);
    top: calc(var(--pn-roseta-y) - 135px);
    width: 270px; height: 270px;
    pointer-events: none;
  }
  /* En el sello el azulejo tapa el centro; aquí no hay azulejo, y los 24 círculos se cruzan a
     menos de un 10 % del radio: sin vaciarlo, el centro se ve como un punto suelto (medido en la
     primera captura). */
  .acc .acc-panel-roseta .acc-roseta {
    -webkit-mask-image: radial-gradient(closest-side, transparent 14%, #000 34%, #000 52%, transparent 100%);
            mask-image: radial-gradient(closest-side, transparent 14%, #000 34%, #000 52%, transparent 100%);
  }

  .acc .acc-panel-antetitulo {
    display: flex; align-items: center; gap: 12px;
    font-size: var(--acc-fs-ui);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: .01em;
    color: var(--acc-acento);
  }
  .acc .acc-panel-antetitulo::before {
    content: '';
    flex: none;
    width: 28px; height: 1px;
    background: var(--acc-acento-linea);
  }
  .acc .acc-panel-titular {
    margin-top: 18px;
    font-family: var(--acc-serif);
    font-weight: 500;
    font-size: 34px;
    line-height: 1.12;
    letter-spacing: -.014em;
    color: var(--acc-tinta);
  }
  .acc .acc-panel-tramo { display: block; text-wrap: pretty; }

  .acc .acc-panel-roles { list-style: none; margin-top: 36px; }
  .acc .acc-panel-rol {
    padding: 23px 0 24px;
    border-top: 1px solid var(--acc-tarjeta-linea);
  }
  .acc .acc-panel-rol:last-child { border-bottom: 1px solid var(--acc-tarjeta-linea); }
  .acc .acc-panel-quien {
    display: block;
    font-size: var(--acc-fs-ui);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: .01em;
    color: var(--acc-acento);
  }
  .acc .acc-panel-que {
    display: block;
    margin-top: 6px;
    font-family: var(--acc-serif);
    font-weight: 500;
    font-size: 20px;
    line-height: 1.28;
    letter-spacing: -.004em;
    color: var(--acc-tinta-2);
  }
  .acc .acc-panel-pie {
    margin-top: 18px;
    font-size: var(--acc-fs-ui);
    line-height: 1.4;
    color: var(--acc-tinta-3);
    text-wrap: pretty;
  }
}


/* ═════════════ Capa de ARRANQUE (app) ═════════════
   SIEMPRE marino, en los dos temas: continúa el splash nativo #0C1222 mientras
   la app prueba el token guardado. La página la trae VISIBLE y el JS la
   esconde; sus reglas mínimas (pantalla completa + fondo) están también en el
   <style> en línea de la app, para que el autologin no dependa de esta hoja. */
.acc .acc-arranque {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0;
  z-index: 60;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px;
  color-scheme: dark;
  color: var(--acc-fijo-marfil);
  background:
    linear-gradient(180deg, #0C1222 0, rgba(12, 18, 34, 0) 96px),
    radial-gradient(120% 55% at 50% 0%, rgba(33, 72, 140, .55) 0%, rgba(33, 72, 140, 0) 62%),
    var(--acc-fijo-marino);
  transition: opacity .32s ease, visibility .32s;
}
.acc .acc-arranque.is-out { opacity: 0; visibility: hidden; }
.acc .acc-arranque-sello { position: relative; width: 136px; height: 136px; display: grid; place-items: center; }
.acc .acc-arranque-sello svg {
  position: absolute; top: 0; left: 0;
  width: 100%; height: 100%;
  transform-origin: 50% 50%;
}
.acc .acc-arranque-anillo { animation: acc-gira 1.8s linear infinite; }
.acc .acc-arranque-dial { animation: acc-gira 16s linear infinite reverse; }
.acc .acc-arranque-pista { fill: none; stroke: rgba(201, 162, 75, .16); stroke-width: 1.2; }
.acc .acc-arranque-arco {
  fill: none; stroke: var(--acc-fijo-oro); stroke-width: 1.8;
  stroke-linecap: round; stroke-dasharray: 72 330;
}
.acc .acc-arranque-marcas { fill: none; stroke: rgba(201, 162, 75, .45); stroke-width: 1; stroke-dasharray: .8 6.2; }
.acc .acc-arranque-sello img {
  position: relative;
  width: 76px; height: 76px;
  border-radius: 17px;
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, .75);
}
.acc .acc-arranque-titulo {
  margin-top: 28px;
  font-family: var(--acc-serif);
  font-weight: 500;
  font-size: var(--acc-fs-titulo);
  line-height: 1.1;
  letter-spacing: -.008em;
  text-align: center;
}
.acc .acc-arranque-sub {
  margin-top: 8px;
  font-size: var(--acc-fs-ui);
  text-align: center;
  color: var(--acc-fijo-arranque-sub);
}
.acc .acc-arranque-firma {
  position: absolute; left: 0; right: 0;
  bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  text-align: center;
  font-family: var(--acc-serif);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.2;
  color: var(--acc-fijo-arranque-firma);
}
.acc .acc-arranque-marca { font-weight: 500; font-style: normal; color: var(--acc-fijo-arranque-marca); }
.acc .acc-arranque-firma i { font-style: italic; font-weight: 400; }


/* ═════════════ Movimiento ═════════════ */
@keyframes acc-gira { to { transform: rotate(360deg); } }
@keyframes acc-sube { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes acc-cae { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.acc .acc-sube { animation: acc-sube .7s var(--acc-curva) both; }
.acc .acc-d2 { animation-delay: .08s; }
.acc .acc-d3 { animation-delay: .16s; }

/* El interruptor de tema salta sin transiciones (mismo criterio que
   assets/css/style.css): si no, ~300 ms con media paleta de cada tema. */
.acc.theme-switching,
.acc.theme-switching *,
.acc.theme-switching *::before,
.acc.theme-switching *::after { transition: none !important; animation-duration: 0s !important; }

@media (prefers-reduced-motion: reduce) {
  .acc *, .acc *::before, .acc *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  /* Con menos movimiento las fotos no rotan (index.php): cuatro puntos que nunca cambian no dicen nada. */
  .acc .acc-puntos { display: none; }
}


/* ═════════════ Tamaños de pantalla ═════════════ */

/* Pantallas bajas (≤ 700 px de alto): se recorta aire, no contenido. Objetivo
   MEDIDO contra la altura de la VISTA, no del aparato: en la app (WebView a
   pantalla completa) 360×640 deja unos 616 px útiles y el botón acaba en 585; en
   Chrome del mismo teléfono quedan unos 560 (barra de estado + de direcciones) y
   el botón «Ingresar» acaba en 611 en el central y en 628 con «Colegio San Antonio
   de Padua»: ahí queda BAJO el pliegue, como ya pasaba con sap en el diseño de
   antes (29/30-sep-2026). El sello sube junto a ES/EN, que están en otra esquina;
   no si el logo es ANCHO (.acc-marca--ancha: llegaría a su altura) ni, en la web,
   por debajo de 370 px, donde ES/EN + el tema llegan hasta el sello (medido a
   320×568: el subrayado de «ES» tocaba el marco dorado). */
@media (max-height: 700px) {
  .acc .acc-marca { margin-top: -14px; padding-bottom: 18px; }
  .acc .acc-marca.acc-marca--ancha { margin-top: 0; }
  .acc .acc-marca-nombre { margin-top: 12px; font-size: 42px; }
  .acc .acc-marca--colegio .acc-marca-nombre { font-size: clamp(28px, 7.6vw, 36px); }
  .acc .acc-tarjeta { padding-top: 20px; }
  .acc .acc-cabecera { margin-bottom: 18px; }
  .acc .acc-campo + .acc-campo { margin-top: 14px; }
  .acc .acc-meta { margin: 2px 0 6px; }
  /* La app con «¿Olvidaste tu contraseña?» (3-oct-2026): a 360×616 —la vista de 360×640 menos la
     barra de estado— el botón acababa a 3 px del borde (612,8). Sin el aire de fuera, que la caja de
     44 px del enlace ya deja alrededor del texto, acaba en 605 (sin el enlace, 585). */
  .acc.acc--app .acc-meta { margin: 0 0 2px; }
}
@media (max-width: 370px) and (max-height: 700px) {
  .acc:not(.acc--app) .acc-marca { margin-top: 0; }
}

/* Teléfonos estrechos (≤ 370 px). */
@media (max-width: 370px) {
  .acc { --acc-fs-titulo: 26px; }
  .acc .acc-pantalla { padding: 0 16px; }
  .acc .acc-tarjeta { padding-left: 20px; padding-right: 20px; }
}

/* Escritorio (contrato 9): con fotos, panel a la izquierda y la columna a la
   derecha; sin fotos, la columna centrada sobre el fondo, o —si el colegio tiene
   algún pilar del Diploma— con el panel IB a su izquierda (su sección, arriba). */
@media (min-width: 900px) and (hover: hover) and (pointer: fine) {
  .acc .acc-escena { display: flex; align-items: flex-start; }
  .acc .visual:not(.fallback) {
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    display: block;
    flex: 1 1 auto;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
    background: var(--acc-fijo-marino);
  }
  .acc .visual:not(.fallback) ~ .acc-pantalla {
    flex: 0 0 auto;
    width: 540px;
    max-width: none;
    margin: 0;
    padding: 0 50px;
  }
  .acc .acc-marca { padding-top: 12px; }
}

/* Portátiles (≤ 820 px de alto: 1366×768 y 1280×800 con la barra del navegador
   dejan 580-700 px). Con el sello de 86 px, el nombre del colegio en dos líneas
   de 36 px y la firma, la tarjeta empezaba a 270 px: a 1366×625 «Ingresar» quedaba
   CORTADO con sap y «Entrar con Google» fuera de la pantalla (revisión visual,
   30-sep-2026). Aquí hay ratón: los objetivos pueden bajar de 44 px. Medido tras
   el cambio (botón / Google, fondo en px): 1366×625 central 493, sap 489/575;
   1280×580 sap 489/575. Sigue sin caber Google con un nombre de 63 caracteres a
   1366×625 (638): el botón sí. */
@media (min-width: 900px) and (max-height: 820px) and (hover: hover) and (pointer: fine) {
  .acc { --acc-fs-titulo: 24px; }
  .acc .acc-barra { padding-top: 4px; }
  .acc .acc-idioma-op, .acc .acc-tema { height: 36px; }
  .acc .acc-marca { margin-top: -16px; padding-top: 0; padding-bottom: 12px; }
  .acc .acc-marca.acc-marca--ancha { margin-top: 0; }
  .acc .acc-sello { min-width: 64px; height: 64px; }
  .acc .acc-roseta { width: 200px; height: 200px; }
  .acc .acc-azulejo { width: 64px; height: 64px; padding: 5px; border-radius: 18px; }
  .acc .acc-azulejo img { width: 52px; height: 52px; border-radius: 12px; }
  .acc .acc-azulejo--ancho { width: auto; }
  .acc .acc-azulejo--ancho img { width: auto; max-width: 160px; }
  .acc .acc-marca-nombre { margin-top: 10px; font-size: 36px; }
  .acc .acc-marca--colegio .acc-marca-nombre { max-width: none; font-size: 30px; }
  .acc .acc-firma { margin-top: 4px; font-size: 17px; }
  .acc .acc-marca--colegio .acc-firma { font-size: 16px; }
  .acc .acc-tarjeta { padding-top: 18px; padding-bottom: 18px; }
  .acc .acc-cabecera { margin-bottom: 12px; }
  .acc .acc-entradilla { margin-top: 4px; }
  .acc .acc-campo + .acc-campo { margin-top: 12px; }
  .acc .acc-campo label { margin-bottom: 5px; }
  .acc .acc-control input { height: 46px; }
  .acc .acc-meta { margin: 0 0 4px; }
  .acc .acc-enlace { min-height: 34px; }
  .acc .acc-boton { min-height: 48px; }
  .acc .acc-separador { margin: 10px 0 8px; }
  .acc .acc-google { min-height: 46px; }
  /* El panel IB (su sección, tras el panel de fotos) se compacta con la columna: antetítulo a la altura
     del nombre (30/36 px), titular de 28 px —nunca por encima del nombre del colegio— y la roseta, a la
     del sello de 64 px. */
  .acc .visual.fallback ~ .acc-panel { --pn-arriba: 100px; --pn-roseta-y: -44px; }
  .acc .acc-panel-titular { margin-top: 14px; font-size: 28px; }
  .acc .acc-panel-roles { margin-top: 24px; }
  .acc .acc-panel-rol { padding: 15px 0 16px; }
  .acc .acc-panel-que { margin-top: 4px; font-size: 18px; }
  .acc .acc-panel-pie { margin-top: 14px; }
}
