/* [PILOT 2 · PEÇA 7 · 16/10/2026] Peces de maquetació d'Iridian per als mòduls IA (prefix `ia-l-`).
 *
 * Per què: cada mòdul generat reescrivia les mateixes disposicions (graella de targetes, fila de botons, text +
 * imatge…) amb les seves pròpies @media (54 de 60 CSS de sistema en porten; 15 talls diferents). Aquí viuen UNA
 * vegada, provades a 390/768/1440, i la IA només posa una classe amb paràmetres amb NOM (mai xifres):
 *   ia-l-stack     apilat vertical                     --gap-0|xs|s|m|l|xl
 *   ia-l-cluster   fila que salta de línia             --gap-*  --justify-start|center|end|between  --align-start|center|end|baseline
 *   ia-l-grid      graella que s'adapta (auto-fit)     --gap-*  --min-xs|sm|md|lg  --max-2|3|4
 *   ia-l-sidebar   barra lateral + contingut           --gap-*  --side-sm|md|lg  --side-end  --content-min-l
 *   ia-l-switcher  fila que passa a columna            --gap-*  --at-sm|md|lg
 *   ia-l-center    columna centrada amb mesura         --measure-s|m|l  --text  --intrinsic
 *   ia-l-cover     cobrir (hero) amb alçada mínima     --h-s|m|l|full  --pad-0|s|m|l  (fill opcional .ia-l-cover__main)
 *   ia-l-frame     marc de mitjà amb proporció         --ratio-16x9|4x3|3x2|1x1|3x4|21x9
 *
 * Regles d'aquest fitxer (no les trenquis):
 *  1. MÒBIL DE SÈRIE, SENSE @media: tot és intrínsec (auto-fit + min(), flex-basis amb llindar, min-inline-size %).
 *     L'única @media és la de qualitat (cap). Container queries: PILOT 3.
 *  2. ESTILS MANA: els espais són l'escala d'Estils (--ia-space-xs…xl, «Layout y espaciado»), amb reserva rem
 *     (espais i radis sí porten reserva; skill iridian-estils §2.3). Les amplades (mínims de graella, barra lateral,
 *     llindar, mesura) són CONSTANTS d'aquest fitxer (`--ia-l-*`), no camps d'Estils (cap camp nou si cap no en cobreix
 *     el rol; si Xavi les vol a Estils, és una decisió a part).
 *  3. ESPECIFICITAT 0: tot va dins `:where()`, de manera que el CSS del mòdul, el Grid i el Live Editor sempre hi passen
 *     per sobre (Tema < Estils < Mòdul < Grid < Live Editor). Excepcions, NOMÉS on una regla d'ETIQUETA del tema ho
 *     trencaria, i sempre per sota d'una regla de mòdul (0,2,0): el reset de marges verticals dels fills directes
 *     (`.ia-l-x > *`, 0,1,0; guanya `main p` / `main li`, 0,0,2, perquè el gap sigui l'únic espai), el mitjà d'un
 *     ia-l-frame (0,1,1; guanya `img { height: auto }` de main.css) i `.ia-l-cover__main` (0,1,0; guanya el marge
 *     dels `h1…h6` del tema). Les provoca la prova de render: sense elles, V2/F2/S2 cauen.
 *  4. Paràmetres = variables locals que cada peça REINICIA al seu propi element: una peça niada no hereta el gap de
 *     la mare. Els modificadors van DESPRÉS de la base (mateixa especificitat 0 → mana l'ordre del fitxer).
 *  5. Cap `!important`, cap color, cap tipografia, cap moviment: només disposició. `translate`/`scale`/`rotate`/`opacity`,
 *     transicions i animacions són el canal del catàleg d'efectes, que les escriu en línia (PLA_F1_CATALEG §5.1.7; test C7).
 * Contracte i proves: docs/coordinacio/PROPOSTA_CSS_MAQUETACIO.md; render a 390/768/1440 amb tools/layout_primitives_check.php.
 */

:root {
    /* Mínims de la graella (amplada mínima d'una cel·la abans de saltar de fila). */
    --ia-l-min-xs: 10rem;
    --ia-l-min-sm: 14rem;
    --ia-l-min-md: 18rem;
    --ia-l-min-lg: 24rem;
    /* Amplada de la barra lateral. */
    --ia-l-side-sm: 14rem;
    --ia-l-side-md: 20rem;
    --ia-l-side-lg: 26rem;
    /* Llindar del switcher: per sota d'aquesta amplada del CONTENIDOR, tot en columna. */
    --ia-l-at-sm: 30rem;
    --ia-l-at-md: 40rem;
    --ia-l-at-lg: 52rem;
    /* Mesura de lectura (amplada màxima d'una columna de text). */
    --ia-l-measure-s: 45ch;
    --ia-l-measure-m: 65ch;
    --ia-l-measure-l: 80ch;
}

/* ── [17/10/2026 · Marta #14, P1] Cap text d'un mòdul IA desborda l'amplada del mòdul ────────────────────────────────
 * Un text sense espais (un número de 29 xifres a «Cifras», un titular d'una sola paraula, una URL, un preu) es parteix on
 * calgui en lloc de sortir de la caixa i fer scroll horitzontal. Dues regles, especificitat 0 (regla 3: el mòdul hi passa
 * per sobre), a l'arrel de TOTS els mòduls IA (`class="iaLayer-<slug>"`, panel/libs/ai_module_root.php):
 *  · `overflow-wrap: break-word` (s'hereta): una paraula que no hi cap salta de línia. NO `anywhere`: aquest també redueix
 *    l'amplada MÍNIMA del contingut i trenca el truc del `width: min-content` (portada de la Gemma a /es/demo: «Hola, soy»
 *    sortia lletra a lletra en vertical). `break-word` no la toca.
 *  · `min-width: 0` als elements de text: un fill de graella `1fr` o un fill flex (min-width:auto per defecte) pot
 *    estrènyer-se per sota de la paraula més llarga, i aleshores la primera regla el parteix. Fora d'una graella o d'un
 *    flex no fa res (0 ja és el valor inicial). Excepte els mitjans i els controls (img, svg, video, iframe, canvas, picture,
 *    object, embed, input, select, textarea, button), que mantenen la seva mida mínima (no s'aixafen).
 * Prova de render (390/768/1440): tests/ia_layer/fixtures/ia_text_overflow/demo.html (T1–T6, també el min-content i la
 * imatge). Comprovat sense canvis a les 12 pàgines del banc visual del DEF a 390 i 1440 (alçada de cada mòdul i amplada). */
:where([class*="iaLayer-"]) { overflow-wrap: break-word; }
:where([class*="iaLayer-"] :not(img, svg, video, iframe, canvas, picture, object, embed, input, select, textarea, button)) { min-width: 0; }
/* [21/10/2026 · cssf, prova final] Tercera regla: els TÍTOLS i els PARÀGRAFS no fan mai més ample que el seu contenidor. En una columna
 * flex amb `align-items: flex-start` (o center/end), cada fill fa l'amplada del seu contingut, com a mínim la de la paraula més llarga:
 * un títol de portada amb una paraula llarga («Diseñamos», «desenvolupament») feia una caixa més ampla que la columna i, com que la
 * portada té `overflow: hidden` (per al fons d'imatge o vídeo), a 390 px se'n tallaven les últimes lletres (gen-fixtures qafin14_fonsvideo,
 * qamr1, qafin05_parallax: 3 de 3 portades amb fons de la IA). Amb el sostre, la caixa queda a la columna i la primera regla parteix la
 * paraula que no hi cap. No toca el min-content (el truc de la Gemma continua: T5) ni els mitjans; especificitat 0 (regla 3).
 * Prova de render: ia_text_overflow/demo.html, M7/T7. */
:where([class*="iaLayer-"] :is(h1, h2, h3, h4, h5, h6, p)) { max-width: 100%; }
/* [24/10/2026 · fix5c · punt 5, prova del Pere] Quarta regla: els TEXTOS CURTS (noms, càrrecs, autors, etiquetes, xips, insígnies, antetítols) mai
 * es parteixen a mitja paraula: «Al/bert Ju/an» a les opinions de 4 columnes. La columna del nom (fill flex al costat de la foto, amb min-width:0)
 * es fa més estreta que la paraula i el `break-word` de la primera regla la partia; amb `normal` cada paraula va sencera a la seva línia (com a molt
 * sobresurt del seu requadre cap al marge de la targeta; mesurat: 0 px fora de la targeta a 390/768/900/1100/1440). Es reconeixen per la classe del
 * mòdul (`…__name`, `…-role`, `…-tag`…; «cite»), només si són text sense blocs a dins (`:not(:has(…))`: el contenidor `…__author` de la foto + el
 * nom no hi entra). Els PREUS no: un preu és una sola «paraula» de xifres i, si no hi cap, s'ha de poder partir (M4; mesurat: «1.000.000.000€» en una
 * targeta feia scroll horitzontal amb `normal`). Especificitat 0 (regla 3): el CSS del mòdul hi passa per sobre; per això, en CREAR, el pont de
 * revisió del CSS (gb_check_title_wrap, panel/ajax/_ia_title_wrap.php) treu també `break-word|anywhere|break-all` de les regles d'aquests textos.
 * Prova de render: ia_text_overflow/demo.html, M8/T8 (també T1/T2: cap desbordament del document ni del mòdul). */
:where([class*="iaLayer-"] :is(cite, [class*="-name"], [class*="_name"], [class*="-role"], [class*="_role"], [class*="-author"], [class*="_author"], [class*="-cargo"], [class*="_cargo"], [class*="-label"], [class*="_label"], [class*="-tag"], [class*="_tag"], [class*="-chip"], [class*="_chip"], [class*="-badge"], [class*="_badge"], [class*="-eyebrow"], [class*="_eyebrow"], [class*="-kicker"], [class*="_kicker"]):not(:has(p, div, ul, ol, li, dl, h1, h2, h3, h4, h5, h6, blockquote, section, article, figure, table, form))) { overflow-wrap: normal; word-break: normal; }

/* ── [28/10/2026 · P1 de la dissenyadora] TÍTOLS · CONTENIDOR ─────────────────────────────────────────────────────────────────
 * Cas real (qa-marta-dissenyadora-28-10): «Portada con imagen» en mitja columna (278 px) pintava el títol a 96 px i la paraula es partia per la meitat,
 * sense guionet («mens/aje», «princi/pal»), als 4 heroes de 2 columnes. La mida del títol (--ia-title-hero-size|-section-size) és ara el MÍNIM entre la
 * d'Estils i un sostre en unitats cqi (18 % de l'amplada del contenidor, amb terra de 2 rem als heroes i 1,5 rem a les seccions): en un contenidor ample no mossega.
 * Aquí viu l'altra meitat: QUI és el contenidor, la reserva de la fórmula i com es parteix una paraula que no hi cap.
 *  · És la COLUMNA del Grid (`.row > .col-*`) que té un mòdul IA com a fill directe (l'arrel porta data-idbloc, posat per modules/_runtime.php): el
 *    mòdul hi ocupa tota l'amplada, així que l'amplada de la columna és la del mòdul. NO l'arrel del mòdul: container-type crea un context de format
 *    independent i, a més, l'arrel pot ser un flex que s'encongeix per contingut (col·lapsaria a 0 amb la contenció d'amplada) i canviaria els marges
 *    que col·lapsen cap enfora. Una columna ja és element de flex/graella (ja és context independent) i té amplada pròpia (flex-basis / width de .col-N):
 *    la contenció d'amplada no li canvia res. `.col-auto` / `.col-md-auto` queden fora: fan l'amplada del contingut i col·lapsarien.
 *  · container-type: inline-size no aplica contenció de disposició (css-contain-3: només mida d'amplada i estil, i un context de format independent): position: fixed
 *    i sticky dels fills no canvien (comprovat al navegador: prova de render title_container, T-fixed).
 *  · Sense columna (arrel fora del Grid, vista prèvia del Taller…) no hi ha contenidor: cqi val 1 % de l'amplada de la finestra, de manera que el sostre
 *    només actua en finestres estretes (mòbil) i el mòdul es veu com sempre en una finestra ampla.
 * RESERVA DE LA FÓRMULA (revisió 28/10, P1-1): els dos àlies de títol viuen a system-twig.css, però system.css es GENERA (no és a git) i una web que s'actualitza
 * no el regenera fins que algú desa Estils: sense això el títol continuava a 96 px dins de 286 px. Aquest full SÍ que arriba amb l'actualització, així que l'arrel
 * de cada mòdul IA torna a declarar els dos àlies amb la MATEIXA fórmula (només depèn de --ia-heading-1|2-size, que ja és al system.css vell). Especificitat 0
 * (:where): un mòdul, el Grid o el Live Editor que escrigui la seva pròpia mida hi passa per sobre. Guarda de paritat amb la plantilla: test_title_container_size.php TC6.
 * Un mòdul amb DUES columnes internes (text + imatge) fa que el títol visqui en una columna més estreta que el mòdul (el hero partit: títol de 276 px dins d'un
 * mòdul de 673 px): la seva columna de text és també contenidor, amb UNA regla comuna (TEXT DE DUES COLUMNES, més avall) i cqi mesura la columna del títol, no la del mòdul.
 * Partició de paraules (revisió 28/10, P0-1): l'arrel dels mòduls hi posa `overflow-wrap: break-word` (xarxa de la Marta #14, més amunt) i el títol l'hereta; en un
 * contenidor estret (< 30 rem) s'hi afegeix `hyphens: auto` NOMÉS als títols de hero i de secció (h1/h2; decisió de Xavi 28/10: «no parteix paraules, guionet si cal»; els h3–h6 només porten break-word) amb `hyphenate-limit-chars: 10 4 4` (les paraules curtes no es parteixen; els navegadors que no el coneixen l'ignoren) (la llengua l'agafa del <html lang>): la paraula es parteix per síl·labes AMB guionet quan el navegador té
 * el diccionari i, si no (Chrome no en porta per al català, l'anglès ni l'italià), es talla només quan no hi ha més remei. MAI `overflow-wrap: normal`: «Desenvolupament»,
 * «Instal·lacions» o un correu feien el document de 514 px a 390 (i de 495 a 320). En un contenidor ample es queda l'herència d'abans (cap canvi: `hyphens: auto`
 * partiria el títol a final de línia encara que la paraula hi càpiga, p. ex. «di-cen»). Especificitat 0: un mòdul que escrigui la seva pròpia regla hi passa per sobre.
 * Prova de render: tests/ia_layer/fixtures/ia_text_overflow/demo.html (M9–M11, 320 i 390) i fixtures/title_container/demo.html. */
:where([class*="iaLayer-"]) {
    --ia-title-hero-size: min(var(--ia-heading-1-size), max(2rem, 18cqi));
    --ia-title-section-size: min(var(--ia-heading-2-size), max(1.5rem, 18cqi));
}
:where(.row > [class*="col-"]:not([class*="-auto"]):has(> [class*="iaLayer-"][data-idbloc])) { container-type: inline-size; }
@container (max-width: 30rem) {
    :where([class*="iaLayer-"] :is(h1, h2, h3, h4, h5, h6)) { overflow-wrap: break-word; }
    :where([class*="iaLayer-"] :is(h1, h2)) { hyphens: auto; hyphenate-limit-chars: 10 4 4; }
}
/* TEXT DE DUES COLUMNES (revisió 28/10, P0-2 i P1-2): la columna de text d'un mòdul amb text + imatge en dues columnes és el contenidor del seu títol.
 * `width: 100%` perquè la contenció d'amplada fa que una caixa d'amplada automàtica (element de graella amb `margin: auto`, que és el que escriu «Posición del bloque»
 * del Live Editor) quedi a 0 px: ocupa la seva pista com sempre (la graella l'estira) i el `max-width` de cada mòdul continua manant. Un mòdul nou amb dues columnes
 * hi ha d'afegir la seva columna aquí: test_title_container_size.php TC7 (cens) cau si no. */
:where(
    .iaLayer-iaherosplitv1 .ihsv1-content,
    .iaLayer-iaaboutv1 .iabtv1-content,
    .iaLayer-iaproducthighlightv1 .iphv1-content,
    .iaLayer-iacasestudyv1 .icsv1-content,
    .iaLayer-ianewsletterv1 .inlv1-copy,
    .iaLayer-imatgegrandaltv1 .igda-body,
    .iaLayer-iamapv1 .imv1-body,
    .iaLayer-trabajarjuntostecnologia .wj-content
) { container-type: inline-size; width: 100%; }

/* ── Gap comú: base m, modificadors --gap-* (escala d'Estils) ─────────────────────────────────────────────── */
:where(.ia-l-stack, .ia-l-cluster, .ia-l-grid, .ia-l-sidebar, .ia-l-switcher) {
    --ia-l-gap: var(--ia-space-m, 1.5rem);
    gap: var(--ia-l-gap);
}
:where(.ia-l-stack, .ia-l-cluster) { --ia-l-gap: var(--ia-space-s, 1rem); }
:where(.ia-l-stack--gap-0, .ia-l-cluster--gap-0, .ia-l-grid--gap-0, .ia-l-sidebar--gap-0, .ia-l-switcher--gap-0) { --ia-l-gap: 0px; }
:where(.ia-l-stack--gap-xs, .ia-l-cluster--gap-xs, .ia-l-grid--gap-xs, .ia-l-sidebar--gap-xs, .ia-l-switcher--gap-xs) { --ia-l-gap: var(--ia-space-xs, 0.75rem); }
:where(.ia-l-stack--gap-s, .ia-l-cluster--gap-s, .ia-l-grid--gap-s, .ia-l-sidebar--gap-s, .ia-l-switcher--gap-s) { --ia-l-gap: var(--ia-space-s, 1rem); }
:where(.ia-l-stack--gap-m, .ia-l-cluster--gap-m, .ia-l-grid--gap-m, .ia-l-sidebar--gap-m, .ia-l-switcher--gap-m) { --ia-l-gap: var(--ia-space-m, 1.5rem); }
:where(.ia-l-stack--gap-l, .ia-l-cluster--gap-l, .ia-l-grid--gap-l, .ia-l-sidebar--gap-l, .ia-l-switcher--gap-l) { --ia-l-gap: var(--ia-space-l, 2rem); }
:where(.ia-l-stack--gap-xl, .ia-l-cluster--gap-xl, .ia-l-grid--gap-xl, .ia-l-sidebar--gap-xl, .ia-l-switcher--gap-xl) { --ia-l-gap: var(--ia-space-xl, 3rem); }

/* El gap és l'únic espai entre fills: fora marges verticals heretats del tema (main p, main li). Vegeu la regla 3. */
.ia-l-stack > *,
.ia-l-cluster > *,
.ia-l-grid > *,
.ia-l-sidebar > *,
.ia-l-switcher > * {
    margin-block: 0;
}

/* ── 1. Apilat ───────────────────────────────────────────────────────────────────────────────────────────── */
:where(.ia-l-stack) {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
}

/* ── 2. Fila que salta ───────────────────────────────────────────────────────────────────────────────────── */
:where(.ia-l-cluster) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
}
:where(.ia-l-cluster--justify-start) { justify-content: flex-start; }
:where(.ia-l-cluster--justify-center) { justify-content: center; }
:where(.ia-l-cluster--justify-end) { justify-content: flex-end; }
:where(.ia-l-cluster--justify-between) { justify-content: space-between; }
:where(.ia-l-cluster--align-start) { align-items: flex-start; }
:where(.ia-l-cluster--align-center) { align-items: center; }
:where(.ia-l-cluster--align-end) { align-items: flex-end; }
:where(.ia-l-cluster--align-baseline) { align-items: baseline; }

/* ── 3. Graella que s'adapta ─────────────────────────────────────────────────────────────────────────────────
   Cel·la = max(mínim, amplada de «max» columnes), mai més ample que el contenidor (min(…, 100%)): a 390 px cap
   graella desborda, encara que el mínim sigui més gran que la pantalla. Sense --max-*, tantes columnes com hi càpiguen. */
:where(.ia-l-grid) {
    --ia-l-grid-min: var(--ia-l-min-md);
    --ia-l-grid-max: 12;
    display: grid;
    grid-template-columns: repeat(
        auto-fit,
        minmax(min(100%, max(var(--ia-l-grid-min), (100% - (var(--ia-l-grid-max) - 1) * var(--ia-l-gap)) / var(--ia-l-grid-max))), 1fr)
    );
    align-items: stretch;
}
:where(.ia-l-grid--min-xs) { --ia-l-grid-min: var(--ia-l-min-xs); }
:where(.ia-l-grid--min-sm) { --ia-l-grid-min: var(--ia-l-min-sm); }
:where(.ia-l-grid--min-md) { --ia-l-grid-min: var(--ia-l-min-md); }
:where(.ia-l-grid--min-lg) { --ia-l-grid-min: var(--ia-l-min-lg); }
:where(.ia-l-grid--max-2) { --ia-l-grid-max: 2; }
:where(.ia-l-grid--max-3) { --ia-l-grid-max: 3; }
:where(.ia-l-grid--max-4) { --ia-l-grid-max: 4; }

/* ── 4. Barra lateral + contingut ────────────────────────────────────────────────────────────────────────────
   El 1r fill és la barra (o l'últim amb --side-end); l'altre és el contingut. Quan el contingut quedaria per sota
   del 50 % (60 % amb --content-min-l), salta a sota: a mòbil, apilat de sèrie. */
:where(.ia-l-sidebar) {
    --ia-l-side: var(--ia-l-side-md);
    --ia-l-content-min: 50%;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
}
:where(.ia-l-sidebar--side-sm) { --ia-l-side: var(--ia-l-side-sm); }
:where(.ia-l-sidebar--side-md) { --ia-l-side: var(--ia-l-side-md); }
:where(.ia-l-sidebar--side-lg) { --ia-l-side: var(--ia-l-side-lg); }
:where(.ia-l-sidebar--content-min-l) { --ia-l-content-min: 60%; }
:where(.ia-l-sidebar--stretch) { align-items: stretch; }
:where(.ia-l-sidebar) > :where(*) {
    flex-basis: var(--ia-l-side);
    flex-grow: 1;
    min-inline-size: 0;
}
:where(.ia-l-sidebar:not(.ia-l-sidebar--side-end)) > :where(:last-child),
:where(.ia-l-sidebar--side-end) > :where(:first-child) {
    flex-basis: 0;
    flex-grow: 999;
    min-inline-size: var(--ia-l-content-min);
}
:where(.ia-l-sidebar:not(.ia-l-sidebar--side-end)) > :where(:only-child),
:where(.ia-l-sidebar--side-end) > :where(:only-child) {
    min-inline-size: 100%;
}

/* ── 5. Fila que passa a columna (switcher) ──────────────────────────────────────────────────────────────────
   Tots els fills a la mateixa fila mentre el CONTENIDOR fa més del llindar; per sota, tots en columna (mai 2+1).
   Amb més de 4 fills, sempre en columna (fer servir ia-l-grid). */
:where(.ia-l-switcher) {
    --ia-l-at: var(--ia-l-at-md);
    display: flex;
    flex-wrap: wrap;
}
:where(.ia-l-switcher--at-sm) { --ia-l-at: var(--ia-l-at-sm); }
:where(.ia-l-switcher--at-md) { --ia-l-at: var(--ia-l-at-md); }
:where(.ia-l-switcher--at-lg) { --ia-l-at: var(--ia-l-at-lg); }
:where(.ia-l-switcher) > :where(*) {
    flex-grow: 1;
    flex-basis: calc((var(--ia-l-at) - 100%) * 999);
    min-inline-size: 0;
}
:where(.ia-l-switcher) > :where(:nth-last-child(n+5)),
:where(.ia-l-switcher) > :where(:nth-last-child(n+5) ~ *) {
    flex-basis: 100%;
}

/* ── 6. Centrat amb mesura ───────────────────────────────────────────────────────────────────────────────────
   Columna centrada d'amplada màxima de lectura. La mesura és sobre el CONTINGUT (box-sizing: content-box): un
   padding del mòdul no la retalla. --text centra el text; --intrinsic centra els fills pel seu ample propi. */
:where(.ia-l-center) {
    --ia-l-measure: var(--ia-l-measure-m);
    box-sizing: content-box;
    max-inline-size: var(--ia-l-measure);
    margin-inline: auto;
}
:where(.ia-l-center--measure-s) { --ia-l-measure: var(--ia-l-measure-s); }
:where(.ia-l-center--measure-m) { --ia-l-measure: var(--ia-l-measure-m); }
:where(.ia-l-center--measure-l) { --ia-l-measure: var(--ia-l-measure-l); }
:where(.ia-l-center--text) { text-align: center; }
:where(.ia-l-center--intrinsic) {
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* ── 7. Cobrir (hero) ────────────────────────────────────────────────────────────────────────────────────────
   Alçada mínima amb nom (mai 100vh a pèl: a mòbil, svh evita el salt de la barra del navegador). El fill
   .ia-l-cover__main queda centrat verticalment; la resta (eyebrow, peu) queda a dalt / a baix. Sense __main, tot
   el contingut queda centrat. El contingut que no hi cap fa créixer el bloc (min-, no height). */
:where(.ia-l-cover) {
    --ia-l-cover-h: 60vh;
    --ia-l-cover-pad: var(--ia-space-m, 1.5rem);
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-block-size: var(--ia-l-cover-h);
    padding-block: var(--ia-l-cover-pad);
    box-sizing: border-box;
}
:where(.ia-l-cover--h-s) { --ia-l-cover-h: 40vh; }
:where(.ia-l-cover--h-m) { --ia-l-cover-h: 60vh; }
:where(.ia-l-cover--h-l) { --ia-l-cover-h: 80vh; }
:where(.ia-l-cover--h-full) { --ia-l-cover-h: 100vh; }
@supports (min-block-size: 1svh) {
    :where(.ia-l-cover) { --ia-l-cover-h: 60svh; }
    :where(.ia-l-cover--h-s) { --ia-l-cover-h: 40svh; }
    :where(.ia-l-cover--h-m) { --ia-l-cover-h: 60svh; }
    :where(.ia-l-cover--h-l) { --ia-l-cover-h: 80svh; }
    :where(.ia-l-cover--h-full) { --ia-l-cover-h: 100svh; }
}
:where(.ia-l-cover--pad-0) { --ia-l-cover-pad: 0px; }
:where(.ia-l-cover--pad-s) { --ia-l-cover-pad: var(--ia-space-s, 1rem); }
:where(.ia-l-cover--pad-m) { --ia-l-cover-pad: var(--ia-space-m, 1.5rem); }
:where(.ia-l-cover--pad-l) { --ia-l-cover-pad: var(--ia-space-l, 2rem); }
/* Els marges automàtics absorbeixen l'espai lliure abans que justify-content: __main al mig, la resta a les vores. */
:where(.ia-l-cover) > .ia-l-cover__main { margin-block: auto; }

/* ── 8. Marc de mitjà ────────────────────────────────────────────────────────────────────────────────────────
   Proporció fixa amb nom; la imatge o el vídeo de dins omple el marc retallant (object-fit: cover). La posició
   del retall la posa el mòdul (object-position). Una <picture> de dins també omple. */
:where(.ia-l-frame) {
    --ia-l-ratio: 16 / 9;
    aspect-ratio: var(--ia-l-ratio);
    overflow: hidden;
    position: relative;
}
:where(.ia-l-frame--ratio-16x9) { --ia-l-ratio: 16 / 9; }
:where(.ia-l-frame--ratio-21x9) { --ia-l-ratio: 21 / 9; }
:where(.ia-l-frame--ratio-4x3) { --ia-l-ratio: 4 / 3; }
:where(.ia-l-frame--ratio-3x2) { --ia-l-ratio: 3 / 2; }
:where(.ia-l-frame--ratio-1x1) { --ia-l-ratio: 1 / 1; }
:where(.ia-l-frame--ratio-3x4) { --ia-l-ratio: 3 / 4; }
/* Especificitat 0,1,1 (segona excepció de la regla 3): ha de guanyar `img, picture, svg, video { height: auto }` del
   tema (main.css, 0,0,1); el CSS del mòdul (0,2,0) hi continua passant per sobre. */
.ia-l-frame > img,
.ia-l-frame > video,
.ia-l-frame > iframe,
.ia-l-frame > picture,
.ia-l-frame > picture > img {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
}
