/* ═══════════════════════════════════════════════════════════
   ROMANOVSKIS.XYZ — v3 · "Index & Stage", versione essenziale (5 ott 2026)
   Sopra style.css. Due livelli di portfolio (siti per aziende, progetti AI),
   ognuno con un indice e un palco fisso che mostra ciò che stai per aprire.
   Navigazione: pathbar.css. Inchiostro nel blocco contatti: js/ink.js.
═══════════════════════════════════════════════════════════ */

/* ── Hero foundation ─────────────────────────────────────── */
.hero-v3 { min-height: 0; padding-bottom: 0; }
.hero-v3 h1 { font-size: clamp(2.5rem, 5.2vw, 5.6rem); max-width: 15em; margin: 0 0 26px; text-wrap: balance; }
.hero-v3 .lead { max-width: 36em; margin-bottom: 30px; }
.idx-intro { display: flex; align-items: baseline; justify-content: space-between; gap: 24px; margin-bottom: 18px; }
.idx-intro h2 { font-weight: 500; }
.idx-intro p { font-size: 14px; color: var(--muted); max-width: 46em; text-align: right; }

/* ── Stage (palco dell'indice) ───────────────────────────── */
.stage {
  position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius); overflow: hidden;
  background: var(--card); isolation: isolate; text-align: left; padding: 0; border: 0; color: var(--fg);
}
/* le schermate dei siti sono 16:9: entrano intere. Le immagini dei progetti AI non si tagliano mai */
.stage img, .stage video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; visibility: hidden; transition: opacity 0.6s var(--ease), visibility 0s linear 0.6s; }
.index-ai .stage img { object-fit: contain; }
/* copertine video dei progetti AI (Mythos, Wisdom Council): riempiono il palco, il video non lascia bande */
.index-ai .stage video { object-fit: cover; }
.index-web .stage img { object-fit: contain; }
.stage img.on, .stage video.on { opacity: 1; visibility: visible; transition: opacity 0.6s var(--ease), visibility 0s; }
.stage-label {
  position: absolute; left: 14px; bottom: 14px; z-index: 2; display: inline-flex; align-items: center; gap: 12px;
  padding: 8px 12px 8px 10px; border-radius: 999px; background: var(--bg);
  font-size: 12px; font-weight: 500; max-width: calc(100% - 28px);
}
.stage-label .k { font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; color: var(--muted); }
.stage-label .l { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Index ───────────────────────────────────────────────── */
.index { display: grid; grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); gap: 48px; align-items: start; }
.idx-list { border-top: 1px solid var(--fg); }
.row {
  display: grid; grid-template-columns: 36px 1fr 56px 36px; align-items: center; gap: 4px 16px;
  padding: 20px 0; border-bottom: 1px solid var(--line); position: relative;
}
.row .i { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.row .n { font-family: var(--display); font-weight: 600; font-size: clamp(1.25rem, 2vw, 1.8rem); letter-spacing: -0.035em; line-height: 1.05; }
.row .c { grid-column: 2; grid-row: 2; font-size: 13px; color: var(--muted); line-height: 1.4; }
.row .n { grid-column: 2; }
.row .y { grid-column: 3; grid-row: 1 / 3; }
.row .a { grid-column: 4; grid-row: 1 / 3; }
.row .i { grid-row: 1 / 3; }
.row .y { font-family: var(--mono); font-size: 11px; color: var(--muted); text-align: right; }
.row.ext .y { color: var(--green-text); }
.row .a { width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--line); display: grid; place-items: center; transition: background 0.3s, color 0.3s, border-color 0.3s; }
.row:hover .a { background: var(--fg); color: var(--bg); border-color: var(--fg); }
/* la riga "accesa" segue il palco: solo dove il palco si vede */
@media (min-width: 861px) { .row.on .a { background: var(--fg); color: var(--bg); border-color: var(--fg); } }
.row .thumb { display: none; }
/* Partner credits have their own link, below the project link. */
.client-entry .row { border-bottom: 0; padding-bottom: 6px; }
.client-credit { margin: 0; padding: 0 0 16px 52px; border-bottom: 1px solid var(--line); font-size: 12px; line-height: 1.5; color: var(--muted); }
.client-credit a { display: inline-flex; align-items: center; gap: 4px; min-height: 24px; color: var(--fg); text-decoration: underline; text-underline-offset: 3px; }
.client-credit a:hover { text-decoration-thickness: 2px; }
.idx-stage-wrap { position: sticky; top: calc(var(--pb-h, 56px) + 32px); }
.idx-stage .stage-label .l { max-width: 24ch; }

/* ── How it works: accordi prima di partire ──────────────── */
.terms { display: grid; grid-template-columns: 1fr 2fr; gap: 32px; margin-top: 56px; padding-top: 28px; border-top: 1px solid var(--fg); }
.terms-h { font-family: var(--display); font-weight: 600; font-size: clamp(1.4rem, 2.2vw, 1.9rem); letter-spacing: -0.03em; line-height: 1.1; }
.terms ol { counter-reset: t; }
.terms li { counter-increment: t; display: grid; grid-template-columns: 44px 1fr; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--line); color: var(--muted); font-size: 15px; max-width: 46em; }
.terms li:first-child { padding-top: 4px; }
.terms li::before { content: counter(t, decimal-leading-zero); font-family: var(--mono); font-size: 11px; color: var(--muted); padding-top: 4px; }


/* ── Contatto: grigio scuro sfumato + inchiostro (js/ink.js) ── */
.contact {
  position: relative; isolation: isolate; overflow: hidden;
  /* quasi nero, pieno, senza sfumatura: di poco più chiaro della scia nera di js/ink.js (richiesta AD) */
  background: #0f0f0e;
}
.ink-host > .ink-canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1; pointer-events: none; }
.contact .eyebrow { color: rgba(245,244,240,0.62); }
.contact .eyebrow::before { background: var(--bg); }
.contact :focus-visible { outline-color: var(--bg); }
.contact-close { margin-top: clamp(72px, 12vh, 140px); padding-top: 20px; border-top: 1px solid rgba(245,244,240,0.14); font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(245,244,240,0.6); }

/* ── Mobile ──────────────────────────────────────────────── */
@media (max-width: 1100px) {
  .index { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: 32px; }
  .row { grid-template-columns: 36px 1fr 56px 36px; }
  .row .c { grid-column: 2; grid-row: 2; }
  .row .n { grid-column: 2; }
  .row .y { grid-column: 3; grid-row: 1 / 3; }
  .row .a { grid-column: 4; grid-row: 1 / 3; }
  .row .i { grid-row: 1 / 3; }
  .terms { grid-template-columns: 1fr; gap: 16px; }
}
@media (max-width: 860px) {
  .index { grid-template-columns: 1fr; }
  .idx-stage-wrap { display: none; }
  .row { grid-template-columns: 1fr 36px; grid-template-rows: auto auto auto; gap: 4px 16px; padding: 16px 0; }
  .row .thumb { display: block; grid-column: 1 / -1; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius-sm); margin-bottom: 10px; background: var(--card); }
  .index-ai .row .thumb { object-fit: contain; }
  .index-ai .row video.thumb { object-fit: cover; }
  .index-web .row .thumb { object-fit: contain; }
  .row .i { display: none; }
  .client-credit { padding-left: 0; }
  .row .n { grid-column: 1; grid-row: 2; }
  .row .c { grid-column: 1; grid-row: 3; }
  .row .y { display: none; }
  .row .a { grid-column: 2; grid-row: 2 / 4; align-self: center; }
  .idx-intro { flex-direction: column; gap: 8px; }
  .idx-intro p { text-align: left; }
  .terms li { grid-template-columns: 32px 1fr; font-size: 14.5px; }
}

@media (prefers-reduced-motion: reduce) { .stage img { transform: none; transition: opacity 0.3s; } }

/* anteprime statiche (?static=<id>): le altre sezioni sono [hidden], anche se hanno un display proprio */
.static-shot [hidden] { display: none !important; }
.static-shot .section { padding-top: 48px; }
.static-shot .contact { margin-top: 0; }

/* ═══════════════════════════════════════════════════════════
   LORE · typography and code, here and there (6 ott 2026)
   The page treated as a proof that is also source: the typographer's reference
   marks (¹ § ¶) each do a real job, and the web's own marks (h1, https://) name
   what is there. Red still means only "you are here" (see .mark-sig in pathbar.css).
   Motion: transform/opacity only, off under reduced motion. Nothing here takes clicks
   except the ¶ links.
═══════════════════════════════════════════════════════════ */

/* ── Proof: the hero heading as a specimen (hover devices, 1280px and wider) ──
   Chip in typesetter notation: element, face, size/leading, tracking in 1/1000 em
   (js rewrites data-spec on resize). Ticks in the margin at the first line's
   cap height, x-height and baseline. Inter Tight file: ascender 0.96875,
   descender 0.24121, line-height 1 -> baseline 0.8638em, cap 0.7275em, x 0.5459em. */
.hero-v3 h1 { position: relative; }
.proof { display: none; }
@media (hover: hover) and (min-width: 1280px) {
  html.js .proof { display: block; position: absolute; inset: 0; pointer-events: none; -webkit-user-select: none; user-select: none; }
  .proof::before {
    content: 'h1 \00B7  ' attr(data-spec); /* two spaces: the first one ends the escape */
    position: absolute; left: 0; bottom: calc(100% + 12px);
    padding: 3px 7px; border-radius: 4px; background: var(--fg); color: var(--bg);
    font: 400 10px/14px var(--mono); letter-spacing: 0.02em; white-space: nowrap;
    opacity: 0; transform: translateY(4px);
    transition: opacity 0.2s, transform 0.35s var(--ease);
  }
  .proof i { position: absolute; left: 0; top: 0.8638em; width: 0; height: 0; }
  .proof i[data-k="cap"] { top: 0.1363em; }
  .proof i[data-k="x"] { top: 0.3179em; }
  .proof i::before {
    content: ''; position: absolute; right: 6px; top: -0.5px; width: 12px; height: 1px; background: var(--muted);
    transform: scaleX(0); transform-origin: right center; transition: transform 0.4s var(--ease);
  }
  .proof i::after {
    content: attr(data-k); position: absolute; right: 24px; top: -6px;
    font: 400 10px/12px var(--mono); letter-spacing: 0.04em; color: var(--muted); white-space: nowrap;
    opacity: 0; transition: opacity 0.2s;
  }
  .proof i[data-k="x"]::before { transition-delay: 0.04s; }
  .proof i[data-k="base"]::before { transition-delay: 0.08s; }
  .hero-v3 h1:hover .proof::before { opacity: 1; transform: none; }
  .hero-v3 h1:hover .proof i::before { transform: none; }
  .hero-v3 h1:hover .proof i::after { opacity: 1; transition-delay: 0.12s; }
}

/* ── Footnote: a superior figure in the lead, the note at the foot of the hero ──
   ¹ is the font's own superior figure (U+00B9): Google Fonts strips 'sups', and a
   synthesised <sup> would be too light and open the line spacing. Not a link: a 1em
   target would fall under 44px; screen readers get "Note:" in front of the note. */
.fn-ref { margin-left: 0.04em; color: var(--fg); }
.fns { display: grid; gap: 4px; margin-top: 24px; }
.fn { display: flex; gap: 6px; max-width: 52em; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.fn-n { min-width: 0.6em; }
.fn-n { flex: none; color: var(--fg); }

/* ── ¶ permalinks (js adds them): hung in the left margin beside the section label ──
   Docs heading permalink (Sphinx, Django) set as hanging punctuation: the text edge stays
   clean. 44px tall and as wide as the gutter; only where the gutter is at least 44px. */
.has-pilcrow { position: relative; }
.pilcrow { display: none; }
@media (hover: hover) and (min-width: 1100px) {
  .pilcrow {
    position: absolute; right: 100%; top: 50%; display: flex; align-items: center; justify-content: flex-end;
    width: var(--gutter); height: 44px; margin-top: -22px; padding-right: 12px; border-radius: 8px;
    font: 400 13px/1 var(--sans); letter-spacing: 0; text-transform: none; color: var(--muted);
    opacity: 0; transform: translateX(4px);
    transition: opacity 0.2s, transform 0.35s var(--ease), color 0.2s;
  }
  :is(.section-head, .idx-intro):hover .pilcrow, .pilcrow:focus-visible { opacity: 1; transform: none; }
  .pilcrow:hover { color: var(--fg); }
  .pilcrow:focus-visible { outline-offset: -4px; }
}
.pilcrow-ok { color: var(--fg); animation: pilcrow-ok 0.35s var(--ease); }
@keyframes pilcrow-ok { from { opacity: 0; transform: translateX(-6px); } }

/* ── Client stage: the label reads like an address bar (where the row goes) ── */
.index-web .stage-label .l { max-width: 36ch; font-family: var(--mono); font-size: 12px; font-weight: 400; letter-spacing: 0; }
.index-web .stage-label .l::before { content: 'https://'; color: var(--muted); }

/* ── "Agreed before we start" is a small agreement: its clauses carry the section sign ──
   No-break space keeps § and its figure together. Second line: alt text where supported. */
.terms li::before { content: '\00A7\00A0' counter(t); }
.terms li::before { content: '\00A7\00A0' counter(t) / 'Clause ' counter(t); }

/* ── Colophon: the closing line names its typefaces, each set in its own face ── */
.contact-close { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 10px 32px; }

/* ── Proofreading: no widows, balanced heads, arrows in the house stroke ──
   ↗ and → are in none of the Google Fonts subsets served here (wrong-font): svg instead. */
.lead, .section p, .service li, .terms li, .cs-side .desc, .cs-tabs small, .fn { text-wrap: pretty; }
.section h2, .section h3, .contact h2, .cs-side h2 { text-wrap: balance; }
.ico { flex: none; display: inline-block; vertical-align: -1px; }
.cs-nextp { gap: 8px; }
/* selection on the dark block was ink on near-black: invisible */
.contact ::selection { background: var(--bg); color: var(--fg); }

@media (prefers-reduced-motion: reduce) {
  .proof::before, .proof i::before, .proof i::after, .pilcrow { transition: none !important; }
  .pilcrow { transform: none; }
  .pilcrow-ok { animation: none; }
}
@media print { .proof, .pilcrow { display: none !important; } }

/* ── How it works: infografiche Three.js nelle card (js/process3d.js + js/process/*.js) ──
   Lo spazio è riservato subito (niente salti); senza JS o senza WebGL/CDN non esiste. */
.step-viz { position: relative; width: calc(100% + 24px); margin: -8px -12px 0; aspect-ratio: 4 / 3; pointer-events: none; }
.step-viz canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
html:not(.js) .step-viz, html.no-3d .step-viz { display: none; }
.has-3d .step { gap: 16px; }

/* ═══════════════════════════════════════════════════════════
   ABOUT · "Titoli di testa" (5 ott 2026, sostituisce .about / .about-copy / .about-art)
   Le vecchie regole non hanno più elementi (il markup usa solo classi .about-ot / .ot-*):
   cancellarle comunque, style.css righe 101-104 e v3.css righe 63-69 e 107-109.
   Risponde a "Who am I hiring?": titolo di testa (Web design, code and graphics by /
   Edgars | Romanovskis, il nome diviso dal filo rosso), la promessa, l'offerta con i bottoni.
   Duality è stampata sulla carta: fondo #F5F4F0 e bordi sfumati cotti nel file
   ASSET/painting/duality-paper.webp, quindi nessun blend, maschera o filtro a runtime.
   Stesso markup, tre composizioni:
   1. >= 1024px, base: ferma, tre colonne, Duality al centro come spina (sticky).
      Vale senza JS, con riduci movimento, sugli schermi bassi, con ?static=about e in stampa.
   2. >= 1024x560 con JS e movimento consentito: la scena si ferma sotto la Path Bar per
      1,8 schermi; la camera scende lungo il quadro e si sposta di lato (il filo rosso
      attraversa l'inquadratura), i titoli entrano ed escono di lato. Solo transform (js/about.js).
      Il layout è deciso qui, al primo disegno: il JS non cambia altezze.
   3. < 1024px: colonna centrata sul filo rosso, Edgars sopra il quadro e Romanovskis sotto;
      con JS i titoli scivolano di lato mentre entrano. Nessun blocco dello scroll.
   Il testo non tocca mai la colonna scura: misurata su duality.jpg, tra il 26% e il 95%
   dell'altezza resta entro 0,30 della larghezza dal filo rosso; i titoli stanno a 28px.
═══════════════════════════════════════════════════════════ */

#about.about-ot {
  --ot-pad: clamp(80px, 12vh, 160px);
  --ot-ink-2: #45443F;   /* testo secondario: 8,9:1 sulla carta, oltre 5:1 sulle velature del quadro */
  padding: var(--ot-pad) 0 0;
}
.static-shot #about.about-ot { padding-top: 48px; }

.ot { position: relative; }
@supports (overflow: clip) { .ot { overflow-x: clip; } }   /* clip, non hidden: non rompe lo sticky */
.ot-stage { position: relative; isolation: isolate; background: var(--bg); }

/* il riquadro ha sempre misure esplicite (width/height): spazio riservato prima del caricamento */
.ot-fig { position: relative; z-index: 0; margin: 0; pointer-events: none; }
.ot-fig img { width: 100%; height: 100%; object-fit: cover; }   /* riquadro 2:3 come il file: intera */
.ot-s1, .ot-shot { position: relative; z-index: 1; min-width: 0; }

.ot-title { font-weight: 400; }
.ot-credit {
  display: block; font-family: var(--mono); font-size: 11px; font-weight: 400; line-height: 1.5;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ot-ink-2);
}
.ot-first, .ot-last {
  display: block; font-family: var(--display); font-weight: 600; font-size: var(--ot-name, 3rem);
  letter-spacing: -0.045em; line-height: 1; white-space: nowrap;
}
.ot-sub { max-width: 22em; font-size: 16px; line-height: 1.5; color: var(--ot-ink-2); text-wrap: pretty; }
.ot-line {
  max-width: 14em; font-family: var(--display); font-weight: 600; font-size: var(--ot-line, 2rem);
  letter-spacing: -0.035em; line-height: 1.06; text-wrap: balance;
}
.ot-small { max-width: 30em; margin-top: 18px; font-size: 15px; line-height: 1.55; color: var(--ot-ink-2); text-wrap: pretty; }
.ot-cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
.ot-cta .btn { min-height: 44px; }
#about.ot-live [data-side], #about.ot-live .ot-fig { will-change: transform; }

/* ── 1. Desktop, composizione ferma: tre colonne, il quadro al centro ── */
@media (min-width: 1024px) {
  .ot {
    --ot-ws: min(34vw, 440px, calc((100vh - var(--pb-h) - 64px) / 1.5));
    --ot-col: calc(var(--ot-ws) + 32px);
    --ot-name: clamp(2.25rem, min(5vw, 12vh, calc((100vw - 2 * var(--gutter) - var(--ot-col) - 24px) / 13)), 6rem);
    --ot-line: clamp(1.75rem, 2.8vw, 3rem);
  }
  @supports (height: 100svh) {
    .ot { --ot-ws: min(34vw, 440px, calc((100svh - var(--pb-h) - 64px) / 1.5)); }
  }
  .ot-stage {
    display: grid; grid-template-columns: minmax(0, 1fr) var(--ot-col) minmax(0, 1fr);
    padding: 0 var(--gutter);
  }
  .ot-fig {
    grid-column: 2; grid-row: 1 / span 3; align-self: start; justify-self: center;
    position: sticky; top: max(calc(var(--pb-h) + 16px), calc(var(--pb-h) + (100vh - var(--pb-h) - var(--ot-ws) * 1.5) / 2));
    width: var(--ot-ws); height: calc(var(--ot-ws) * 1.5);
  }
  /* il nome: Edgars finisce e Romanovskis comincia ai due lati del quadro */
  .ot-s1 {
    grid-column: 1 / -1; grid-row: 1;
    display: grid; grid-template-columns: minmax(0, 1fr) var(--ot-col) minmax(0, 1fr);
    row-gap: 16px; padding-top: calc(var(--ot-ws) * 0.36);
  }
  .ot-title {
    grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) var(--ot-col) minmax(0, 1fr);
    row-gap: 14px; align-items: end;
  }
  .ot-credit { grid-column: 1; grid-row: 1; justify-self: end; text-align: right; }
  .ot-first { grid-column: 1; grid-row: 2; justify-self: end; }
  .ot-last { grid-column: 3; grid-row: 2; justify-self: start; }
  .ot-sub { grid-column: 3; justify-self: start; }
  .ot-shot { padding-top: clamp(64px, 14vh, 140px); }
  .ot-shot[data-shot="1"] { grid-column: 3; grid-row: 2; justify-self: start; }
  .ot-shot[data-shot="2"] { grid-column: 1; grid-row: 3; justify-self: end; padding-bottom: 8px; }
}

/* ── 2. Desktop, scena fissata (solo con JS e movimento consentito) ── */
@media screen and (min-width: 1024px) and (min-height: 560px) and (prefers-reduced-motion: no-preference) {
  /* i salti dalla Path Bar e ?at=about arrivano a scena già fissata, sull'inquadratura 1 */
  html.js body:not(.static-shot) #about.about-ot { scroll-margin-top: calc(-1 * var(--ot-pad) - 16px); }
  html.js body:not(.static-shot) .ot {
    --ot-h: calc(100vh - var(--pb-h));                                       /* altezza della scena sotto la barra */
    --ot-imgw: min(calc(var(--ot-h) * 0.7067), calc(75vw - 100px), 720px);   /* alto 1,06 scene; max 720: niente ingrandimento su schermi 1x */
    --ot-reach: calc(var(--ot-imgw) * 0.3 + 28px);                           /* dal filo rosso al bordo del testo */
    --ot-col: calc(var(--ot-reach) * 2);
    --ot-pan: 0.22;    /* spostamento laterale del quadro, in larghezze della scena (letto da js/about.js) */
    --ot-tilt: 0.16;   /* corsa verticale della camera, in altezze della scena (letto da js/about.js) */
    --ot-max: 40rem;
    --ot-line: clamp(1.75rem, 3vw, 3.2rem);
    height: calc(var(--ot-h) * 2.8);                                         /* 1 scena + 1,8 schermi di corsa */
  }
  @supports (height: 100svh) {
    html.js body:not(.static-shot) .ot { --ot-h: calc(100svh - var(--pb-h)); }
  }
  html.js body:not(.static-shot) .ot-stage {
    position: sticky; top: var(--pb-h); height: var(--ot-h);
    overflow: hidden; overflow: clip;   /* clip: nessun contenitore di scroll, il fuoco non può spostare la scena */
    grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr);
    padding: 0;
  }
  html.js body:not(.static-shot) .ot-fig {
    grid-area: auto; position: absolute; left: 50%; top: 50%;
    width: var(--ot-imgw); height: calc(var(--ot-imgw) * 1.5);
    margin: calc(var(--ot-imgw) * -0.75) 0 0 calc(var(--ot-imgw) * -0.5);
  }
  html.js body:not(.static-shot) .ot-s1 { grid-area: 1 / 1; align-self: center; padding: 0 var(--gutter); }
  html.js body:not(.static-shot) .ot-shot {
    grid-area: 1 / 1; align-self: center; padding: 0;
    max-width: min(var(--ot-max), calc(50% + var(--ot-pan) * 100% - var(--ot-reach) - var(--gutter)));
  }
  /* a quadro spostato dall'altro lato, il blocco parte a 28px dalla colonna scura */
  html.js body:not(.static-shot) .ot-shot[data-side="r"] {
    justify-self: start; margin-left: calc(50% - var(--ot-pan) * 100% + var(--ot-reach));
    transform: translate3d(100vw, 0, 0);    /* fuori scena finché js/about.js non lo porta dentro */
  }
  html.js body:not(.static-shot) .ot-shot[data-side="l"] {
    justify-self: end; margin-right: calc(50% - var(--ot-pan) * 100% + var(--ot-reach));
    transform: translate3d(-100vw, 0, 0);
  }
}

/* ── 3. Telefono e tablet: colonna sul filo rosso, Edgars sopra e Romanovskis sotto ── */
@media (max-width: 1023.98px) {
  .ot {
    --ot-name: clamp(2.25rem, 11vw, 4rem);
    --ot-line: clamp(1.55rem, 6.4vw, 2.4rem);
    --ot-g: 14px;   /* aria tra il nome e il quadro */
    /* il titolo intero (riga piccola, Edgars, quadro, Romanovskis) entra in uno schermo sopra la barra */
    --ot-pw: min(64vw, 340px, max(180px, calc((100vh - var(--pb-h) - 2 * var(--ot-name) - 80px) / 1.5)));
    overflow: hidden; padding-bottom: 8px;
  }
  @supports (height: 100svh) {
    .ot { --ot-pw: min(64vw, 340px, max(180px, calc((100svh - var(--pb-h) - 2 * var(--ot-name) - 80px) / 1.5))); }
  }
  @supports (overflow: clip) { .ot { overflow: clip; } }
  .ot-stage {
    display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center;
    padding: 0 var(--gutter); text-align: center;
  }
  /* il quadro occupa lo spazio lasciato sotto "Edgars": riga piccola (11px x 1,5) + 10px + nome + aria */
  .ot-fig {
    grid-area: 1 / 1; align-self: start;
    width: var(--ot-pw); height: calc(var(--ot-pw) * 1.5);
    margin-top: calc(11px * 1.5 + 10px + var(--ot-name) + var(--ot-g));
  }
  .ot-s1 { grid-area: 1 / 1; display: flex; flex-direction: column; align-items: center; }
  .ot-title { display: flex; flex-direction: column; align-items: center; }
  .ot-credit { margin-bottom: 10px; white-space: nowrap; }
  .ot-first { margin-bottom: calc(var(--ot-pw) * 1.5 + 2 * var(--ot-g)); }
  .ot-sub { max-width: 24em; margin-top: 16px; font-size: 15.5px; }
  .ot-shot { max-width: 26em; margin-top: clamp(56px, 10vh, 96px); }
  .ot-shot[data-shot="1"] { grid-row: 2; }
  .ot-shot[data-shot="2"] { grid-row: 3; }
  .ot-line, .ot-small { margin-left: auto; margin-right: auto; }
  .ot-small { font-size: 14.5px; }
  .ot-cta { justify-content: center; }
}

/* ── Fermo: riduci movimento, anteprime statiche e stampa ── */
@media (prefers-reduced-motion: reduce) {
  #about [data-side], #about .ot-fig { transform: none !important; }
}
.static-shot #about [data-side], .static-shot #about .ot-fig { transform: none !important; }
@media print {
  #about [data-side], #about .ot-fig { transform: none !important; }
  .ot-fig { position: relative !important; top: auto !important; }
}

/* ═══ How it works, versione moderna (5 ott 2026): sostituisce card grigie e lista dei termini ═══
   Binario a 4 tappe: una riga sottile con un nodo per tappa; tra le tappe il "cancello" (quadratino rosso
   = approvazione, lo stesso significato del tassello rosso nelle infografiche). Testo su carta, solo
   l'infografica sta in un riquadro. Sotto, gli accordi come clausole in griglia. */
.how-head { grid-template-columns: 1fr minmax(0, 26em); align-items: end; }
.how-head .lead { margin: 0; font-size: 1.05rem; }
.process { list-style: none; position: relative; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 40px; border-top: 1px solid var(--fg); }
/* colonne tutte uguali (riquadri della stessa altezza); il filetto tra le tappe sta nel gap */
.process .step { position: relative; background: none; border-radius: 0; min-height: 0; display: flex; flex-direction: column; gap: 0; padding: 20px 0 8px; }
.process .step + .step::before { content: ''; position: absolute; left: -20px; top: 0; bottom: 0; border-left: 1px solid var(--line); }
.step-tile { position: relative; border-radius: var(--radius-sm); background: var(--card); overflow: hidden; transition: transform 0.5s var(--ease); }
.step:hover .step-tile { transform: translateY(-4px); }
.step-tile .step-viz { width: 100%; margin: 0; aspect-ratio: 4 / 3; }
html:not(.js) .step-tile, html.no-3d .step-tile { display: none; }
.step-meta { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin: 18px 0 10px; }
.process .step .k { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; color: var(--muted); }
.step-gate { display: inline-flex; align-items: center; gap: 8px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.step-gate i { width: 7px; height: 7px; border-radius: 1.5px; background: var(--signal); }
.process .step h3 { margin: 0; font-size: clamp(1.35rem, 1.8vw, 1.7rem); }
.process .step p { margin-top: 8px; color: var(--muted); font-size: 14px; line-height: 1.5; max-width: 26em; }

.terms { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2.2fr); gap: 40px; margin-top: 64px; padding: 32px; border: 1px solid var(--line); border-top: 1px solid var(--line); border-radius: var(--radius); background: rgba(255, 255, 255, 0.35); }
.terms-head p { margin-top: 12px; color: var(--muted); font-size: 14px; max-width: 22em; }
.terms-list { list-style: none; counter-reset: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 32px; }
.terms .terms-list li { display: grid; grid-template-columns: 44px 1fr; grid-template-rows: auto auto; gap: 2px 12px; padding: 16px 0; border-top: 1px solid var(--line); border-bottom: 0; max-width: none; color: var(--muted); font-size: 14px; }
.terms .terms-list li::before { content: none; }
.terms-list li:nth-child(-n+2) { border-top: 0; padding-top: 0; }
.terms-list .t-n { grid-row: 1 / 3; font-family: var(--mono); font-size: 11px; color: var(--muted); padding-top: 3px; white-space: nowrap; }
.terms-list b { font-family: var(--display); font-weight: 600; font-size: 1.05rem; letter-spacing: -0.02em; color: var(--fg); }
@media (max-width: 1100px) {
  .process { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .process .step:nth-child(3)::before { content: none; }
  .process .step:nth-child(n+3) { margin-top: 24px; border-top: 1px solid var(--fg); }
  .terms { grid-template-columns: 1fr; gap: 20px; }
}
@media (max-width: 860px) {
  .how-head { grid-template-columns: 1fr; }
  .process { grid-template-columns: 1fr; }
  .process .step + .step::before { content: none; }
  .process .step + .step { margin-top: 24px; border-top: 1px solid var(--fg); }
  .terms { padding: 24px 20px; }
  .terms-list { grid-template-columns: 1fr; }
  .terms-list li:nth-child(2) { border-top: 1px solid var(--line); padding-top: 16px; }
  .terms .terms-list li { grid-template-columns: 36px 1fr; }
}
@media (prefers-reduced-motion: reduce) { .step-tile { transition: none; } .step:hover .step-tile { transform: none; } }

/* Hero: due colonne sulla stessa griglia; la scena ha uno spazio proprio,
   mentre titolo, presentazione e azioni restano un unico blocco. */
.hero.hero-v3 {
  position: relative; display: block; min-height: 100svh; overflow: hidden;
  padding: calc(var(--pb-h, 56px) + clamp(24px, 4vh, 48px)) var(--gutter) clamp(64px, 8vh, 96px);
  background: radial-gradient(ellipse at 28% 52%, #e5e2da 0, #eeece6 30%, var(--bg) 68%);
}
.hero-copy { position: relative; z-index: 1; min-width: 0; }
.hero-title { position: static; min-height: 0; padding: 0; display: block; }
.hero-title h1 { margin: 0; max-width: none; font-size: clamp(3rem, min(4.5vw, 8.6svh), 5.8rem); line-height: .98; letter-spacing: -0.048em; }
.hero-title .ln { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.hero-title .ln > span { display: block; }
.hero-title .ln.thin { font-size: .78em; line-height: 1.06; letter-spacing: -.04em; margin-top: .3em; }
.hero-body { padding: 0; margin-top: clamp(22px, 3.3vh, 32px); max-width: 32em; }
.hero-body .lead { font-size: clamp(1rem, 1.2vw, 1.15rem); max-width: 28em; margin: 0 0 24px; }
.hero-body .fns { margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--line); gap: 6px; }
.hero-body .fn { font-size: 11px; }

.hero-art { position: relative; z-index: 1; opacity: 0; transition: opacity 1.4s var(--ease) 0.15s; }
.hero-art.morph-ready { opacity: 1; }
.hero-form { position: absolute; inset: 0; }
.hero-form canvas { display: block; width: 100%; height: 100%; }
.hero-form { pointer-events: none; }
/* produzione isometrica (js/hero-iso.js): registro del procedimento sopra la scena, etichette nel disegno.
   Il registro ha la sua fascia (--proc-h): la scena si inquadra sotto, così niente si sovrappone. */
.hero-art { --proc-h: 76px; }
.hero-art .hero-form { inset: var(--proc-h) 0 0 0; }
.hero-proc { position: absolute; z-index: 2; left: 0; right: 0; top: 0; height: var(--proc-h); pointer-events: none; font-family: var(--mono); }
.hero-steps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin: 0; padding: 0; list-style: none; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.hero-steps li { position: relative; display: flex; align-items: center; gap: 7px; padding-bottom: 9px; opacity: .45; transition: opacity .6s var(--ease), color .6s var(--ease); }
.hero-steps .sq { flex: none; width: 7px; height: 7px; box-shadow: inset 0 0 0 1px currentColor; transition: background-color .4s var(--ease); }
.hero-steps .bar { position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: color-mix(in srgb, currentColor 22%, transparent); overflow: hidden; }
.hero-steps .bar i { display: block; height: 100%; background: currentColor; transform: scaleX(0); transform-origin: 0 50%; }
.hero-steps li.past { opacity: .75; }
.hero-steps li.on { opacity: 1; color: var(--fg); }
.hero-steps li.ok .sq { background: currentColor; }
.hero-now { display: flex; align-items: baseline; gap: 10px; margin: 14px 0 0; font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hero-now .hn-n { font-size: 11px; letter-spacing: .06em; }
.hero-now b { font-family: var(--display); font-weight: 600; font-size: 15px; letter-spacing: -.02em; color: var(--fg); }
.hero-now .hn-t { overflow: hidden; text-overflow: ellipsis; }
.hero-now.in { animation: hero-now .7s var(--ease) both; }
@keyframes hero-now { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.hero-lab { position: absolute; z-index: 2; margin-top: 2px; opacity: 0; white-space: nowrap; pointer-events: none; font-family: var(--mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); transform: translate(-50%, 6px); }
.hero-lab.is-small { font-size: 10px; letter-spacing: .06em; }
/* numero dentro la casella di approvazione: grigio sulla casella vuota, bianco quando il tassello nero si posa */
.hero-lab.is-gate { margin-top: -7px; font-size: 10px; letter-spacing: .04em; color: var(--muted); transition: color .4s var(--ease); }
.hero-lab.is-gate.is-lit { color: var(--fg); }
@media (max-width: 860px) {
  .hero-art { --proc-h: 84px; }
  .hero-steps { gap: 8px; font-size: 10px; letter-spacing: .03em; }
  .hero-steps li { gap: 5px; }
  .hero-steps .sq { width: 6px; height: 6px; }
  .hero-now { margin-top: 12px; font-size: 11px; gap: 5px 8px; flex-wrap: wrap; white-space: normal; }
  .hero-now .hn-t { flex-basis: 100%; padding-left: 32px; line-height: 1.4; }
  .hero-now b { font-size: 14px; }
  .hero-lab { font-size: 9.5px; }
  /* sul telefono il tavolo è piccolo: numeri ed etichette nel disegno si toccherebbero, restano legenda e registro */
  .hero-lab { display: none; }
}
/* registro sui telefoni stretti: in italiano "Sviluppo" è la fase più lunga, la spaziatura si stringe; sotto i 360px
   i numeri delle fasi lasciano posto ai nomi (il numero resta nel passaggio in corso, 04.4), in entrambe le lingue */
@media (max-width: 400px) { :lang(it) .hero-steps { letter-spacing: 0; } }
@media (max-width: 359px) { .hero-steps .n { display: none; } }
@media (prefers-reduced-motion: reduce) { .hero-steps li, .hero-steps .sq { transition: none; } .hero-now.in { animation: none; } }
.hero-floor { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent); }

.hero-cue { position: absolute; z-index: 1; left: var(--gutter); bottom: clamp(16px, 3vh, 32px); display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.hero-cue:hover { color: var(--fg); }
.hero-cue svg { animation: cue 2.4s var(--ease) infinite; }
@keyframes cue { 0%, 100% { transform: translateY(-2px); } 50% { transform: translateY(3px); } }

/* entrata: le righe del titolo salgono da una maschera, poi l'invito a scorrere */
html.js .hero-title .ln > span { transform: translateY(108%); }
html.js .hero-cue { transform: translateY(12px); opacity: 0; }
html.js.hero-in .hero-title .ln > span { transform: none; transition: transform 1.25s cubic-bezier(0.19, 1, 0.22, 1); }
html.js.hero-in .hero-title .ln + .ln > span { transition-delay: 0.14s; }
html.js.hero-in .hero-cue { transform: none; opacity: 1; transition: transform 0.9s var(--ease) 1s, opacity 0.9s var(--ease) 1s; }

/* Su desktop forma e testo condividono il centro e margini equivalenti. */
@media (min-width: 1001px) {
  .hero.hero-v3 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(48px, 6vw, 112px); align-items: center; }
  .hero-copy { grid-column: 1; grid-row: 1; width: 100%; max-width: 650px; justify-self: end; }
  .hero-art { grid-column: 2; grid-row: 1; width: 100%; height: clamp(400px, 70svh, 680px); }
  .hero-v3[data-art="left"] .hero-art { grid-column: 1; }
  .hero-v3[data-art="left"] .hero-copy { grid-column: 2; justify-self: start; }
  /* illustrazione come sfondo di tutta la hero (AD, 6 ott: "più grande, va a sinistra sotto il testo, parte del
     background sul desktop"): canvas su tutta la sezione, registro in alto nella metà destra, velo carta dietro il testo */
  .hero.hero-v3[data-art="right"] { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
  .hero-v3[data-art="right"] .hero-copy { position: relative; z-index: 2; justify-self: start; }
  .hero-v3[data-art="right"] .hero-copy::before { content: ""; position: absolute; z-index: -1; inset: -12% -18% -12% -30%; pointer-events: none;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--bg) 88%, transparent) 55%, color-mix(in srgb, var(--bg) 0%, transparent)); }
  /* grid-area auto: un assoluto con colonna assegnata userebbe la colonna come contenitore, non la sezione */
  .hero-v3[data-art="right"] .hero-art { position: absolute; inset: 0; grid-area: auto; z-index: 0; width: auto; height: auto; margin: 0; }
  /* sotto il testo il disegno è sfondo (attenuato), dalla metà in poi è pieno */
  .hero-v3[data-art="right"] .hero-art .hero-form { inset: 0;
    -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,.2) 0, rgba(0,0,0,.2) 30%, #000 46%);
            mask-image: linear-gradient(90deg, rgba(0,0,0,.2) 0, rgba(0,0,0,.2) 30%, #000 46%); }
  .hero-v3[data-art="right"] .hero-proc { left: 54%; right: var(--gutter); top: calc(var(--pb-h, 56px) + clamp(24px, 4vh, 48px)); }
  .hero-v3[data-art="left"] .hero-cue { left: auto; right: var(--gutter); }
}
/* Su tablet e telefono la scena segue il testo senza margini negativi. */
@media (max-width: 1000px) {
  .hero.hero-v3 { min-height: 0; padding-bottom: 16px; }
  .hero-copy { max-width: 660px; }
  .hero-art { width: 100%; height: clamp(340px, 48svh, 520px); margin-top: 12px; }
  .hero-cue { display: none; }
}
@media (max-width: 860px) {
  .hero.hero-v3 { display: flex; flex-direction: column; padding-top: 28px; background: radial-gradient(ellipse at 50% 64%, #e5e2da 0, var(--bg) 70%); }
  .hero-copy, .hero-body { display: contents; }
  .hero-title { order: 0; }
  .hero-title h1 { font-size: clamp(2.4rem, 9.5vw, 4rem); }
  .hero-body .lead { order: 1; margin-top: 24px; }
  .hero-cta { order: 2; }
  .hero-art { order: 3; height: clamp(410px, 110vw, 520px); margin-top: 24px; }
  .hero-body .fns { order: 4; margin-top: 0; padding-top: 14px; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .hero-title .ln > span, html.js .hero-cue { transform: none; opacity: 1; transition: none; }
  .hero-cue svg { animation: none; }
  .hero-art { transition: none; }
}

/* ═══ Sistema RGB (5 ott 2026): le tre forme piccole dell'hero diventano il codice del sito.
   Cubo rosso = web design (la struttura), sfera verde = front-end (si adatta), piramide blu = grafica (il segno).
   Si muovono solo nell'hero; altrove sono segni piatti e fermi, piccoli: mai testo, mai fondi.
   Un filo sottile d'inchiostro le stacca dalla carta (il verde puro da solo sparirebbe). ═══ */
.prim { display: inline-block; flex: none; width: 0.62em; height: 0.62em; fill: currentColor; stroke: rgba(15, 15, 15, 0.22); stroke-width: 0.6px; vertical-align: baseline; overflow: visible; }
.prim.r { color: var(--rgb-r); }
.prim.g { color: var(--rgb-g); }
.prim.b { color: var(--rgb-b); }
.prim.k { color: var(--rgb-k); }   /* Visuals: cilindro nero, il K della stampa (quarto pilastro, AD 8 ott 2026) */
.prims { display: inline-flex; align-items: center; gap: 0.24em; margin-left: 0.5em; vertical-align: 0.04em; }
.pb-name .prims { font-size: 13px; }
.pb-home .prims, .masthead .prims { font-size: 14px; }
/* la testata su telefono dà a ogni span una riga propria (pathbar.css): le primitive restano accanto al nome */
.masthead b .prims { display: inline-flex; margin-top: 0; font-family: inherit; letter-spacing: 0; text-transform: none; }
.service h3 .prim { width: 0.46em; height: 0.46em; margin-right: 0.42em; vertical-align: 0.1em; }
.row .tags { display: inline-flex; align-items: center; gap: 5px; margin-left: 12px; vertical-align: 0.18em; }
.row .tags .prim { width: 10px; height: 10px; }
.row .nw { white-space: nowrap; }   /* le forme restano attaccate all'ultima parola del nome, mai da sole a capo */
/* Servizi sotto il nome (AD 8 ott 2026: "sotto il nome si vedano bene i tag dei servizi, fatti con il colore della
   categoria"): etichette col bordo e una velatura del colore RGB della categoria (rosso web design, verde front-end,
   blu grafica), testo in inchiostro per leggerle bene; stesso ordine delle forme accanto al nome. Il verde puro sulla
   carta sparirebbe: il bordo è un verde più scuro. Nei lavori per clienti sono i servizi scritti prima (Branding,
   Logo design, Web design, Front-end); nei progetti AI la categoria, con "Visuals" al posto di "Graphic design" (AD 8 ott:
   immagini, grafiche e video). Dopo i servizi, qualche etichetta in più sul lavoro (stesso colore della disciplina: AD 8 ott,
   "aggiungi più tag"). Sotto, in grigio, la descrizione del progetto (AD 8 ott: "descrivi il progetto"; clienti dai loro siti). */
.row .svc { display: flex; flex-wrap: wrap; gap: 4px; margin: 7px 0 6px; }
.row .sv {
  display: inline-flex; align-items: center; min-height: 17px; padding: 2px 6px 1px; border-radius: 999px;   /* piccole come l'anno accanto (AD 8 ott) */
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.05em; text-transform: uppercase; line-height: 1; white-space: nowrap;
  color: var(--fg); border: 1px solid var(--rgb-r); background: rgba(255, 0, 0, 0.08);
}
.row .sv.b { border-color: var(--rgb-b); background: rgba(0, 0, 255, 0.07); }
.row .sv.g { border-color: #14B014; background: rgba(0, 255, 0, 0.16); }
.row .sv.k { border-color: var(--rgb-k); background: rgba(15, 15, 15, 0.06); }
.row .ctx { display: block; }
/* Desktop (AD 8 ott 2026: "il numero allineato al tag, così come interlinea mi fa strano"): numero, anno e lente non stanno
   più a metà riga ma sulla riga delle etichette dei servizi; i tag sono alti 17px e partono 7px sotto il nome. */
@media (min-width: 861px) {
  .row .i, .row .y { grid-row: 2; align-self: start; margin-top: 7px; line-height: 17px; }
  .row .a { grid-row: 2; align-self: start; margin-top: -2px; }
}
.prim-key { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 6px 20px; margin: -4px 0 16px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--muted); }
.prim-key span { display: inline-flex; align-items: center; gap: 7px; }
.prim-key .prim { width: 10px; height: 10px; }
/* in Client work la chiave sta nell'intestazione, in basso a destra (come il lead di How it works) */
.section-head .prim-key { margin: 0; padding-bottom: 4px; } /* linea di base allineata a quella del lead */
@media (max-width: 860px) {
  .prim-key { justify-content: flex-start; margin-top: 4px; }
}
@media print { .prim { stroke: #0f0f0f; } }


/* ═══ Sezioni su nero (richiesta AD, 5 ott 2026): AI projects e How it works.
   La pagina alterna chiaro e scuro: hero, Client work | AI projects | Services | How it works | About | Contact.
   Si ridefiniscono i token dentro la sezione, così indici, bottoni, filetti e testi si girano da soli.
   --signal va ridichiarato: sulla radice è già risolto in inchiostro. ═══ */
.section.section-dark {
  --fg: #F5F4F0; --bg: #0F0F0E; --card: #1C1C1A; --muted: #A9A69E; --muted-2: #77756F;
  --muted-card: #4A4945; --line: rgba(245, 244, 240, 0.14); --signal: #F5F4F0;
  background: #0F0F0E; color: var(--fg);
  margin-top: clamp(80px, 12vh, 150px); padding-bottom: clamp(88px, 13vh, 160px);
  border-radius: 36px;
}
.section.section-dark + .section { padding-top: clamp(88px, 13vh, 160px); }
/* How it works cresce dall'80% a piena misura con lo scroll (js/main.js): si allarga dal bordo alto, al centro */
#how-it-works.section-dark { transform-origin: 50% 0; will-change: transform; }
.section-dark ::selection { background: var(--fg); color: var(--bg); }
/* infografiche 3D su nero (AD, 6 ott): tavola scura con un filo, disegno in negativo (palette DARK in js/process3d.js) */
.section-dark .step-tile { background: #151514; box-shadow: inset 0 0 0 1px rgba(245, 244, 240, 0.09); }
.section-dark .terms { background: rgba(245, 244, 240, 0.035); }
/* sul nero il blu puro quasi sparisce: il filo che sulla carta è d'inchiostro qui è di carta */
.section-dark .prim { stroke: rgba(245, 244, 240, 0.4); }
@media (max-width: 860px) {
  .section.section-dark { border-radius: 24px; }
}

/* ═══ Sezioni nella luce dell'hero (prova AD, 5 ott 2026): al posto del nero, AI projects e How it works
   prendono la sfumatura dell'hero con gli stessi colori, gli stessi passaggi e la stessa misura
   (#e5e2da → #eeece6 → carta; ellisse 101vw × 73,5% di uno schermo, come quella dietro la forma).
   La luce è un livello sotto la sezione, alto uno schermo e centrato su --tone-y: finisce in trasparenza
   esattamente sul suo bordo, quindi non c'è mai una giunta, nemmeno quando sconfina nella sezione vicina.
   Il centro sta dove resta visibile: dietro l'indice dei progetti AI (come la forma nell'hero, a sinistra),
   sotto le quattro tavole di How it works (che sono fogli semitrasparenti e la lasciano passare).
   Per tornare al nero basta rimettere .section-dark al posto di .section-tone nell'HTML. ═══ */
.section.section-tone {
  --muted: var(--muted-card);         /* testo secondario AA anche sul centro più scuro */
  --line: rgba(15, 15, 15, 0.1);      /* filetti visibili sia sulla carta sia sulla sfumatura */
  --card: rgba(255, 255, 255, 0.42);  /* tavole e palco: fogli appena più chiari della luce */
  --tone-x: 50%; --tone-y: 50%;
  position: relative;
  padding-top: clamp(112px, 17vh, 200px); padding-bottom: clamp(40px, 5vh, 64px);
}
.section.section-tone::before {
  content: ''; position: absolute; z-index: -1; left: 0; right: 0; pointer-events: none;
  top: calc(var(--tone-y) - 50vh); height: 100vh;
  top: calc(var(--tone-y) - 50svh); height: 100svh;
  background: radial-gradient(101vw 73.5% at var(--tone-x) 50%, #e5e2da 0, #eeece6 30%, rgba(245, 244, 240, 0) 68%);
}
#ai.section-tone { --tone-x: 28%; --tone-y: 64%; }          /* centro dell'indice tra 1440 e 1920 di larghezza */
#how-it-works.section-tone { --tone-x: 50%; --tone-y: 36%; } /* altezza delle tavole */
/* le tavole sono fogli chiari: un filo le tiene leggibili anche dove la luce torna carta (come il riquadro degli accordi) */
.section-tone .step-tile { box-shadow: inset 0 0 0 1px var(--line); }
/* su telefono le immagini coprono la larghezza: la luce sta all'ingresso della sezione (titolo e primo pezzo) */
@media (max-width: 860px) {
  #ai.section-tone, #how-it-works.section-tone { --tone-x: 50%; --tone-y: 380px; }
}

/* ═══ About · Volo su Duality (richiesta AD, 5-6 ott 2026): tutto l'About sta sul volo.
   js/film.js aggiunge #about.ot-film-on solo con JS e movimento (non con Save-Data né ?static=): la scena
   .ot-stage si ferma sotto la Path Bar (sul telefono in alto: la barra è in basso) per 3,6 schermi e il <video>
   .ot-film fa il volo (Kling senza audio tagliato a 5,2 s come l'ingresso di .ch, ricodificato per lo scroll in
   ASSET/painting/flight/flight-l|p.mp4).
   Il nome sul primo fotogramma: largo = ai due lati della linea rossa (colonna --film-col dal JS: colonna scura
   del quadro + 28px); stretto (.ot-tall) = Edgars in alto e Romanovskis in basso, su fasce di carta (canvas).
   Le due frasi dopo il tuffo, quando si vede l'orizzonte: in basso, chiare su un velo scuro che sale dal fondo
   (canvas), la 1 a destra, la 2 con i bottoni a sinistra (stretto: centrate). Cielo e orizzonte liberi (AD, 6 ott).
   Senza la classe vale tutto quello sopra: composizione ferma con il quadro. ═══ */
.ot-film { display: none; }
#about.ot-film-on { scroll-margin-top: calc(-1 * var(--ot-pad) - 16px); }   /* i salti arrivano a scena ferma */
#about.ot-film-on .ot {
  --film-h: calc(100vh - var(--pb-h));
  --ot-col: var(--film-col, 480px);
  --ot-line: clamp(1.5rem, min(2.5vw, 4.4vh), 2.6rem);
  --shot-pad: clamp(28px, 6vh, 64px);
  --film-run: 3.6;    /* schermi di volo (letto da js/film.js) */
  /* coda: Contact sale sopra la scena mentre il volo finisce (ultimo fotogramma a metà salita, js/film.js);
     --film-cover = altezza di Contact (al massimo la scena), misurata da js/film.js sulla radice */
  height: calc(var(--film-h) * (1 + var(--film-run)) + var(--film-cover, 0px)); overflow: visible; padding-bottom: 0;
}
@supports (height: 100svh) { #about.ot-film-on .ot { --film-h: calc(100svh - var(--pb-h)); } }
#about.ot-film-on .ot-stage {
  position: sticky; top: var(--pb-h); height: var(--film-h);
  display: block; padding: 0; overflow: hidden; overflow: clip; background: var(--bg); text-align: left;
}
#about.ot-film-on .ot-fig { display: none; }
#about.ot-film-on .ot-film {
  display: block; position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; pointer-events: none; background: var(--bg); visibility: hidden;
}
#about.ot-film-on.has-poster .ot-film, #about.ot-film-on.has-frame .ot-film { visibility: visible; }
/* livelli sopra il video (creati da js/film.js): fasce di carta del nome (solo stretto) e il velo scuro di ogni frase */
#about.ot-film-on .ot-band, #about.ot-film-on .ot-veil { position: absolute; left: 0; right: 0; z-index: 0; opacity: 0; pointer-events: none; }
#about.ot-film-on .ot-band { display: none; }
#about.ot-film-on.ot-tall .ot-band-top { display: block; }
#about.ot-film-on.ot-tall .ot-film { will-change: transform; }
#about.ot-film-on.ot-tall .ot { --film-run: 2.4; }   /* telefono: un terzo di scroll in meno per lo stesso volo (AD 8 ott: "va un po' lenta") */
#about.ot-film-on .ot-band-top { top: 0; height: 30%; background: var(--bg); will-change: transform; }   /* foglio netto, nessuna sfumatura (AD) */
#about.ot-film-on .ot-band-bottom { bottom: 0; height: 38%; background: linear-gradient(to top, var(--bg) 0, var(--bg) 68%, rgba(245, 244, 240, 0) 100%); }
#about.ot-film-on .ot-veil { bottom: 0; }   /* altezza e sfumatura le misura il JS sul blocco della frase */
#about.ot-film-on .ot-s1 { position: absolute; inset: 0; z-index: 1; margin: 0; }
#about.ot-film-on [data-shot] { will-change: transform, opacity; }
/* alla fine Contact sale sopra il volo fermo sull'ultimo fotogramma, ma solo per la sua altezza: la pagina finisce
   con il cielo e le cime in alto e la carta nera in basso, mai tutto nero (richieste AD, 6 ott: "sotto il nero,
   senza sfumatura", poi "non voglio che diventi tutto nero"). Su schermi bassi, se Contact è più alto della scena,
   la copre tutta e prosegue. */
#about.ot-film-on + .contact { z-index: 2; margin-top: calc(-1 * var(--film-cover, 0px)); }

/* largo: il nome ai due lati della linea rossa, centrato in altezza */
#about.ot-film-on:not(.ot-tall) .ot { --ot-name: clamp(2rem, min(5vw, 11vh, calc((100vw - 2 * var(--gutter) - var(--ot-col) - 24px) / 13)), 6rem); }
#about.ot-film-on:not(.ot-tall) .ot-s1 {
  display: grid; grid-template-columns: minmax(0, 1fr) var(--ot-col) minmax(0, 1fr);
  align-content: center; row-gap: 16px; padding: 0 var(--gutter); text-align: left;
}
#about.ot-film-on:not(.ot-tall) .ot-title {
  grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) var(--ot-col) minmax(0, 1fr);
  row-gap: 14px; align-items: end;
}
#about.ot-film-on:not(.ot-tall) .ot-credit { grid-column: 1; grid-row: 1; justify-self: end; text-align: right; margin: 0; white-space: normal; }
#about.ot-film-on:not(.ot-tall) .ot-first { grid-column: 1; grid-row: 2; justify-self: end; margin: 0; }
#about.ot-film-on:not(.ot-tall) .ot-last { grid-column: 3; grid-row: 2; justify-self: start; margin: 0; }
#about.ot-film-on:not(.ot-tall) .ot-sub { grid-column: 3; justify-self: start; margin: 0; }

/* stretto: Edgars in alto, Romanovskis e la riga sulla Svizzera in basso, il quadro in mezzo */
#about.ot-film-on.ot-tall .ot { --ot-line: clamp(1.4rem, 6vw, 2rem); }
#about.ot-film-on.ot-tall .ot-s1 {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: clamp(18px, 4vh, 36px) var(--gutter) clamp(20px, 4.5vh, 40px);
}
#about.ot-film-on.ot-tall .ot-title { flex: none; display: flex; flex-direction: column; align-items: center; }
#about.ot-film-on.ot-tall .ot-credit { margin: 0 0 10px; white-space: nowrap; }
#about.ot-film-on.ot-tall .ot-first { margin: 0; }
#about.ot-film-on.ot-tall .ot-last { margin-top: 0; }
#about.ot-film-on.ot-tall .ot-sub { max-width: 24em; margin: 12px 0 0; font-size: 15px; }

/* le due frasi in basso, chiare sul velo scuro (opacità, spostamento e clic li regola il JS) */
#about.ot-film-on .ot-shot {
  position: absolute; z-index: 2; top: auto; bottom: var(--shot-pad); grid-area: auto; margin: 0; padding: 0;
  width: min(40vw, 34rem); max-width: none; opacity: 0; transform: none; pointer-events: none; text-align: left;
  color: var(--bg);
}
#about.ot-film-on .ot-shot .ot-small { color: rgba(245, 244, 240, 0.82); }
#about.ot-film-on .ot-shot .btn { background: var(--bg); color: var(--fg); border-color: var(--bg); }
#about.ot-film-on .ot-shot .btn.ghost { background: transparent; color: var(--bg); border-color: rgba(245, 244, 240, 0.4); }
#about.ot-film-on .ot-shot .btn.ghost:hover { border-color: var(--bg); }
#about.ot-film-on .ot-shot :focus-visible { outline-color: var(--bg); }
#about.ot-film-on .ot-shot ::selection { background: var(--bg); color: var(--fg); }
#about.ot-film-on .ot-shot[data-side="r"] { right: var(--gutter); left: auto; justify-self: auto; }
#about.ot-film-on .ot-shot[data-side="l"] { left: var(--gutter); right: auto; justify-self: auto; }
#about.ot-film-on .ot-shot .ot-line { max-width: 15em; margin-left: 0; margin-right: 0; }
#about.ot-film-on .ot-shot .ot-small { margin: 12px 0 0; }
#about.ot-film-on .ot-shot .ot-cta { margin-top: 18px; justify-content: flex-start; }
#about.ot-film-on.ot-tall .ot-shot { left: var(--gutter); right: var(--gutter); width: auto; text-align: center; }
#about.ot-film-on.ot-tall .ot-shot .ot-line,
#about.ot-film-on.ot-tall .ot-shot .ot-small { margin-left: auto; margin-right: auto; }
#about.ot-film-on.ot-tall .ot-shot .ot-cta { justify-content: center; }

@media (max-width: 860px) {
  #about.ot-film-on .ot-stage { top: 0; }
  /* telefono: Contact più compatto, così sopra resta una fascia di cielo */
  #about.ot-film-on + .contact { padding-top: clamp(56px, 8vh, 72px); }
  #about.ot-film-on + .contact .contact-close { margin-top: clamp(40px, 6vh, 56px); }
  #about.ot-film-on .ot { --film-h: calc(100vh - var(--pb-h) - env(safe-area-inset-bottom, 0px)); }
  @supports (height: 100svh) { #about.ot-film-on .ot { --film-h: calc(100svh - var(--pb-h) - env(safe-area-inset-bottom, 0px)); } }
}
@media print {
  #about.ot-film-on .ot { height: auto; }
  #about.ot-film-on + .contact { margin-top: 0; }
  #about.ot-film-on .ot-stage { position: relative; height: auto; }
  #about.ot-film-on .ot-film { display: none; }
  #about.ot-film-on .ot-s1, #about.ot-film-on .ot-shot { position: static; width: auto; }
  #about.ot-film-on [data-shot] { opacity: 1 !important; transform: none !important; }
}

/* ═══ Servizi in home (8 ott 2026): le card sono quelle che si girano, in css/flip-cards.css (prima qui: card con
   elenco, poi accorciate; AD: "le card nuove mettile nella homepage, non voglio che le singole card portino al
   dettaglio"). Qui resta il bottone "Services in detail" nell'intestazione della sezione. ═══ */
.svc-all { align-self: end; white-space: nowrap; }
.svc-all .arr { display: inline-flex; }
@media (max-width: 860px) { .svc-all { justify-self: start; } }

/* ═══ Link Services nel menu (AD 8 ott 2026: "nel menu il link services"). Desktop: nella barra, prima di Start a
   project. Telefono (la barra è nascosta): nella testata in cima, a destra del nome. Nella pagina Servizi è segnato. ═══ */
.pb-link { flex: none; display: inline-flex; align-items: center; min-height: 44px; margin-left: auto; padding: 0 16px; border-radius: 999px; font-size: 14px; font-weight: 500; color: var(--fg); transition: background-color 0.25s; }
.pb-link:hover { background: rgba(15, 15, 15, 0.06); }
.pb-link[aria-current="page"] { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
@media (min-width: 861px) { .pathbar .pb-link + .pb-cta { margin-left: 6px; } }
.mh-link { flex: none; display: none; align-items: center; min-height: 40px; margin-left: auto; padding: 0 14px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line); font-size: 13px; font-weight: 500; color: var(--fg); }
.mh-link[aria-current="page"] { box-shadow: inset 0 0 0 1px var(--fg); }
@media (max-width: 860px) { .mh-link { display: inline-flex; } }
@media print { .pb-link, .mh-link { display: none; } }

/* ═══ Lingua (AD 8 ott 2026: italiano come seconda lingua, pagine in it/). Il bottone porta alla stessa pagina
   nell'altra lingua: IT sulle pagine inglesi, EN su quelle italiane. Desktop: nella barra, tra Services e Start a
   project. Telefono: nella testata, accanto a Services. Stessa forma della lingua di romanovskis.ch (.nav-lang). ═══ */
.pb-lang, .mh-lang { flex: none; align-items: center; justify-content: center; min-width: 44px; padding: 0 12px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line); font-family: var(--mono); font-size: 11px; font-weight: 500; letter-spacing: 0.1em; color: var(--fg); transition: box-shadow 0.25s; }
.pb-lang:hover, .mh-lang:hover { box-shadow: inset 0 0 0 1px var(--fg); }
.pb-lang { display: inline-flex; min-height: 36px; margin-left: 2px; }
@media (min-width: 861px) { .pathbar .pb-lang + .pb-cta { margin-left: 8px; } }
.mh-lang { display: none; min-height: 40px; margin-left: -4px; }
@media (max-width: 860px) { .mh-lang { display: inline-flex; } }
@media print { .pb-lang, .mh-lang { display: none; } }

/* ═══ Studio di caso (AD 8 ott 2026): "la navigazione al prossimo progetto sempre accessibile, la sidebar a sinistra, i
   media dentro una finestra, non a tutto schermo, come sul loro tavolo di lavoro". Su desktop la colonna del testo è a
   sinistra e il suo piede (Start a project, Next project col nome del progetto che segue) resta sempre in vista in
   basso mentre il testo scorre. A destra il tavolo (grigio carta) e sopra la finestra del media, col formato del media
   (--ar dal JS, misurato al caricamento) e una barra sottile col nome del media. Sul telefono resta media sopra, testo sotto. ═══ */
.cs-media { container-type: size; }
.cs-stage { position: absolute; inset: 64px 64px 92px; display: grid; place-items: center; container-type: size; }
.cs-win {
  --bar: 34px;
  width: min(100cqw, calc((100cqh - var(--bar)) * var(--ar, 1.6)));
  border-radius: 14px; overflow: hidden; background: var(--bg);
  box-shadow: 0 0 0 1px rgba(15, 15, 15, 0.08), 0 28px 60px -34px rgba(15, 15, 15, 0.45), 0 2px 6px rgba(15, 15, 15, 0.06);
}
.cs-win-bar { height: var(--bar); display: flex; align-items: center; gap: 6px; padding: 0 14px; border-bottom: 1px solid var(--line); background: #FCFBF8; }
.cs-win-bar i { width: 8px; height: 8px; border-radius: 50%; background: rgba(15, 15, 15, 0.13); flex: none; }
.cs-win-label { margin-left: 10px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-win-body { position: relative; aspect-ratio: var(--ar, 1.6); background: var(--bg); }
.cs-media .cs-win-body img, .cs-media .cs-win-body video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.cs-side { padding-bottom: 0; }
.cs-side .cs-foot { position: sticky; bottom: 0; z-index: 2; margin-top: auto; padding: 14px 0 18px; background: var(--bg); }
.cs-nextp > span { display: inline-flex; flex-direction: column; align-items: flex-end; line-height: 1.2; }
.cs-nextname { font-family: var(--display); font-weight: 600; font-size: 15px; letter-spacing: -0.02em; text-transform: none; }
.cs-nextname:empty { display: none; }
@media (min-width: 861px) {
  .cs { grid-template-columns: minmax(340px, 400px) minmax(0, 1fr); }
  .cs-side { grid-column: 1; grid-row: 1; border-left: 0; border-right: 1px solid var(--line); }
  .cs-media { grid-column: 2; grid-row: 1; }
}
@media (max-width: 860px) {
  .cs-stage { inset: 56px 16px 72px; }
  .cs-win { --bar: 26px; border-radius: 10px; }
  .cs-win-bar { padding: 0 10px; gap: 5px; }
  .cs-win-bar i { width: 6px; height: 6px; }
}

