/* =========================================================================
   03-primitives.css — @layer primitives
   Contenitori, scala tipografica, materiali (filetto illuminato, lente,
   grana, luce ambientale), sistema placeholder, reveal.
   Nessun colore letterale: solo token.
   ========================================================================= */

@layer primitives {
  /* ====================================================================== */
  /* 1. Contenitori e sezioni                                               */
  /* ====================================================================== */

  .container {
    width: var(--page);
    margin-inline: auto;
  }

  /* L'alternanza di misura e' cio' che rende un impaginato editoriale invece
     che una lista di sezioni: la maggioranza a 1180, una sola a 1400 per
     respiro, una o due a 720 che sono il momento di lettura. */
  .container[data-w="wide"] {
    width: var(--page-wide);
  }

  .container[data-w="narrow"] {
    width: var(--page-narrow);
  }

  .section {
    position: relative;
    isolation: isolate;
    padding-block: var(--section-y);
  }

  .section[data-y="sm"] {
    padding-block: var(--section-y-sm);
  }

  .section[data-y="lg"] {
    padding-block: var(--section-y-lg);
  }

  /* L'ultima sezione della pagina non finisce mai sotto la dock fissa */
  .section[data-y="dock"] {
    padding-block: var(--section-y-lg) calc(var(--section-y) + var(--dock-safe));
  }

  /* Luce ambientale: una sola sorgente per sezione, mai due. Picco <=10% per
     l'ambra, <=6% per il bianco, raggio >=60% della larghezza, cosi' il bordo
     dell'alone non e' mai percepibile. */
  .section[data-ambient]::before {
    position: absolute;
    z-index: var(--z-decor);
    inset: 0;
    content: "";
    pointer-events: none;
  }

  .section[data-ambient="tl"]::before {
    background: var(--ambient-1);
  }

  .section[data-ambient="top"]::before {
    background: var(--ambient-2);
  }

  .section[data-ambient="tr"]::before {
    background: var(--ambient-3);
  }

  .section[data-ambient="cool"]::before {
    background: var(--ambient-4);
  }

  .section > .container {
    position: relative;
    z-index: var(--z-content);
  }

  /* ====================================================================== */
  /* 2. Grana                                                               */
  /* ====================================================================== */

  /* Strato unico a livello pagina: attraversa i confini di sezione ed e' cio'
     che fa leggere la pagina come un unico stampato invece che come una pila
     di blocchi. Costo: una tile 160x160 in data-URI, zero richieste di rete. */
  body::after {
    position: fixed;
    z-index: var(--z-grain);
    inset: 0;
    background-image: var(--grain-url);
    background-repeat: repeat;
    background-size: var(--grain-size) var(--grain-size);
    content: "";
    mix-blend-mode: var(--grain-blend-page);
    opacity: var(--grain-op-page);
    pointer-events: none;
  }

  .has-grain {
    position: relative;
    isolation: isolate;
  }

  .has-grain::after {
    position: absolute;
    z-index: var(--z-decor);
    inset: 0;
    background-image: var(--grain-url);
    background-size: var(--grain-size) var(--grain-size);
    content: "";
    mix-blend-mode: var(--grain-blend-local);
    opacity: var(--grain-op-dark);
    pointer-events: none;
  }

  @media (prefers-reduced-transparency: reduce) {
    body::after,
    .has-grain::after {
      display: none;
    }
  }

  /* ====================================================================== */
  /* 3. Scala tipografica                                                   */
  /* ====================================================================== */

  /* opsz resta automatico: il browser lo mappa alla dimensione realmente
     renderizzata, che e' esattamente il comportamento voluto.
     font-variation-settings nomina solo SOFT e WONK, quindi non lo tocca. */
  .u-display-xl,
  .u-display-l,
  .u-display-m,
  .u-h1,
  .u-h2,
  .u-h3,
  .u-h4,
  .u-quote,
  .u-metric-xl,
  .u-metric-l,
  .u-metric-m {
    font-family: var(--display);
    font-optical-sizing: auto;
    font-variation-settings: "SOFT" var(--fv-soft, 0), "WONK" var(--fv-wonk, 0);
    text-wrap: balance;
  }

  .u-display-xl {
    max-width: 12ch;
    font-size: var(--fs-display-xl);
    font-weight: 780;
    line-height: var(--lh-display-xl);
    letter-spacing: var(--tr-display-xl);
  }

  .u-display-l {
    max-width: 14ch;
    font-size: var(--fs-display-l);
    font-weight: 760;
    line-height: var(--lh-display);
    letter-spacing: var(--tr-display-l);
  }

  .u-display-m {
    max-width: 16ch;
    font-size: var(--fs-display-m);
    font-weight: 740;
    line-height: var(--lh-display);
    letter-spacing: var(--tr-display-m);
  }

  /* Solo i due display grandi possono portare WONK 1: le code storte di g, y e
     j scaldano il titolo. Su un paragrafo sarebbero una firma fuori posto. */
  .u-display-xl,
  .u-display-l {
    --fv-wonk: var(--fv-wonk-display, 1);
  }

  .u-h1 {
    max-width: 18ch;
    font-size: var(--fs-h1);
    font-weight: 720;
    line-height: var(--lh-h1);
    letter-spacing: var(--tr-h1);
  }

  .u-h2 {
    max-width: 20ch;
    font-size: var(--fs-h2);
    font-weight: 700;
    line-height: var(--lh-h2);
    letter-spacing: var(--tr-h2);
  }

  .u-h3 {
    max-width: 24ch;
    font-size: var(--fs-h3);
    font-weight: var(--fw-h3, 680);
    line-height: var(--lh-h3);
    letter-spacing: var(--tr-h3);
  }

  .u-h4 {
    max-width: 28ch;
    font-size: var(--fs-h4);
    font-weight: var(--fw-h4, 640);
    line-height: var(--lh-h4);
    letter-spacing: var(--tr-h4);
  }

  /* WONK 0 su h1-h4: sono struttura, non firma */
  .u-h1,
  .u-h2,
  .u-h3,
  .u-h4 {
    --fv-wonk: 0;
  }

  .u-quote {
    --fv-wonk: 1;
    max-width: 24ch;
    font-size: var(--fs-h2);
    font-weight: 700;
    line-height: var(--lh-quote);
    letter-spacing: var(--tr-h2);
  }

  .u-lead,
  .u-body-l,
  .u-body,
  .u-body-s,
  .u-caption,
  .u-micro {
    font-family: var(--body);
    text-wrap: pretty;
  }

  /* Calibrazione delle misure di riga. L'unita' ch e' la larghezza dello
     zero, che in Inter vale circa .6em, mentre un carattere medio di prosa
     ne vale circa .5em: una max-width in ch rende quindi circa il 25 per
     cento di caratteri in piu' di quanti il numero suggerisca. Misurato
     sulla pagina con le rect di Range: 68ch = 86 caratteri reali, cioe'
     fuori dalla banda comoda 45-75. I valori qui sotto sono gia' corretti
     per quel fattore e vanno letti come "circa 70 caratteri al cap". Se li
     rialzi pensando in caratteri, li stai rialzando del 25 per cento. */
  .u-lead {
    max-width: 50ch;
    font-size: var(--fs-lead);
    font-weight: 400;
    line-height: var(--lh-lead);
    letter-spacing: -.006em;
  }

  .u-body-l {
    max-width: 56ch;
    font-size: var(--fs-body-l);
    font-weight: 400;
    line-height: var(--lh-body);
  }

  .u-body {
    max-width: 57ch;
    font-size: var(--fs-body);
    font-weight: 400;
    line-height: var(--lh-body);
  }

  .u-body-s {
    max-width: 58ch;
    font-size: var(--fs-body-s);
    font-weight: 400;
    line-height: var(--lh-small);
    letter-spacing: .002em;
  }

  .u-caption {
    max-width: 50ch;
    font-size: var(--fs-caption);
    font-weight: 450;
    line-height: var(--lh-small);
    letter-spacing: .005em;
  }

  .u-micro {
    max-width: 50ch;
    font-size: var(--fs-micro);
    font-weight: 500;
    line-height: var(--lh-small);
    letter-spacing: .010em;
  }

  /* 12px e' il minimo assoluto renderizzato: sotto, con questo tracking, la
     label smette di essere leggibile e diventa decorazione. */
  .u-label {
    max-width: 40ch;
    font-family: var(--body);
    font-size: var(--fs-label);
    font-weight: 700;
    line-height: var(--lh-label);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }

  /* I numeri si leggono come dato: tabellari, mai WONK. */
  .u-metric-xl,
  .u-metric-l,
  .u-metric-m,
  .u-metric-s {
    --fv-wonk: 0;
    font-variant-numeric: tabular-nums;
  }

  .u-metric-xl {
    font-size: var(--fs-metric-xl);
    font-weight: 800;
    line-height: .92;
    letter-spacing: -.050em;
  }

  .u-metric-l {
    font-size: var(--fs-metric-l);
    font-weight: 780;
    line-height: .95;
    letter-spacing: -.040em;
  }

  .u-metric-m {
    font-size: var(--fs-metric-m);
    font-weight: 760;
    line-height: 1.00;
    letter-spacing: -.030em;
  }

  /* --u-metric-s e' l'unica della famiglia in Inter: a 18px un numero deve
     leggersi come dato, non come firma. Coerente con la regola delle due
     famiglie dichiarata in 01-tokens.css. */
  .u-metric-s {
    font-family: var(--body);
    font-size: var(--fs-metric-s);
    font-weight: 700;
    line-height: 1.20;
    letter-spacing: -.010em;
  }

  /* Colori di testo, mappati sul contratto della skin */
  .u-ink-1 { color: var(--ink-1); }
  .u-ink-2 { color: var(--ink-2); }
  .u-ink-3 { color: var(--ink-3); }
  .u-ink-4 { color: var(--ink-4); }
  .u-accent { color: var(--accent-text); }

  /* Misura di riga. Il limite comodo per Inter e' 45-75 caratteri: sopra i
     75 l'occhio perde la riga nel ritorno a capo. Le misure qui sotto sono
     scese di 4-8ch proprio per restare dentro quel limite anche a 1440. */
  .u-measure { max-width: 52ch; }
  .u-measure-short { max-width: 40ch; }

  em {
    color: var(--accent-text);
    font-style: normal;
  }

  /* ====================================================================== */
  /* 4. Accessibilita'                                                      */
  /* ====================================================================== */

  .sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
  }

  .skip-link {
    position: fixed;
    z-index: var(--z-skip);
    top: 12px;
    left: 12px;
    padding: 10px 14px;
    color: var(--ink);
    background: var(--amber);
    font-weight: 800;
    text-decoration: none;
    transform: translateY(-160%);
    transition: transform var(--dur-2) var(--ease-out);
  }

  .skip-link:focus {
    --focus-ring: var(--ink);
    transform: translateY(0);
  }

  /* ====================================================================== */
  /* 5. Il filetto illuminato                                               */
  /* ====================================================================== */

  /* Doppio background con background-clip: il gradiente sta sul solo bordo da
     1px. L'occhio lo legge come luce radente su uno spigolo, non come lamina
     d'oro, perche' la superficie interna resta un colore pieno e neutro.
     E' la distinzione fra ambra-luce e ambra-materiale. */
  .edge-lit {
    --edge-a: .38;
    border: 1px solid transparent;
    border-radius: var(--card-radius);
    background-image:
      linear-gradient(var(--edge-surface), var(--edge-surface)),
      linear-gradient(158deg,
        rgb(var(--edge-rgb) / var(--edge-a)) 0%,
        rgb(var(--white-rgb) / .10) 20%,
        rgb(var(--white-rgb) / 0) 46%,
        rgb(var(--white-rgb) / .05) 74%,
        rgb(var(--edge-rgb) / calc(var(--edge-a) * .5)) 100%);
    background-clip: padding-box, border-box;
    background-origin: border-box;
    box-shadow: var(--card-elev);
    /* In uscita si torna piu' in fretta che in entrata */
    transition:
      --edge-a var(--dur-exit) var(--ease-exit),
      box-shadow var(--dur-exit) var(--ease-exit),
      transform var(--dur-exit) var(--ease-exit);
  }

  @media (hover: hover) and (pointer: fine) {
    .edge-lit:is(:hover, :focus-within) {
      --edge-a: .68;
      --edge-surface: var(--card-surface-2);
      box-shadow: var(--card-elev-hover);
      transform: translateY(var(--lift-edge, -3px));
      transition:
        --edge-a var(--dur-3) var(--ease-out),
        box-shadow var(--dur-3) var(--ease-out),
        transform var(--dur-3) var(--ease-out);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    /* Il cambio di bordo e di superficie resta: porta informazione.
       Sparisce solo lo spostamento. */
    .edge-lit:is(:hover, :focus-within) {
      transform: none;
    }
  }

  /* ====================================================================== */
  /* 6. La lente                                                            */
  /* ====================================================================== */

  /* Il cerchio ricorreva gia' tre volte nel codice senza essere codificato.
     Qui diventa motivo di brand: sempre parzialmente fuori dal proprio
     contenitore, sempre dietro il contenuto, mai piu' di 3 per pagina. */
  .lens {
    position: absolute;
    z-index: var(--z-decor);
    width: var(--lens-d);
    aspect-ratio: 1;
    border: 1px solid var(--hair-accent);
    border-radius: 50%;
    pointer-events: none;
  }

  .lens[data-lens="tr"] {
    top: calc(var(--lens-d) / -3);
    right: calc(var(--lens-d) / -4);
  }

  .lens[data-lens="br"] {
    right: calc(var(--lens-d) / -4);
    bottom: calc(var(--lens-d) / -3);
  }

  .lens[data-lens="bl"] {
    bottom: calc(var(--lens-d) / -3);
    left: calc(var(--lens-d) / -4);
  }

  .lens[data-lens="cl"] {
    top: 50%;
    left: calc(var(--lens-d) / -2);
    translate: 0 -50%;
  }

  /* ====================================================================== */
  /* 7. Sistema placeholder                                                 */
  /* ====================================================================== */

  /* Meccanismo unico per tutti e cinque: lo stato e' dichiarato da
     data-ph-empty sul <figure>. Sostituire un placeholder e' quindi sempre la
     stessa singola istruzione: inserisci l'<img> come primo figlio e togli
     data-ph-empty. Nessun JS, nessun onerror, nessun percorso rotto. */
  .ph {
    position: relative;
    margin: 0;
    overflow: hidden;
    isolation: isolate;
  }

  .ph > img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }

  /* Lo stato vuoto non e' mai un rettangolo grigio: fondo di card, un
     tratteggio appena percettibile e la luce ambientale della sezione.
     Legge come una scena illuminata in attesa del soggetto. */
  .ph[data-ph-empty] {
    background-color: var(--ph-empty-bg);
    background-image: var(--ph-hatch), var(--ambient-1);
  }

  .ph[data-ph-empty]::after {
    position: absolute;
    z-index: var(--z-content);
    top: var(--s-4);
    right: var(--s-4);
    color: var(--ink-4);
    font: 700 var(--fs-label) / 1.2 var(--body);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    content: attr(data-ph-label);
  }

  /* La caption e' un <figcaption> statico fuori dal <figure>: in posizione
     assoluta in basso finirebbe sotto la dock fissa. */
  .ph-caption {
    margin-top: var(--s-3);
    color: var(--ink-4);
    font: 700 var(--fs-label) / 1.3 var(--body);
    letter-spacing: .10em;
    text-transform: uppercase;
  }

  /* --- 7.1 Foto hero, sfumata ------------------------------------------ */

  .ph-hero {
    position: absolute;
    z-index: var(--z-base);
    inset: 0;
    background: var(--page-bg);
  }

  .ph-hero > img {
    aspect-ratio: 16 / 9;
    object-position: 50% 42%;
    /* Desaturazione: resta il 28% di colore, cosi' l'ambra e' l'unico accento
       cromatico della scena. */
    filter: var(--hero-photo-filter);
    /* La foto contribuisce solo luminanza, mai una tinta concorrente */
    mix-blend-mode: var(--hero-photo-blend);
    /* Dissolve prima di raggiungere la colonna dell'H1 */
    -webkit-mask-image: var(--mask-hero);
    mask-image: var(--mask-hero);
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
  }

  /* Le hero con foto reali conservano la scena per intero: il contrasto del
     testo e' affidato allo scrim, mentre la dissolvenza verticale le lega al
     fondo della pagina. */
  .ph-hero[data-photo-focus] > img {
    -webkit-mask-image: linear-gradient(to bottom, rgb(var(--black-rgb) / 0) 0%, rgb(var(--black-rgb)) 12%, rgb(var(--black-rgb)) 76%, rgb(var(--black-rgb) / 0) 100%);
    mask-image: linear-gradient(to bottom, rgb(var(--black-rgb) / 0) 0%, rgb(var(--black-rgb)) 12%, rgb(var(--black-rgb)) 76%, rgb(var(--black-rgb) / 0) 100%);
  }

  .ph-hero[data-photo-focus="portrait-immersive"] > img {
    width: min(64vw, 940px);
    margin-left: auto;
    object-position: 50% 27%;
    transform: translateX(30%);
  }

  .ph-hero[data-photo-focus="training-wide"] > img {
    object-position: 43% 50%;
  }

  /* Stato vuoto: non un rettangolo grigio, ma una scena illuminata in attesa
     del soggetto. Fondo di card, ambient, grana e la lente a cavallo del bordo. */
  .ph-hero[data-ph-empty]::after {
    top: auto;
    right: var(--gutter);
    bottom: var(--s-6);
  }

  .hero-scrim {
    position: absolute;
    z-index: var(--z-decor);
    inset: 0;
    background: var(--hero-scrim);
    pointer-events: none;
  }

  /* Parallasse: dove il browser sa legare un'animazione allo scroll lo fa da
     solo, senza un listener. scale 1.06 garantisce che la traslazione non
     scopra mai un bordo; oltre i 90px di corsa la foto scivolerebbe via dal
     testo, per questo l'intervallo e' cosi' corto. */
  @supports (animation-timeline: view()) {
    .ph-hero > img {
      animation: hero-parallax linear both;
      animation-range: entry 0% cover 100%;
      animation-timeline: view();
      scale: 1.06;
    }

    @keyframes hero-parallax {
      from { translate: 0 -3%; }
      to { translate: 0 5%; }
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .ph-hero > img {
      animation: none;
      scale: 1;
      translate: 0;
    }
  }

  @media (max-width: 780px) {
    .ph-hero > img {
      aspect-ratio: 4 / 5;
      object-position: 50% 35%;
      -webkit-mask-image: var(--mask-hero-mobile);
      mask-image: var(--mask-hero-mobile);
    }

    .hero-scrim {
      background: var(--hero-scrim-mobile);
    }

    .ph-hero[data-photo-focus="portrait-immersive"] > img {
      width: 100%;
      margin-left: 0;
      object-position: 50% 24%;
      transform: none;
    }

    .ph-hero[data-photo-focus="training-wide"] > img {
      object-position: 43% 50%;
    }
  }

  /* --- 7.2 Ritratto editoriale ----------------------------------------- */

  .ph-portrait {
    --edge-surface: var(--card-surface);
    aspect-ratio: 4 / 5;
  }

  .ph-portrait > img {
    object-position: 50% 28%;
    filter: grayscale(.35) contrast(1.04);
  }

  .ph-portrait[data-photo-focus="credential"] > img {
    object-position: 59% 48%;
    filter: grayscale(.12) contrast(1.03) saturate(.92);
  }

  /* Stato vuoto: cornice d'archivio con crocini di registro, non un buco */
  .ph-portrait[data-ph-empty]::before {
    position: absolute;
    inset: 16px;
    background:
      linear-gradient(var(--hair-accent), var(--hair-accent)) 0 0 / 14px 1px no-repeat,
      linear-gradient(var(--hair-accent), var(--hair-accent)) 0 0 / 1px 14px no-repeat,
      linear-gradient(var(--hair-accent), var(--hair-accent)) 100% 0 / 14px 1px no-repeat,
      linear-gradient(var(--hair-accent), var(--hair-accent)) 100% 0 / 1px 14px no-repeat,
      linear-gradient(var(--hair-accent), var(--hair-accent)) 0 100% / 14px 1px no-repeat,
      linear-gradient(var(--hair-accent), var(--hair-accent)) 0 100% / 1px 14px no-repeat,
      linear-gradient(var(--hair-accent), var(--hair-accent)) 100% 100% / 14px 1px no-repeat,
      linear-gradient(var(--hair-accent), var(--hair-accent)) 100% 100% / 1px 14px no-repeat;
    content: "";
    pointer-events: none;
  }

  .portrait-note {
    position: absolute;
    z-index: var(--z-content);
    top: var(--s-5);
    left: var(--s-5);
    max-width: 26ch;
    padding: var(--s-4) var(--s-5);
    border-left: 3px solid var(--amber);
    color: var(--on-light-1);
    background: rgb(var(--white-rgb) / .94);
    box-shadow: var(--elev-3);
    backdrop-filter: blur(8px) saturate(1.1);
    transform: rotate(-1.2deg);
  }

  .portrait-note span {
    display: block;
    color: var(--amber-text);
    font: 700 var(--fs-label) / 1.2 var(--body);
    letter-spacing: var(--track-label);
    text-transform: uppercase;
  }

  .portrait-note strong {
    display: block;
    margin-top: var(--s-2);
    font-family: var(--display);
    font-optical-sizing: auto;
    font-size: var(--fs-h4);
    font-weight: 700;
    line-height: 1.2;
    /* SOFT 30 ammorbidisce le terminazioni: e' la nota scritta a mano */
    font-variation-settings: "SOFT" 30, "WONK" 0;
  }

  @media (max-width: 680px) {
    .portrait-note {
      top: auto;
      right: var(--s-4);
      bottom: var(--s-4);
      left: var(--s-4);
      max-width: none;
      padding: var(--s-3) var(--s-4);
      transform: none;
    }

    /* La nota resta Fraunces, quindi resta sulla scala display: prima
       scendeva a --fs-body-l, cioe' un token di CORPO, e si leggeva a 17px.
       Un serif editoriale a 17px in grassetto su un telefono e' esattamente
       la resa che il sistema deve evitare. Il box qui e' a tutta larghezza,
       quindi --fs-h4 (20px) ci sta senza andare a capo in piu'. */
    .portrait-note strong {
      font-size: var(--fs-h4);
      font-weight: var(--fw-h4, 700);
    }
  }

  /* --- 7.3 Visual dei casi studio -------------------------------------- */

  .ph-case {
    --edge-surface: var(--card-surface);
    margin-bottom: var(--s-5);
    aspect-ratio: 16 / 10;
  }

  .ph-case > img {
    filter: grayscale(.55) contrast(1.05);
  }

  /* Stato vuoto: uno schizzo di dati costruito sui numeri reali del caso.
     Il velo ambra sotto la curva codifica un valore, quindi e' inchiostro-dato
     e non decorazione. Il tratto resta ambra piena e piatta. */
  .case-sketch {
    display: block;
    width: 100%;
    height: 100%;
    /* Il tratto e il velo ereditano da qui: su carta l'ambra piena sarebbe a
       1,9:1 e il grafico smetterebbe di essere leggibile. */
    color: var(--accent-fill);
  }

  /* ====================================================================== */
  /* 8. Reveal                                                              */
  /* ====================================================================== */

  /* Quattro varianti guidate da attributo. Spostamento mai oltre 16px,
     nessuno scale oltre .98 -> 1, nessuna rotazione. */
  .html-has-js [data-reveal] {
    will-change: opacity, transform;
  }

  .html-has-js [data-reveal="fade"] {
    opacity: 0;
    transition: opacity var(--dur-4) var(--ease-entrance) var(--reveal-delay, 0ms);
  }

  .html-has-js [data-reveal="rise"] {
    opacity: 0;
    transform: translateY(14px);
    transition:
      opacity var(--dur-4) var(--ease-entrance) var(--reveal-delay, 0ms),
      transform 560ms var(--ease-entrance) var(--reveal-delay, 0ms);
  }

  .html-has-js [data-reveal="rule"] {
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 640ms var(--ease-out) var(--reveal-delay, 0ms);
  }

  .html-has-js [data-reveal="mask"] {
    clip-path: inset(0 100% 0 0);
    transition: clip-path 720ms var(--ease-out) var(--reveal-delay, 0ms);
  }

  .html-has-js [data-reveal].is-visible {
    opacity: 1;
    clip-path: inset(0 0 0 0);
    transform: none;
  }

  @media (prefers-reduced-motion: reduce) {
    .html-has-js [data-reveal],
    .html-has-js [data-reveal].is-visible {
      --reveal-delay: 0ms;
      opacity: 1;
      clip-path: none;
      transform: none;
      transition: none;
      will-change: auto;
    }
  }
}
