/* ==========================================================================
   Socorrista Urbano — capa de marca sobre Modernist
   --------------------------------------------------------------------------
   Se carga DESPUÉS de `modernist.css` y le gana, porque su capa está declarada
   segunda en `@layer modernist, socorrista;` (arriba de todo en modernist.css).

   Acá va todo lo que es propio de este proyecto y NO debería volver al sistema
   genérico:
     1. El rojo de marca #DC2626 y su rampa completa.
     2. Los dos tokens de estado del campus (verde y ámbar).
     3. El interruptor de color de las fotos.
     4. Primitivas de maquetación + la capa responsive / mobile-first.

   Igual que en modernist.css, TODA regla que pinte algo va detrás del
   interruptor `:where([data-modernist])`. Sólo los tokens (`:root`) quedan
   sueltos, porque una variable que nadie usa no puede alterar una pantalla.

   Ver CLAUDE.md secciones 13.6, 13.7 y 13.9.
   ========================================================================== */

@layer socorrista {

/* ══════════════════════════════════════════════════════════════════════════
   1. EL ROJO DE MARCA — #DC2626
   --------------------------------------------------------------------------
   Modernist viene con #ec3013 (más anaranjado). El rojo de Socorrista Urbano
   es #DC2626, que además es exactamente el rojo del isotipo del logo, así que
   no hay que regenerar el logo.

   La rampa 100–900 NO está elegida a ojo: se generó en OKLCH manteniendo la
   MISMA escala de luminosidad que usan los neutros de Modernist (0.970 / 0.930
   / 0.870 / 0.780 / 0.680 / 0.580 / 0.481 / 0.378 / 0.291), con el tono de
   #DC2626 (H=27.3°) y el perfil de croma del sistema reescalado. Por eso el
   escalón 500 del rojo pesa visualmente lo mismo que el 500 de los neutros.

   Contrastes verificados sobre el fondo #f3f2f2:
     #DC2626 ......... 4.32:1  → alcanza para íconos, títulos y fondo de botón
     accent-700 ...... 6.40:1  → éste es el que se usa para texto de párrafo
     accent-800 ...... 9.59:1
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --color-accent: #DC2626;

  --color-accent-100: #fff2f0;
  --color-accent-200: #fee0dc;
  --color-accent-300: #fec4bc;
  --color-accent-400: #fc978c;
  --color-accent-500: #fb594f;
  --color-accent-600: #d9302d;
  --color-accent-700: #ab1e1d;
  --color-accent-800: #7a1714;
  --color-accent-900: #4c1814;

  /* Hover y pulsado del botón primario.
     ¿Por qué no salen de la rampa? Porque #DC2626 cae JUSTO en el escalón 600
     (luminosidad 0.577 contra 0.580). Usar accent-600 como hover daría 1.01:1
     contra el propio botón: literalmente el mismo color, hover invisible.
     Estos dos valores son los que la marca ya tenía documentados desde antes
     del rebrand (red-700 y red-800) y están en el mismo tono (H=27.5° y 26.9°,
     contra 27.3° del acento), así que la familia cierra.
       hover  #B91C1C → 1.34:1 contra el botón (se nota)
       activo #991B1B → 1.72:1 contra el botón */
  --color-accent-hover: #B91C1C;
  --color-accent-active: #991B1B;

  /* Color del texto SOBRE el acento pleno (botón primario, badges rojos).
     Modernist usa `--color-bg` para esto, que es el blanco roto del fondo
     (#f3f2f2). Con nuestro rojo eso da 4,32:1 — justo por debajo del 4,5:1
     que pide un texto normal. El blanco puro da 4,83:1 y pasa.
     A ojo son indistinguibles sobre rojo; el cambio se nota sólo al medirlo.
     Así no hay que tocar el rojo de marca, que es lo que no se negocia. */
  --color-on-accent: #ffffff;

  /* ── Los dos tonos de texto secundario ──────────────────────────────────
     Antes cada pantalla se inventaba su propia mezcla (60%, 65%, 75%, 78%…) y
     varias quedaban por debajo del contraste mínimo sin que se notara.

     El umbral está calculado, no elegido a ojo: sobre el fondo #f3f2f2, el
     texto #201e1d necesita al menos **62,3% de opacidad** para llegar a 4,5:1.
     Todo lo que esté por debajo de eso NO se puede usar para texto, por chico
     o secundario que sea — WCAG no hace excepciones por importancia.

       --color-text-muted  78% → 7,4:1   texto de apoyo, párrafos secundarios
       --color-text-faint  68% → 5,4:1   etiquetas chicas, metadatos

     Si hace falta un tercer nivel más tenue, NO se baja la opacidad: se cambia
     el tamaño o el peso. */
  --color-text-muted: color-mix(in srgb, var(--color-text) 78%, transparent);
  --color-text-faint: color-mix(in srgb, var(--color-text) 68%, transparent);

  /* La marca no usa un segundo acento. Se apunta al mismo rojo para que, si
     alguna clase heredada de Modernist lo referencia, no aparezca un naranja
     suelto que nadie decidió. */
  --color-accent-2: var(--color-accent);
  --color-accent-2-100: var(--color-accent-100);
  --color-accent-2-200: var(--color-accent-200);
  --color-accent-2-300: var(--color-accent-300);
  --color-accent-2-400: var(--color-accent-400);
  --color-accent-2-500: var(--color-accent-500);
  --color-accent-2-600: var(--color-accent-600);
  --color-accent-2-700: var(--color-accent-700);
  --color-accent-2-800: var(--color-accent-800);
  --color-accent-2-900: var(--color-accent-900);
}

/* ── Links del proyecto ────────────────────────────────────────────────────
   El boceto de la landing traía esta regla, y era la que rompía el botón
   primario: al no excluir a los botones, en hover les pintaba el texto de rojo
   sobre el fondo rojo y encima los subrayaba (CLAUDE.md 13.6b).

   Acá está corregida en el origen, que es donde corresponde: `:not(.btn)` deja
   afuera a cualquier botón, sea <a> o <button>. Como la regla ya vive en el
   sistema, NINGUNA pantalla necesita escribir su propia regla de links — y esa
   es la mejor garantía de que el bug no vuelva.

   >>> SI ALGUNA PANTALLA NECESITA UN ESTILO DE LINK PROPIO, QUE LO ESCRIBA
   SIEMPRE CON `a:not(.btn)`. Un `a:hover` genérico y suelto vuelve a romper
   todos los botones del proyecto. <<<

   El color es accent-700 (6.40:1 sobre el fondo), no el acento pleno: un link
   es texto de párrafo y necesita 4.5:1. */
:where([data-modernist]) a:not(.btn) { color: var(--color-accent-700); text-decoration: none; }
:where([data-modernist]) a:not(.btn):hover { color: var(--color-accent); text-decoration: underline; }

/* Texto de los botones sobre acento pleno — ver `--color-on-accent` arriba.
   Va en esta capa (socorrista) y no en modernist, porque es consecuencia de
   NUESTRO rojo, no un defecto del sistema. La capa socorrista está declarada
   después, así que le gana a las reglas del sistema sin pelear especificidad. */
:where([data-modernist]) .btn-primary,
:where([data-modernist]) a.btn-primary,
:where([data-modernist]) a.btn-primary:hover,
:where([data-modernist]) a.btn-primary:visited { color: var(--color-on-accent); }

/* El botón invertido es al revés: acento sobre claro. Modernist le pone el
   acento pleno, que a 14px da 4,32:1. Va el tono 700 (6,40:1), que es la misma
   regla de siempre: acento pleno para fondos, tono profundo para texto. */
:where([data-modernist]) .btn-inverse,
:where([data-modernist]) a.btn-inverse,
:where([data-modernist]) a.btn-inverse:hover,
:where([data-modernist]) a.btn-inverse:visited { color: var(--color-accent-700); }

/* ══════════════════════════════════════════════════════════════════════════
   2. TOKENS DE ESTADO — SÓLO PARA EL CAMPUS
   --------------------------------------------------------------------------
   Modernist es monocromo a propósito: un acento y grises. Eso rinde en la
   landing, que es marca pura. Pero el campus usa color para INFORMAR
   (Aprobado / Pendiente / Vencido), y sin eso se pierde la lectura de un
   vistazo — y peor: el rojo pasaría a significar "Aprobado" y "Revocar" al
   mismo tiempo, dejando las acciones destructivas sin distintivo visual.

   Por eso se extiende el sistema con EXACTAMENTE DOS colores, generados en la
   misma escala de luminosidad OKLCH que el resto (verde H=150°, ámbar H=62°),
   para que un badge verde y uno rojo pesen igual en la pantalla.

   >>> REGLA DURA: verde y ámbar son DOS TOKENS DE ESTADO, no dos colores
   disponibles. Si aparece la tentación de usarlos para un gráfico, un
   encabezado o un botón, la respuesta es no. <<<

   Para "peligro" (Revocar, Eliminar) se usa el acento rojo de la marca.
   Para "bloqueado / vencido" se usan los neutros de Modernist — no hace falta
   ningún token nuevo.

   Contrastes verificados sobre #f3f2f2:
     ok-700   #017232 → 5.44:1   |  blanco sobre ok-700   → 6.08:1
     warn-700 #894d00 → 6.01:1   |  blanco sobre warn-700 → 6.72:1
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Verde — "Aprobado", "Confirmado", "Completada" */
  --color-ok-100: #f0f7f1;
  --color-ok-200: #dceddf;
  --color-ok-300: #bddfc2;
  --color-ok-400: #8ac996;
  --color-ok-500: #3eb261;
  --color-ok-600: #019342;
  --color-ok-700: #017232;
  --color-ok-800: #005021;
  --color-ok-900: #10341a;
  --color-ok: var(--color-ok-700);

  /* Ámbar — "Pendiente", "Por vencer", "En revisión" */
  --color-warn-100: #fbf4ed;
  --color-warn-200: #f7e4d5;
  --color-warn-300: #f0cdaf;
  --color-warn-400: #e7a870;
  --color-warn-500: #db7e00;
  --color-warn-600: #b16501;
  --color-warn-700: #894d00;
  --color-warn-800: #623500;
  --color-warn-900: #432300;
  --color-warn: var(--color-warn-700);
}

/* ══════════════════════════════════════════════════════════════════════════
   3. INTERRUPTOR DE COLOR DE LAS FOTOS
   --------------------------------------------------------------------------
   Modernist manda que toda foto de contenido vaya en blanco y negro. Acá NO se
   adopta: las fotos van a color en todo el proyecto (CLAUDE.md 13.9). La
   academia vende tranquilidad y capacidad, no dramatismo — el blanco y negro
   documental en este rubro empuja la lectura hacia "noticia y tragedia".

   La clase se mantiene, en cero, para que el proyecto entero tenga UN SOLO
   interruptor: cambiar ese 0 por un 1 acá pone todas las fotos en blanco y
   negro al instante, y al revés. `filter` actúa al mostrar la imagen; el
   archivo original en Storage nunca se modifica.

   Valores: 0 = color pleno, 0.5 = colores a media intensidad, 1 = B/N total.
   ══════════════════════════════════════════════════════════════════════════ */

:where([data-modernist]) .grayscale { filter: grayscale(0) contrast(1.08); }

/* ══════════════════════════════════════════════════════════════════════════
   4. MAQUETACIÓN Y CAPA RESPONSIVE
   --------------------------------------------------------------------------
   Modernist, tal como está publicado, NO tiene ni una media query: es un
   sistema pensado para escritorio (grillas fijas de 3 columnas, contenedor de
   1280px, h1 clavado en 42px). Este proyecto es mobile-first — la mayoría de
   los alumnos entra desde el celular —, así que la capa responsive se
   construye acá.

   Escrito mobile-first: lo que está afuera de toda media query es lo que ve un
   celular; las media queries sólo AGREGAN a medida que hay más ancho.
   Cortes: 768px (tablet) y 1024px (escritorio), los mismos que ya usaba el
   proyecto antes del rebrand.

   Las reglas duras de Modernist sobreviven intactas en pantalla chica: cero
   redondeo, divisorias de 2px, todo alineado a la izquierda.
   ══════════════════════════════════════════════════════════════════════════ */

/* — tipografía fluida —
   clamp(mínimo, ideal, máximo): el navegador elige el valor del medio, pero
   nunca baja del primero ni sube del segundo. Así el título no se desborda a
   360px de ancho y tampoco se agranda de más en un monitor grande. El máximo
   de cada uno es exactamente el tamaño fijo que define Modernist. */
:where([data-modernist]) h1 { font-size: clamp(30px, 7.5vw, 42px); }
:where([data-modernist]) h2 { font-size: clamp(24px, 5.5vw, 32px); }
:where([data-modernist]) h3 { font-size: clamp(20px, 4.2vw, 25px); }
:where([data-modernist]) h4 { font-size: clamp(17px, 3.2vw, 20px); }

/* Evita que una palabra larga (un email, una URL) fuerce scroll horizontal. */
:where([data-modernist]) :is(h1, h2, h3, h4, h5, h6) { overflow-wrap: break-word; text-wrap: balance; }
:where([data-modernist]) :is(p, li, dd) { overflow-wrap: break-word; }

/* — contenedor —
   Ancho máximo de Modernist (1280px) con aire lateral que crece con la
   pantalla. En el celular el aire es chico para no comerse el ancho útil. */
:where([data-modernist]) .container {
  width: 100%;
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: var(--space-4);
}
/* Para textos largos de leer (términos, privacidad, descripciones). */
:where([data-modernist]) .container-narrow {
  width: 100%;
  max-width: 720px;
  margin-inline: auto;
  padding-inline: var(--space-4);
}

/* — secciones —
   Aire vertical fluido y la divisoria de 2px que exige el sistema. */
:where([data-modernist]) .section { padding-block: clamp(32px, 7vw, 72px); }
:where([data-modernist]) .section + .section { border-top: 2px solid var(--color-divider); }
:where([data-modernist]) .section-tight { padding-block: clamp(20px, 4vw, 40px); }
/* Fondo alterno, para separar sin agregar más líneas. */
:where([data-modernist]) .section-alt { background: var(--color-surface); }

/* — grillas —
   Base: UNA columna (celular). Las media queries de más abajo las abren. */
:where([data-modernist]) .grid,
:where([data-modernist]) .grid-2,
:where([data-modernist]) .grid-3,
:where([data-modernist]) .grid-4 { display: grid; gap: var(--space-4); grid-template-columns: 1fr; }

/* Partición asimétrica del hero (1.05fr / 0.95fr en escritorio). Apilada en
   celular, con la imagen debajo del texto. */
:where([data-modernist]) .split { display: grid; gap: var(--space-6); grid-template-columns: 1fr; }

/* — fila que se acomoda sola —
   Botones o etiquetas en línea que bajan de renglón solos si no entran. */
:where([data-modernist]) .cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
/* — pila vertical — */
:where([data-modernist]) .stack { display: flex; flex-direction: column; gap: var(--space-3); }
:where([data-modernist]) .stack-tight { display: flex; flex-direction: column; gap: var(--space-2); }

/* — tablas en pantalla chica —
   Una tabla ancha no se puede reacomodar sin romperla. Se le da su propio
   scroll horizontal para que NUNCA sea la página la que se desplace de lado.
   Envolver así: <div class="table-wrap"><table class="table">…</table></div> */
:where([data-modernist]) .table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* — imágenes y medios embebidos —
   Ningún elemento puede empujar el ancho de la página. */
:where([data-modernist]) :is(img, svg, video, canvas, iframe) { max-width: 100%; }
/* Video responsive sin trucos de padding: <div class="ratio-16x9"><iframe …> */
:where([data-modernist]) .ratio-16x9 { position: relative; width: 100%; aspect-ratio: 16 / 9; }
:where([data-modernist]) .ratio-16x9 > * { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* — botones en celular —
   En pantalla táctil el objetivo mínimo cómodo es ~44px de alto. En escritorio
   se deja el tamaño compacto original de Modernist. */
@media (pointer: coarse) {
  :where([data-modernist]) .btn { min-height: 44px; }
  :where([data-modernist]) .btn-icon { width: 44px; height: 44px; }
}
/* Varios botones apilados a todo el ancho en el celular, con el texto a la
   izquierda como manda el sistema. En tablet vuelven a la fila. */
:where([data-modernist]) .btn-stack { display: flex; flex-direction: column; gap: var(--space-2); align-items: stretch; }
:where([data-modernist]) .btn-stack > .btn { width: 100%; justify-content: flex-start; text-align: left; }

/* ── .hidden — mostrar y esconder desde JavaScript ──────────────────────────
   >>> ESTA CLASE NO ES DECORATIVA: SI FALTA, SE ROMPEN PANTALLAS ENTERAS <<<

   Todo el JavaScript del proyecto muestra y esconde bloques con
   `classList.toggle("hidden", …)`. Esa clase venía de Tailwind en la parte
   pública, y de `admin.css` / `alumno.css` en el campus. Al migrar una
   pantalla se le saca su hoja vieja — y con ella desaparecía `.hidden`,
   dejando visibles al mismo tiempo TODAS las pantallas que deberían estar
   escondidas (el checkout, las confirmaciones de pago, los formularios).

   Pasó de verdad en la etapa 3, en `curso-detalle.html`. Y el campus la usa
   176 veces, así que le tocaría lo mismo en las etapas 4 y 5.

   Viviendo acá, cualquier pantalla que se migre la tiene desde el momento en
   que le ponés `data-modernist`, sin acordarse de nada. */
:where([data-modernist]) .hidden { display: none !important; }

/* — accesibilidad — */
/* Texto sólo para lectores de pantalla. */
:where([data-modernist]) .sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Respeta a quien pidió menos movimiento en su sistema operativo. */
@media (prefers-reduced-motion: reduce) {
  :where([data-modernist]) *,
  :where([data-modernist]) *::before,
  :where([data-modernist]) *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─────────────────────────── TABLET — desde 768px ─────────────────────── */
@media (min-width: 768px) {
  :where([data-modernist]) .container,
  :where([data-modernist]) .container-narrow { padding-inline: var(--space-6); }

  :where([data-modernist]) .grid-2 { grid-template-columns: repeat(2, 1fr); }
  :where([data-modernist]) .grid-3 { grid-template-columns: repeat(2, 1fr); }
  :where([data-modernist]) .grid-4 { grid-template-columns: repeat(2, 1fr); }

  :where([data-modernist]) .split { grid-template-columns: 1.05fr 0.95fr; gap: var(--space-8); align-items: center; }

  /* Ya hay ancho: los botones apilados vuelven a la fila. */
  :where([data-modernist]) .btn-stack { flex-direction: row; align-items: center; }
  :where([data-modernist]) .btn-stack > .btn { width: auto; justify-content: center; text-align: center; }
}

/* ────────────────────────── ESCRITORIO — desde 1024px ─────────────────── */
@media (min-width: 1024px) {
  :where([data-modernist]) .container,
  :where([data-modernist]) .container-narrow { padding-inline: var(--space-8); }

  :where([data-modernist]) .grid-3 { grid-template-columns: repeat(3, 1fr); }
  :where([data-modernist]) .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

} /* fin @layer socorrista */
