/*
 * AFA Escola El Cim — la maqueta comuna del portal.
 *
 * La cargan las TRES páginas del carnet: la shell de la PWA, /registre y
 * /codis. Aquí vive todo lo que comparten —enlace de salto, cabecera, barra
 * lateral, armazón y los bloques del resumen— y por eso `.capcalera` ya no
 * está definida ni en `app.css` ni en `registre.css`: estaba en las dos, con
 * reglas parecidas y no iguales, que es la trampa que el propio proyecto tiene
 * nombrada.
 *
 * NO SE DEFINE NI UN COLOR SUELTO: todo sale de /shared/css/tokens.css. Y no
 * hay ninguna franja de color a la izquierda de ninguna caja — el estado se
 * marca con el triángulo del logotipo y con marcas circulares, y el color
 * nunca es la única señal.
 *
 * DOS SALTOS, UN SOLO CAMBIO DE NAVEGACIÓN:
 *   < 48rem    compacte  una columna, tarjetas 1-up
 *   48–64rem   mitjà     una columna más ancha, tarjetas 2-up
 *   >= 64rem   ample     barra lateral + contenido
 * Solo el de 64rem toca la NAVEGACIÓN. El de 48rem cambia la rejilla y nada
 * más, así que hay tres maquetas y un solo cambio que probar.
 *
 * Ese 64rem está también en `Disseny::TALL_AMPLE` y en `AFA.AMPLE` de
 * `app.js`. Son tres lenguajes y no hay forma de compartir la constante: lo
 * que hay es este aviso en los tres sitios.
 *
 * EL MÓVIL NO PUEDE EMPEORAR. A 375x812 la tarjeta del carnet cabe justa y sin
 * scroll, así que en compacto este fichero no añade ni un píxel de relleno:
 * `.marc` y `.contingut` valen cero hasta 48rem y el relleno lo siguen
 * poniendo `.carnet`, `.llista` y `.avisos`, como hasta ahora.
 */

/* ── Base común de las tres páginas ───────────────────────────────────────
 *
 * Estaba escrita dos veces, en app.css y en registre.css, con una diferencia
 * real escondida dentro: el cuerpo de texto era `mida-m` en una y `mida-s` en
 * la otra. Ahora la base es esta y lo que de verdad se diferencia se dice
 * donde se diferencia, en vez de copiarse entero para cambiar una línea.
 */
* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
  font-family: var(--afa-font);
  font-size: var(--afa-mida-m);
  background: var(--afa-fons);
  color: var(--afa-text);
  -webkit-text-size-adjust: 100%;
}

/* ── Escala tipográfica del portal ────────────────────────────────────────
 *
 * La escala de `tokens.css` se diseñó para una tarjeta de móvil, y a 1.184 px
 * de ancho le faltan dos pasos por arriba: un título de página a 30 px es lo
 * mismo que un título de tarjeta. Estos pasos son LOCALES del portal —no van
 * a tokens.css— porque solo tienen sentido donde hay sitio, y son fluidos
 * para no necesitar un tercer punto de corte.
 */
:root {
  --portal-titol:    clamp(1.5rem, 1.15rem + 1.4vw, 2.125rem);
  --portal-subtitol: clamp(1.0625rem, 1rem + .3vw, 1.1875rem);
  /*
   * El dato que responde a la pregunta que trae aquí a la familia
   * («¿estamos al día?»). Estaba en --afa-mida-l, que es el mismo cuerpo que
   * el título de la tarjeta: en una columna de 900 px eso no es un
   * protagonista, es una fila más. Sube hasta 26 px y solo donde hay sitio.
   */
  --portal-destacat: clamp(1.375rem, 1.1rem + 1.1vw, 1.625rem);
  /*
   * El codi de descompte del resumen. Aquí SÍ va en grande, y no contradice
   * la decisión de que en la tarjeta sea «una fila más»: aquella es sobre la
   * tarjeta, cuya cohesión manda. En escritorio hay un contexto que en el
   * móvil no existe —la compra en línea se hace con un teclado delante— y el
   * código está hecho para pegarlo en un campo de cupón.
   */
  --portal-codi:     clamp(1.375rem, 1.05rem + 1.3vw, 1.75rem);

  /* ── DENSIDAD: tres ritmos y una regla, no una variable uniforme ───────
   *
   * La versión anterior tenía un solo `--portal-ritme` puesto a ojo y con el
   * mismo valor en todas partes, y eso es lo que hace que un panel se lea
   * como una lista de cajas en vez de como una jerarquía. La regla que
   * decide cuál se aplica es esta, y está escrita para no volver a
   * calibrarla a ojo:
   *
   *   RESPIRA lo que responde a una pregunta. SE APRIETA lo que es una lista.
   *
   * - `--portal-ritme`  separa BLOQUES entre sí. Fluido: a 768 px dos cajas
   *   a 2 rem de distancia dejan la columna medio vacía, y a 1.440 px a
   *   1,5 rem se tocan. Crece con el ancho porque el problema crece con el
   *   ancho.
   * - `--portal-aire`   es el relleno de un bloque normal.
   * - `--portal-aire-destacat` es el del bloque protagonista, y es mayor a
   *   propósito: el estado de la familia destaca por el sitio que se le deja
   *   alrededor, no por gritar más fuerte. Es la directriz de NN/g que dice
   *   que quitar adorno alrededor del dato crítico lo destaca más que
   *   añadirle énfasis.
   */
  --portal-ritme:          clamp(1.25rem, .9rem + 1vw, 2rem);
  --portal-aire:           var(--afa-espai-5);
  --portal-aire-destacat:  var(--afa-espai-6);
}

/* ── Enlace de salto ──────────────────────────────────────────────────────
 *
 * Primer elemento tabulable de la página, invisible hasta que recibe el foco.
 * Con una barra lateral persistente esto es obligatorio, no cortesía: WCAG
 * 2.4.1 (nivel A) exige poder saltar los bloques repetidos.
 *
 * `left: -9999px` y no `display:none`: lo segundo lo saca del orden de
 * tabulación y entonces no existe para nadie.
 */
.salta {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--afa-primari);
  color: var(--afa-primari-text);
  font-weight: var(--afa-pes-fort);
  padding: var(--afa-espai-3) var(--afa-espai-4);
  border-radius: 0 0 var(--afa-radi-s) 0;
}
.salta:focus { left: 0; }
/*
 * Y con su cerco, que no es adorno: el enlace es azul y aparece ENCIMA de la
 * cabecera, que también es azul, así que sin cerco lo único que lo separa
 * del fondo es el redondeo de una esquina. WCAG 2.4.7 es AA, no A. El mismo
 * cerco naranja que el resto de elementos con foco del proyecto.
 *
 * Se comprobó con un Tab de verdad el 10 de septiembre —era lo que quedaba
 * pendiente del §15.6 del documento del portal, donde no se había podido ver
 * porque la ventana del navegador no tenía el foco del sistema—: el enlace
 * es el primer elemento tabulable, aparece en 0,0 y mide 181x47.
 */
.salta:focus-visible { outline: 3px solid var(--afa-accent); outline-offset: -3px; }

/*
 * WCAG 2.4.11 (AA): un elemento con el foco no puede quedar completamente
 * tapado por contenido del autor. Con cabecera y barra pegajosas eso pasa al
 * saltar a un ancla, y se arregla con margen de desplazamiento.
 */
:where(a, button, input, select, summary, [tabindex]) {
  scroll-margin-top: var(--afa-espai-6);
}

/* ── La cabecera, UNA sola vez ────────────────────────────────────────────
 *
 * Estaba en app.css (línea 216) y otra vez en registre.css (línea 16). Ahora
 * está aquí y en ningún otro sitio; hay una prueba en bin/proves/carnet.php
 * que lo comprueba, porque una regla sin comprobación automática se cumple
 * donde alguien se acordó.
 */
.capcalera {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--afa-espai-3);
  padding: var(--afa-espai-3) var(--afa-espai-4);
  background: var(--afa-primari);
  color: var(--afa-primari-text);
  /*
   * EL FILETE NARANJA, y es la misma pieza que la tarjeta.
   *
   * En la credencial hay una regla naranja de 2 px justo debajo del
   * logotipo, separando la marca del contenido. La cabecera del portal ES
   * esa banda de marca, así que lleva la misma regla en el mismo sitio.
   *
   * Va en `box-shadow: inset` y no en `border-bottom` por una razón medida:
   * un borde suma 2 px a la altura de la cabecera, y en el móvil la tarjeta
   * cabe JUSTA en 812 px — dos píxeles ahí son una regresión, no un detalle.
   * Con la sombra interior el filete se dibuja dentro y la cabecera sigue
   * midiendo exactamente 70 px.
   */
  box-shadow: inset 0 -2px 0 var(--afa-accent);
}

/*
 * EL LOGOTIPO, en la cabecera y en la tarjeta: una definición, dos tamaños.
 *
 * Antes esto era un `<span>` con el nombre de la asociación en negrita
 * pequeña, y en /registre y /codis ni siquiera eso: llevaba el título de la
 * página. O sea que la única pieza del proyecto con identidad —el logotipo—
 * no aparecía en ninguna de las tres páginas del portal, y la marca del
 * producto se reducía a una franja azul con texto.
 *
 * `.marca` vive ahora en este fichero (venía de app.css) y la cabecera usa
 * `.marca--mini`, que es la misma composición a escala de barra: el
 * triángulo, el nombre del centro y AFA separados por el mismo filete
 * vertical. Lo que se cae en mini es «escola», que a este cuerpo serían
 * 7 px con .38em de espaciado — ilegible, y un texto ilegible no informa,
 * ocupa.
 */
.capcalera__marca {
  min-width: 0;
  flex: 0 1 auto;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
}

.capcalera__enllac { color: var(--afa-primari-text); text-decoration: underline; }
.capcalera .boto--text { color: var(--afa-primari-text); }

/* ── El logotipo ─────────────────────────────────────────────────────────
 *
 * Compuesto con tipografía del sistema y un triángulo en SVG. No es el
 * logotipo oficial de la escuela: cuando exista el fichero se sustituye este
 * bloque por una imagen y no cambia nada más.
 *
 * En horizontal y no apilado como en la referencia impresa: en vertical eran
 * cuatro pisos y la tarjeta dejaba de caber en la pantalla de un móvil.
 *
 * Estaba en `app.css`, o sea disponible SOLO en la shell de la PWA. Vive aquí
 * porque ahora lo usan las tres páginas del portal, y porque tener dos
 * logotipos —uno grande en la tarjeta y otro inventado en la cabecera— es la
 * forma más rápida de que un producto parezca dos.
 */
.marca {
  display: flex;
  align-items: center;
  gap: var(--afa-espai-2);
}

.marca__cim {
  flex: 0 0 auto;
  width: 2.25rem;
  height: 1.625rem;
  color: var(--afa-taronja-500);
}

.marca__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.05;
}

.marca__escola {
  font-size: 0.625rem;
  letter-spacing: .38em;
  text-indent: .38em;              /* compensa el espaciado del último signo */
  color: var(--afa-gris-600);
}

.marca__centre {
  font-size: 1.1875rem;
  letter-spacing: .04em;
  color: var(--afa-blau-900);
}

/*
 * AFA va CENTRADO en la banda que queda entre el separador vertical y el pico
 * del ángulo naranja: flex: 1 se queda con todo el hueco y justify-content lo
 * centra dentro. Suelto a la izquierda quedaba desamparado en un móvil, que es
 * donde de verdad se mira este carnet.
 *
 * 800 ya es el peso más gordo de los tokens, así que para que se note se sube
 * el cuerpo: en la pila del sistema, más peso del que hay en la familia no lo
 * dibuja el navegador, lo finge — y se ve.
 */
.marca__afa {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  /*
   * Tres cosas suman aquí, y la tercera es la que menos se espera:
   *  - cuerpo grande (xl), que es lo que pedía David;
   *  - peso 900, un corte real de la familia del sistema, no negrita falsa;
   *  - espaciado APRETADO. Iba a .12em y las letras separadas se leen más
   *    ligeras: es parte de por qué una Impact pesa lo que pesa. Juntarlas
   *    aporta tanta masa visual como subir el peso.
   * Lo que NO se puede hacer es pedir una Impact: no está en iOS ni en
   * Android, así que el carnet se vería distinto en cada móvil.
   */
  font-size: var(--afa-mida-xl);
  font-weight: var(--afa-pes-negre);
  letter-spacing: .01em;
  color: var(--afa-blau-700);
  border-left: 1px solid var(--afa-gris-300);
}

/* ── El logotipo a escala de barra ───────────────────────────────────────
 *
 * Mismo lockup, un tercio del tamaño y sobre fondo azul, así que los colores
 * se invierten: el triángulo se queda naranja —es la única nota de color de
 * la marca y aquí es lo que se reconoce de lejos— y los textos pasan a
 * blanco. Nada de esto es un color nuevo: son los mismos tokens.
 *
 * El separador vertical usa `--afa-vora-clara`, que es el borde de la casa
 * para trazos sobre fondo oscuro y ya existía en tokens.css. Con
 * `--afa-gris-300` sobre azul se veía como una raya sucia.
 */
.marca--mini { gap: var(--afa-espai-2); }

.marca--mini .marca__cim { width: 1.5rem; height: 1.0625rem; }

.marca--mini .marca__centre {
  font-size: var(--afa-mida-s);
  font-weight: var(--afa-pes-molt);
  letter-spacing: .1em;
  color: var(--afa-primari-text);
  white-space: nowrap;
}

.marca--mini .marca__afa {
  flex: 0 0 auto;
  align-self: center;
  font-size: var(--afa-mida-m);
  letter-spacing: .02em;
  color: var(--afa-primari-text);
  border-left: 1px solid var(--afa-vora-clara);
  padding-left: var(--afa-espai-2);
  line-height: 1;
}

/*
 * El nombre de la familia, solo en ancho.
 *
 * GOV.UK One Login recomienda no etiquetar «cuenta» a secas sino nombrar la
 * cuenta concreta. Aquí se cumple sin inventar una marca: la cabecera dice de
 * quién es esto. En compacto no sale porque la tarjeta ya lo lleva dos
 * centímetros más abajo, y ahí el sitio es lo que escasea.
 */
.capcalera__familia {
  display: none;
  margin-left: auto;
  font-size: var(--afa-mida-s);
  font-weight: var(--afa-pes-fort);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Los ángulos de color ────────────────────────────────────────────────
 *
 * EL MOTIVO DE LA CASA, y no un adorno cualquiera: es la misma diagonal del
 * triángulo del logotipo, repetida en las esquinas. Estaba escrito solo para
 * la credencial (`.credencial__angle`) y por eso el portal no podía usarlo
 * sin copiarlo. Ahora es un componente con su tamaño y su color en variables,
 * y lo usan la tarjeta —con los valores de siempre— y el portal.
 *
 * NO ES LA FRANJA LATERAL PROHIBIDA, y conviene decir en qué se diferencia:
 * una franja de color a la izquierda de una caja es un indicador de estado
 * pegado a un borde, el recurso que hace que un proyecto parezca hecho con la
 * plantilla de otro. Esto es decoración de marca, no dice nada del estado
 * —vale igual en verde, en rojo y en pendiente— y su forma sale del logotipo.
 *
 * Van SIEMPRE en `position: absolute`, y eso no es solo colocación: dentro de
 * un contenedor flex —`.estat` lo es— un hijo estático se convertiría en un
 * elemento flex más y desmontaría la fila. Es la misma trampa que ya se pisó
 * con `.nota`.
 */
.angle {
  position: absolute;
  z-index: 0;
  pointer-events: none;
}

.angle--sup {
  top: 0; right: 0;
  width:  var(--angle-sup, 4rem);
  height: var(--angle-sup, 4rem);
  background: var(--angle-sup-color, var(--afa-taronja-500));
  clip-path: polygon(100% 0, 100% 100%, 0 0);
}

.angle--inf-dre {
  right: 0; bottom: 0;
  width:  var(--angle-dre-ample, 58%);
  height: var(--angle-dre-alt, 3rem);
  background: var(--angle-dre-color, var(--afa-blau-700));
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

.angle--inf-esq {
  left: 0; bottom: 0;
  width:  var(--angle-esq-ample, 44%);
  height: var(--angle-esq-alt, 2rem);
  background: var(--angle-esq-color, var(--afa-blau-500));
  clip-path: polygon(0 0, 100% 100%, 0 100%);
}

/* ── La cinta del curso ──────────────────────────────────────────────────
 *
 * Otra pieza que existía solo dentro de la tarjeta (`.credencial__curs`) y
 * que el resumen de escritorio reproducía como texto plano: «Curs 2026-2027»
 * suelto en una línea de datos. Al ponerlos uno al lado del otro se veía que
 * eran el mismo dato dicho de dos maneras.
 *
 * Los picos laterales son la diagonal del logotipo otra vez, y por eso la
 * cinta no es un rectángulo redondeado como cualquier pastilla.
 */
.cinta {
  display: inline-block;
  background: var(--afa-blau-700);
  color: var(--afa-primari-text);
  font-size: var(--afa-mida-xs);
  font-weight: var(--afa-pes-fort);
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 0.25rem 1.25rem;
  /* Los picos laterales de una cinta, con la diagonal del logotipo. */
  clip-path: polygon(0 0, 100% 0, calc(100% - 0.55rem) 50%, 100% 100%,
                     0 100%, 0.55rem 50%);
}

/* ── Armazón ──────────────────────────────────────────────────────────────
 *
 * En compacto es un `block` sin relleno: el contenido sigue poniendo el suyo,
 * igual que antes de que este fichero existiera. La rejilla con barra lateral
 * aparece solo a partir de 64rem.
 */
.marc { margin: 0 auto; }

.contingut { min-width: 0; }

/* ── Barra lateral (>= 64rem) ─────────────────────────────────────────── */
.lateral { display: none; }

.lateral__grup {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--afa-espai-2);
  margin: var(--afa-espai-5) 0 var(--afa-espai-2);
  padding: 0 var(--afa-espai-3);
  font-size: var(--afa-mida-xs);
  font-weight: var(--afa-pes-fort);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--afa-text-suau);
}
.lateral__grup:first-child { margin-top: 0; }

.lateral__rol {
  letter-spacing: .04em;
  text-transform: none;
  font-weight: var(--afa-pes-normal);
  color: var(--afa-primari);
  background: var(--afa-taronja-050);
  border-radius: var(--afa-radi-s);
  padding: 1px 7px;
}

.lateral__enllac {
  display: flex;
  align-items: center;
  gap: var(--afa-espai-3);
  min-height: var(--afa-tap-min);
  padding: var(--afa-espai-3);
  border-radius: var(--afa-radi-s);
  color: var(--afa-text);
  text-decoration: none;
  font-size: var(--afa-mida-s);
  font-weight: var(--afa-pes-fort);
}

.lateral__enllac:hover { background: var(--afa-gris-100); }

/*
 * La sección activa: triángulo del logotipo + fondo teñido + peso. Nunca solo
 * color y nunca una franja lateral. WCAG 1.4.1 lo exige de forma explícita:
 * si hay que percibir un color concreto hace falta un indicador no cromático
 * INDEPENDIENTEMENTE del ratio de contraste.
 */
.lateral__enllac[aria-current="page"] {
  background: var(--afa-taronja-050);
  color: var(--afa-blau-900);
  font-weight: var(--afa-pes-molt);
}

/* El hueco del triángulo se reserva SIEMPRE, también en los inactivos: si no,
   la etiqueta activa se desplazaría media letra y la lista bailaría al
   cambiar de sección. */
.lateral__enllac::before {
  content: '';
  flex: none;
  width: .6em;
  height: .52em;
}
.lateral__enllac[aria-current="page"]::before {
  background: var(--afa-accent);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

/* ── Iconografía de la navegación ────────────────────────────────────────
 *
 * No había ninguna: la barra lateral era texto. Con cinco entradas funciona;
 * con ocho —y el inventario del portal son veinticuatro destinos repartidos
 * en siete secciones— deja de funcionar, porque una columna de etiquetas
 * iguales se lee en serie en vez de reconocerse de un vistazo.
 *
 * TRES REGLAS, y las tres son restricciones del proyecto, no gusto:
 *
 * 1. SVG EN LÍNEA. Es lo único compatible con `script-src 'self'` sin
 *    peticiones extra y sin atributos `style`. Nada de fuentes de iconos ni
 *    de sprites externos.
 * 2. EL ICONO NUNCA ES LA ÚNICA SEÑAL. Va siempre con su etiqueta, y es
 *    `aria-hidden`: para un lector de pantalla no dice nada que el texto no
 *    diga ya. Lo mismo vale para el estado activo, que sigue llevando
 *    triángulo, tinte y peso además del color (WCAG 1.4.1).
 * 3. DONDE EL CONCEPTO YA TENÍA ICONO, SE USA EL MISMO DIBUJO. La campana de
 *    «Avisos» es la campana de la cabecera y la etiqueta de «Codis» es la
 *    del codi de descompte de la tarjeta, trazo por trazo. Un juego de
 *    iconos coherente no es el que tiene el mismo grosor de línea: es el que
 *    no dibuja dos veces la misma cosa de dos maneras.
 *
 * El trazo (1.9 a 20 px) iguala ópticamente al de los iconos que ya existen
 * (2 a 14 px en las filas de la tarjeta, 2 a 24 px en la cabecera).
 */
.icona-nav {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  color: var(--afa-text-suau);
}

/*
 * El color del icono sigue al de su fila, y no es cosmético: cada
 * combinación tiene que estar medida en `bin/contrast.php`, así que se usan
 * las que ya están y no se inventa una cuarta.
 *   reposo  gris-600 sobre crema     (ya medido, «texto secundario»)
 *   hover   primari sobre gris-100   (ya medido)
 *   activo  blau-900 sobre taronja-050 (ya medido)
 * Un icono es un objeto gráfico y WCAG 1.4.11 le pide 3:1; las tres pasan de
 * largo porque son parejas pensadas para texto.
 */
.lateral__enllac:hover .icona-nav            { color: var(--afa-primari); }
.lateral__enllac[aria-current="page"] .icona-nav { color: var(--afa-blau-900); }

/* ── Cabecera de una pantalla interior ────────────────────────────────────
 *
 * Sustituye a la franja azul que cada vista llevaba dentro. En compacto se
 * lee igual que antes; en ancho el botón de volver desaparece, porque la
 * barra lateral ya dice dónde estás y desde dónde salir.
 */
.pagina {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--afa-espai-3);
  max-width: 34rem;
  margin: 0 auto;
  padding: var(--afa-espai-5) var(--afa-espai-4) 0;
}

.pagina__titol {
  font-size: var(--afa-mida-l);
  font-weight: var(--afa-pes-molt);
  margin: 0;
  line-height: 1.2;
}

/* ── Títulos de página ────────────────────────────────────────────────── */
.titol-pagina {
  font-size: var(--portal-titol);
  font-weight: var(--afa-pes-molt);
  line-height: 1.1;
  letter-spacing: -.01em;
  margin: 0 0 var(--afa-espai-2);
}

.subtitol-pagina {
  font-size: var(--portal-subtitol);
  color: var(--afa-text-suau);
  line-height: 1.45;
  margin: 0 0 var(--afa-espai-6);
  /* 34rem ≈ 70 caracteres. Baymard recomienda 50-75 por línea y observó que
     ante líneas demasiado largas la gente directamente evita leer. */
  max-width: 34rem;
}

/* ── Rejilla de bloques del resumen ───────────────────────────────────── */
.graella {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--portal-ritme);
  align-items: start;
}

.bloc {
  position: relative;
  background: var(--afa-blanc);
  border: 1px solid var(--afa-vora);
  border-radius: var(--afa-radi-m);
  padding: var(--portal-aire);
  box-shadow: var(--afa-ombra-1);
  min-width: 0;
}

.bloc--ample { grid-column: 1 / -1; }

/* ── El bloque protagonista ──────────────────────────────────────────────
 *
 * En escritorio no hay carnet —decisión de David—, así que el sitio de la
 * credencial lo ocupa el estado de la familia. Y lo que lo hace parecer
 * nuestro es la cita del motivo de la casa: el ángulo naranja de la esquina,
 * la misma diagonal del logotipo, recortada contra el mismo redondeo.
 *
 * UN ángulo y no los tres de la tarjeta, y esto sí es una decisión. Los tres
 * son la firma de la credencial —lo que se sostiene en la mano y se enseña
 * en un mostrador—; repetirlos aquí no sería extender el lenguaje, sería
 * clonar la tarjeta en una caja que no es una tarjeta. Con uno se reconoce
 * la familia; con tres se copia el documento.
 *
 * `overflow: hidden` es lo que recorta el ángulo contra la esquina
 * redondeada. Sin eso asoma por fuera, igual que en la credencial.
 */
.bloc--credencial {
  overflow: hidden;
  --angle-sup: 3rem;
  padding: var(--portal-aire-destacat);
  /*
   * EL RELLENO DERECHO VALE LO QUE EL ÁNGULO, y es la misma regla que la
   * tarjeta ya aplica a su logotipo (`.credencial .marca` reserva 4 rem, que
   * es justo lo que mide su ángulo naranja). Con eso, el borde derecho del
   * contenido nunca entra en el cuadrado del ángulo y por tanto no puede
   * caer dentro de su diagonal, mida lo que mida el bloque.
   *
   * No es una precaución teórica: medido con el estado «caducat», que no
   * lleva cinta y deja el bloque 38 px más bajo, el botón «Consulta les
   * quotes» subía hasta quedar a 18 px del ángulo. Ajustar el tamaño del
   * ángulo a ojo habría durado hasta el siguiente estado; esto es una
   * invariante, y hay prueba en bin/proves/disseny.php.
   */
  padding-right: max(var(--portal-aire-destacat), var(--angle-sup));
}

/* Todo lo que es contenido va por delante del ángulo. Se declara en el hijo
   directo y no en cada trozo: un bloque nuevo dentro no se puede olvidar de
   ponerse delante. */
.bloc--credencial > *:not(.angle) { position: relative; z-index: 1; }

/*
 * El título de bloque va en versalitas pequeñas y el de página en cuerpo
 * grande: son dos niveles que no se pueden confundir cuando hay seis bloques
 * en pantalla. Es la directriz que dice que el dato crítico destaca por lo
 * que se le quita alrededor, no por ponerlo más grande.
 */
.bloc__titol {
  font-size: var(--afa-mida-xs);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--afa-text-suau);
  font-weight: var(--afa-pes-fort);
  margin: 0 0 var(--afa-espai-3);
}

.bloc__cos {
  margin: 0 0 var(--afa-espai-4);
  font-size: var(--afa-mida-s);
  line-height: 1.5;
  color: var(--afa-text-suau);
}

.bloc__peu {
  margin: var(--afa-espai-4) 0 0;
  font-size: var(--afa-mida-s);
}

.bloc__peu a {
  color: var(--afa-primari);
  font-weight: var(--afa-pes-fort);
}

/* Los botones del resumen no ocupan el ancho completo: eso es de un
   formulario de móvil, no de una tarjeta de escritorio. */
.bloc .boto--primari,
.estat .boto--primari {
  display: inline-flex;
  align-items: center;
  width: auto;
  margin-top: 0;
}

.boto--secundari {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--afa-blanc);
  color: var(--afa-primari);
  border: 1px solid var(--afa-vora);
  text-decoration: none;
}
.boto--secundari:hover { background: var(--afa-gris-100); }

/* ── El estado de la familia: el objeto principal del resumen ─────────────
 *
 * En escritorio el protagonista deja de ser la credencial y pasa a ser esto.
 * El motivo está medido: la razón mayoritaria por la que la gente contacta con
 * una organización es información ausente o confusa (38 %), muy por encima de
 * los problemas de servicio. La pregunta que trae aquí a una familia es
 * «¿estamos al día? ¿hasta cuándo? ¿y si no?».
 */
.estat {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--afa-espai-4);
}

/* Marca circular con el mismo lenguaje de símbolos que el validador: ✓ / ✗ / !
   El símbolo va en el marcado y no en un pseudoelemento porque cambia con el
   estado y tiene que poder anunciarse. */
.estat__marca {
  flex: none;
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--afa-mida-l);
  font-weight: var(--afa-pes-molt);
  line-height: 1;
}

.estat--vigent  .estat__marca { background: var(--afa-verd-050);    color: var(--afa-verd-600); }
.estat--caducat .estat__marca { background: var(--afa-vermell-050); color: var(--afa-vermell-600); }
.estat--sense   .estat__marca { background: var(--afa-gris-100);    color: var(--afa-blau-900); }

/*
 * 20rem de base y no 16, medido a 1024 px: con 16 la acción cabía a la
 * fuerza en la misma línea y la frase de estado partía por la mitad —«Núm.
 * de soci» en una línea y el número en la siguiente—. Con 20 la acción baja
 * a su propia línea justo cuando el texto empezaría a romperse, y a 1440
 * sigue arriba a la derecha porque ahí sobra sitio. Es la maqueta cediendo
 * donde tiene que ceder: primero se rompe la fila, no la frase.
 */
.estat__text { min-width: 0; flex: 1 1 20rem; }

/*
 * La frase que responde a la pregunta. Sube de --afa-mida-l (22 px, el mismo
 * cuerpo que el título de la tarjeta) a --portal-destacat, que llega a 26 px
 * donde hay sitio. La escala de tokens.css se hizo para una tarjeta de móvil
 * y aquí la columna mide 900 px: con el cuerpo de antes, la respuesta pesaba
 * lo mismo que el nombre de un bloque.
 */
.estat__titular {
  font-size: var(--portal-destacat);
  font-weight: var(--afa-pes-molt);
  line-height: 1.15;
  letter-spacing: -.01em;
  margin: 0;
}

.estat__linia {
  margin: var(--afa-espai-2) 0 0;
  font-size: var(--afa-mida-s);
  color: var(--afa-text-suau);
  line-height: 1.5;
}

/*
 * La explicación de «encara no tens carnet». Va con el cuerpo del texto y no
 * en gris apagado: es lo que la familia ha venido a entender, no una nota al
 * pie. Y con la medida limitada, porque son cuatro líneas y a 900 px de ancho
 * una línea de 130 caracteres no se lee, se evita.
 */
.estat__ajuda {
  margin: var(--afa-espai-3) 0 0;
  font-size: var(--afa-mida-s);
  line-height: 1.55;
  max-width: 34rem;
}

/* La cinta va en su propia línea y no encadenada detrás de la fecha: es una
   pieza, no una palabra. Con `margin-top` y no con `gap` porque su hermano
   de arriba es un párrafo y el contenedor no es flex. */
.estat__cinta { margin: var(--afa-espai-3) 0 0; }

.estat__etiqueta { font-weight: var(--afa-pes-molt); letter-spacing: .04em; }
.estat--vigent  .estat__etiqueta { color: var(--afa-verd-600); }
.estat--caducat .estat__etiqueta { color: var(--afa-vermell-600); }
.estat--sense   .estat__etiqueta { color: var(--afa-text); }

.estat__accio { margin-left: auto; }

/* ── El código de descuento, en grande y SOLO en escritorio ───────────────
 *
 * No contradice la decisión de que en la tarjeta sea «una fila más»: aquella
 * es sobre la tarjeta, cuya cohesión manda, y sigue igual. Aquí hay un
 * contexto que en el móvil no existe — la compra en línea se hace con un
 * teclado delante, y este código está hecho para pegarse en un campo de cupón.
 */
.codi-gran {
  display: flex;
  align-items: center;
  gap: var(--afa-espai-3);
  flex-wrap: wrap;
  margin: 0;
}

.codi-gran__valor {
  font-family: var(--afa-font-mono);
  font-size: var(--portal-codi);
  font-weight: var(--afa-pes-molt);
  letter-spacing: .04em;
  color: var(--afa-blau-900);
  background: var(--afa-gris-100);
  border: 1px dashed var(--afa-vora);
  border-radius: var(--afa-radi-s);
  padding: var(--afa-espai-3) var(--afa-espai-4);
}

/* La confirmación de copiado lleva texto además de color, como en la tarjeta. */
.codi-gran__estat {
  font-size: var(--afa-mida-s);
  font-weight: var(--afa-pes-fort);
  color: var(--afa-verd-600);
}

/* ── El puente al móvil, en banda ────────────────────────────────────────
 *
 * En escritorio NO hay carnet —decisión de David: ofrecerlo competiría con la
 * instalación de la PWA en vez de empujar hacia ella—, así que este bloque es
 * lo que ocupa su sitio. En horizontal, con el código a la izquierda y el
 * texto al lado: un QR de 168 px en una columna de 900 deja un hueco enorme
 * debajo si se apila, y el hueco se lee como que falta algo.
 */
/*
 * LA BANDA AZUL, y es el segundo cambio de identidad del resumen.
 *
 * Este bloque no es información: es la única acción que el escritorio le pide
 * a la familia —«llévate el carnet al móvil»—, y en iOS es la que decide si
 * esa familia va a poder recibir un aviso de la AFA algún día. Pintado como
 * los demás, era la quinta caja blanca de la página y se leía como un pie.
 *
 * Va en `--afa-primari` porque es el color de la marca y porque separa lo que
 * se lee de lo que se hace. Y cierra la página con el mismo pie que la
 * credencial: los DOS ángulos de abajo, la silueta de montaña del logotipo,
 * en los dos azules de la paleta sobre el azul de la banda. En la tarjeta ese
 * pie va sobre blanco; aquí va invertido, que es la misma pieza y no otra.
 *
 * El QR conserva su placa blanca por obligación técnica, no estética: un
 * código se lee con la cámara de otro móvil y tiene que ser negro sobre
 * blanco. Es la misma razón por la que el proyecto no ofrece modo oscuro.
 */
.bloc--pont {
  overflow: hidden;
  background: var(--afa-primari);
  border-color: var(--afa-blau-900);
  color: var(--afa-primari-text);
  --angle-dre-color: var(--afa-blau-900);
  --angle-esq-color: var(--afa-blau-500);
  --angle-dre-alt: 2.25rem;
  --angle-esq-alt: 1.5rem;
  /* El pie de montañas se come la esquina inferior: se le reserva sitio,
     igual que la credencial reserva 2,75rem para su ángulo azul. */
  padding-bottom: calc(var(--portal-aire) + 1.25rem);
}

.bloc--pont > *:not(.angle) { position: relative; z-index: 1; }

/* Sobre azul, los tres cuerpos de texto cambian de color y ninguno estrena
   una pareja: crema y blanco sobre --afa-primari son las que ya usa la
   cabecera. El título deja el gris apagado, que sobre azul sería ilegible. */
.bloc--pont .bloc__titol { color: var(--afa-taronja-050); }
.bloc--pont .bloc__cos   { color: var(--afa-primari-text); }
.bloc--pont .bloc__peu   { color: var(--afa-primari-text); }
.bloc--pont .pont__url   { color: var(--afa-taronja-050); }

/* La placa blanca del QR: el código necesita fondo claro y borde de silencio
   alrededor, que es lo que la cámara usa para encontrarlo. */
.bloc--pont .pont__qr {
  background: var(--afa-blanc);
  border-radius: var(--afa-radi-s);
  padding: var(--afa-espai-2);
}

@media (min-width: 34rem) {
  .bloc--pont {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      'qr titol'
      'qr cos'
      'qr peu';
    align-content: start;
    column-gap: var(--afa-espai-5);
  }
  .bloc--pont .bloc__titol { grid-area: titol; }
  .bloc--pont .bloc__cos   { grid-area: cos; margin-bottom: var(--afa-espai-2); }
  .bloc--pont .pont__qr    { grid-area: qr; margin: 0; align-self: start; }
  .bloc--pont .bloc__peu   { grid-area: peu; margin-top: 0; align-self: start; }
}

/* ── Lista compacta reutilizable (avisos y usos del resumen) ─────────── */
.fila {
  display: flex;
  align-items: baseline;
  gap: var(--afa-espai-3);
  padding: var(--afa-espai-3) 0;
  border-top: 1px solid var(--afa-gris-100);
  margin: 0;
}
.fila:first-of-type { border-top: 0; padding-top: 0; }

.fila__principal { flex: 1; min-width: 0; }

.fila__titol {
  display: block;
  font-size: var(--afa-mida-s);
  font-weight: var(--afa-pes-fort);
  overflow-wrap: anywhere;
}

/* Sin leer: el TRIÁNGULO del logotipo delante, igual que en la lista de
   avisos. Es el motivo de la casa, no un punto de color genérico. */
.fila__nou::before {
  content: '';
  display: inline-block;
  width: .72em;
  height: .62em;
  margin-right: .45em;
  background: var(--afa-accent);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.fila__meta {
  display: block;
  margin-top: 2px;
  font-size: var(--afa-mida-xs);
  color: var(--afa-text-suau);
}

/* ── Estados vacío, de carga y de error de un bloque ──────────────────────
 *
 * Van diseñados y no descritos en prosa. En un portal donde una sección
 * consulta un ERP que puede no responder, los estados no son un detalle: son
 * la mitad del trabajo. Los tres se distinguen por texto, no solo por color.
 */
.bloc__buit {
  margin: 0;
  font-size: var(--afa-mida-s);
  color: var(--afa-text-suau);
}

/* Carga: tres barras grises que ocupan lo que ocupará el contenido, para que
   la tarjeta no dé un salto al llegar el dato. La animación la apaga la regla
   global de prefers-reduced-motion de tokens.css. */
.bloc__carregant {
  display: block;
  height: .8rem;
  margin-bottom: var(--afa-espai-3);
  border-radius: var(--afa-radi-s);
  background: var(--afa-gris-100);
  animation: portal-batec 1.4s ease-in-out infinite;
}
.bloc__carregant:nth-child(2) { width: 80%; }
.bloc__carregant:nth-child(3) { width: 55%; }

@keyframes portal-batec {
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}

/* ── 48rem: la rejilla pasa a dos columnas. La navegación NO cambia. ───── */
@media (min-width: 48rem) {
  .marc { padding: 0 var(--afa-espai-5); max-width: 74rem; }
  .graella { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pagina { max-width: 40rem; }
}

/* ── 64rem: aparece la barra lateral y la hamburguesa se retira. ──────────
 *
 * La hamburguesa desaparece en ancho porque es la recomendación más rotunda
 * que hay sobre esto: en el estudio de NN/g con 179 personas, la navegación
 * oculta se usó el 27 % de las veces en escritorio frente al 48-50 % cuando
 * estaba visible, y las tareas fueron un 39 % más lentas.
 */
@media (min-width: 64rem) {
  /*
   * La cabecera sigue siendo de ancho completo —la franja azul llega a los dos
   * bordes— pero su contenido se alinea con el del portal en vez de quedarse
   * a 1.238 px de distancia. Se hace con relleno y no con un elemento
   * envolvente: así el menú desplegable, que se posiciona respecto a la
   * cabecera, sigue cayendo debajo de la hamburguesa.
   */
  .capcalera {
    padding-inline: max(var(--afa-espai-5), calc((100% - 74rem) / 2 + var(--afa-espai-5)));
  }

  .capcalera__marca { font-size: var(--afa-mida-s); }
  .capcalera__familia { display: block; }

  /*
   * La hamburguesa y su menú, fuera: la navegación está a la vista.
   *
   * Con dos clases (0,2,0) gana a `.menu { display: flex }` de app.css sin
   * necesitar `!important`, que en este proyecto está reservado a `[hidden]`.
   * Y hace falta cubrir el menú además del botón: si alguien lo abre y luego
   * ensancha la ventana, se quedaría abierto sobre una barra lateral.
   */
  .capcalera .icona--menu,
  .capcalera .menu { display: none; }

  /*
   * LA COLUMNA DE LA BARRA LATERAL NO EXISTE CUANDO NO HAY BARRA, y esto era
   * un fallo de verdad. La rejilla declaraba `16rem minmax(0,1fr)` más un
   * hueco, así que SIN SESIÓN —cuando `Disseny::lateral()` no pinta nada—
   * la primera columna seguía ahí, vacía, y el `<main>` caía dentro de ella:
   * la pantalla de entrada se servía a 1.440 px dentro de una columna de
   * **272 px**, con el reclamo del móvil partiendo la dirección a media
   * palabra. Es la única pantalla del portal a la que no se entra con
   * sesión, o sea la única donde no se había mirado.
   *
   * Se arregla moviendo la medida del CARRIL al ELEMENTO: el carril es
   * `auto`, que vale cero cuando no hay nada dentro, y los 16 rem los pone
   * la barra. El hueco pasa a ser su margen por el mismo motivo — un
   * `column-gap` se aplica entre carriles aunque uno esté vacío.
   *
   * Se hace así y no con `:has(> .lateral)` a propósito: si un navegador no
   * entendiera `:has`, la regla entera se cae y la barra se apila encima del
   * contenido. Con `auto` no hay nada que entender.
   */
  .marc {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    padding: 0 var(--afa-espai-5) var(--afa-espai-7);
  }

  .lateral {
    display: block;
    position: sticky;
    top: var(--afa-espai-5);
    align-self: start;
    width: 16rem;
    margin-right: var(--afa-espai-6);
    padding-top: var(--afa-espai-6);
  }

  .contingut {
    max-width: 56rem;
    padding-top: var(--afa-espai-6);
  }

  /* Las pantallas interiores dejan de necesitar el botón de volver: la barra
     lateral dice dónde estás y desde dónde salir. */
  .pagina {
    max-width: none;
    margin: 0;
    padding: 0 0 var(--afa-espai-2);
  }
  .pagina__titol { font-size: var(--portal-titol); letter-spacing: -.01em; }
  .pagina [data-tornar] { display: none; }

  .graella { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /*
   * LA PROSA CRECE CON EL ANCHO; LOS DATOS NO.
   *
   * Es la otra mitad de la decisión de densidad, y responde a «la escala
   * viene del móvil y en escritorio se queda pequeña». Sube lo que se LEE
   * —el texto explicativo de un bloque— y se queda donde está lo que se
   * CONSULTA: las filas de avisos y de usos son una lista, y una lista con
   * el cuerpo del texto corrido ocupa el doble y se recorre peor.
   *
   * Los títulos de bloque tampoco suben: son etiquetas en versalitas y su
   * trabajo es no competir con el dato que tienen debajo.
   */
  .bloc__cos { font-size: var(--afa-mida-m); }
  .estat__linia,
  .estat__ajuda { font-size: var(--afa-mida-m); }
}
