/* Se il JS non parte, niente resta nascosto: le regole che azzerano opacità o
   larghezza valgono solo sotto `.js`, aggiunta da uno script in testa. */
/* ============================================================================
   Platform — "Loom" direction, PP (partner portal)
   ----------------------------------------------------------------------------
   Third proposal for the client side, and the first one built around a voice
   rather than a surface.

       petrol : dark room, tiles, instrument        (internal)
       bloom  : ivory paper, gold light, editorial  (PP)
       loom   : warm stone, ink blue, a conversation (PP)

   THE TONE ASKED FOR: light but not white, and not dark either. So the canvas
   is warm stone — a real colour, around 91% lightness — and the cards sit
   *above* it at 97%. That inversion is the whole trick: on a white page a card
   has to draw a border to exist, and borders everywhere read as a form to fill
   in. On stone, a card is simply lighter than the room, the way paper on a desk
   is, and it needs almost no line at all.

   HOME, BUT TECHNICAL. The warmth comes from the stone, the rounded shapes and
   the fact that the page speaks in sentences. The precision comes from a
   monospaced label on every fact, hairline rules, and status that is always a
   word plus a mark. Neither half is decoration: a client should feel invited
   and should still believe there is real machinery behind the invitation.

   THE VOICE. Marta is the person who follows your searches, and the page is
   written as her side of a conversation — "ti presentiamo Giulia", "se ti va,
   il colloquio lo fissiamo noi". The client's own moves are drawn as replies.
   This is the argument to weigh: it is warmer than any of the other
   directions, and it only stays honest if a real person is actually there.

   Behaviour in assets/loom.js. No build step, no CDN.
   ============================================================================ */

@font-face { font-family: "Fraunces"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/fraunces-500.woff2") format("woff2"); }
@font-face { font-family: "Fraunces"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/fraunces-600.woff2") format("woff2"); }
@font-face { font-family: "Fraunces"; font-style: italic; font-weight: 500; font-display: swap; src: url("fonts/fraunces-italic-500.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("fonts/inter-400.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("fonts/inter-500.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("fonts/inter-600.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("fonts/inter-700.woff2") format("woff2"); }

:root {
  --font-sans:  "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-serif: "Fraunces", "Iowan Old Style", Palatino, Georgia, serif;
  --font-mono:  ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* The room is stone; the cards are paper laid on it. Neither is white. */
  --room:   oklch(0.912 0.010 85);
  --room-2: oklch(0.886 0.012 82);
  --card:   oklch(0.968 0.006 88);
  --card-2: oklch(0.945 0.008 86);

  /* Ink is graphite with blue in it — warm stone under cool ink is what keeps
     the page from going either clinical or rustic. */
  --ink:    oklch(0.285 0.028 265);
  --muted:  oklch(0.440 0.024 265);
  --faint:  oklch(0.505 0.020 265);
  --line:   oklch(0.845 0.012 85);
  --line-2: oklch(0.788 0.016 84);

  /* Ink blue — the technical half. Clears 6:1 on card, so it may be text. */
  --accent:      oklch(0.475 0.105 258);
  --accent-deep: oklch(0.375 0.095 260);
  --accent-soft: oklch(0.912 0.032 258);
  --accent-line: oklch(0.828 0.052 258);

  /* Iris — the live one: what is happening right now. Fills and marks only,
     never text, it does not clear on stone. */
  --iris:      oklch(0.640 0.135 282);
  --iris-ink:  oklch(0.470 0.125 282);
  --iris-soft: oklch(0.918 0.038 282);

  /* Peach — the warm one, and the only colour allowed to mean "your move". */
  --peach:      oklch(0.760 0.115 48);
  --peach-ink:  oklch(0.505 0.115 48);
  --peach-soft: oklch(0.925 0.042 48);

  --ok:     oklch(0.480 0.090 158);
  --ok-soft:oklch(0.918 0.036 158);

  --s1: 8px; --s2: 14px; --s3: 20px; --s4: 28px; --s5: 40px; --s6: 60px; --s7: 84px;

  --r-sm:   12px;
  --r:      20px;
  --r-lg:   28px;
  --r-pill: 999px;
  /* A speech bubble keeps one corner tight — that is what makes it read as
     said rather than as another box. */
  --r-said: 22px 22px 22px 6px;
  --r-mine: 22px 22px 6px 22px;

  --shadow-1: 0 1px 2px oklch(0.285 0.028 265 / .06), 0 4px 14px oklch(0.285 0.028 265 / .06);
  --shadow-2: 0 2px 6px oklch(0.285 0.028 265 / .07), 0 18px 40px oklch(0.285 0.028 265 / .13);
  --ease:      cubic-bezier(.2, .7, .2, 1);
  --ease-back: cubic-bezier(.34, 1.42, .64, 1);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--room); color: var(--ink);
  font-family: var(--font-sans); font-size: 16px; line-height: 1.6;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  /* The machinery, barely visible: a technical grid under a domestic colour. */
  background-image:
    linear-gradient(oklch(0.285 0.028 265 / .028) 1px, transparent 1px),
    linear-gradient(90deg, oklch(0.285 0.028 265 / .028) 1px, transparent 1px);
  background-size: 34px 34px;
}
a { color: inherit; }
button, input, textarea { font: inherit; }
:focus-visible { outline: 2.5px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
::selection { background: var(--accent-soft); color: var(--ink); }

/* ---- Top bar ------------------------------------------------------------- */
.top {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: var(--s4);
  padding: var(--s2) clamp(18px, 4vw, 44px);
  background: oklch(0.912 0.010 85 / .86); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 11px; font-weight: 650; letter-spacing: -.012em; flex: none; }
.brand .sub { display: block; font-family: var(--font-mono); font-size: 10.5px; font-weight: 400;
              color: var(--faint); letter-spacing: .06em; text-transform: uppercase; }
.mark {
  width: 34px; height: 34px; flex: none; display: grid; place-items: center;
  border-radius: 11px; font-weight: 800; font-size: 14px; color: var(--card);
  background: linear-gradient(145deg, var(--iris), var(--accent-deep));
  box-shadow: 0 3px 12px oklch(0.475 0.105 258 / .30);
}
.nav { display: flex; gap: 2px; flex: 1; }
.nav a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 15px;
  text-decoration: none; color: var(--muted); font-size: 14.5px; font-weight: 500;
  border-radius: var(--r-pill); transition: color .18s var(--ease), background .18s var(--ease);
}
.nav a:hover { color: var(--ink); background: oklch(1 0 0 / .55); }
.nav a.on { color: var(--accent-deep); background: var(--card); font-weight: 650; box-shadow: var(--shadow-1); }
.nav a .n {
  margin-left: 8px; min-width: 21px; height: 21px; padding: 0 6px;
  display: inline-grid; place-items: center; border-radius: var(--r-pill);
  font-size: 11px; font-weight: 700; color: var(--card); background: var(--peach-ink);
}
.top .right { display: flex; align-items: center; gap: var(--s2); flex: none; }
.who { text-align: right; line-height: 1.25; }
.who .n { font-size: 13.5px; font-weight: 600; }
.who .o { font-family: var(--font-mono); font-size: 10.5px; color: var(--faint); letter-spacing: .04em; }
.me {
  width: 38px; height: 38px; flex: none; display: grid; place-items: center; cursor: pointer;
  border-radius: 13px; font-size: 12.5px; font-weight: 700; color: var(--card);
  background: linear-gradient(145deg, var(--peach), var(--peach-ink));
}
@media (max-width: 800px) { .nav, .who { display: none; } }

/* ---- Page ---------------------------------------------------------------- */
.wrap { max-width: 1020px; margin: 0 auto; padding: var(--s6) clamp(18px, 4vw, 44px) var(--s7); }
.wrap.narrow { max-width: 800px; }

/* The mono label is the technical half of the voice: every warm sentence is
   answered somewhere by a precise little tag. */
.tag {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
}
.tag .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--iris); flex: none; }
.tag.live .dot { animation: breathe 2.4s var(--ease) infinite; }

h1.display {
  font-family: var(--font-serif); font-weight: 600;
  font-size: clamp(34px, 4.8vw, 56px); line-height: 1.06; letter-spacing: -.028em; margin: 0 0 var(--s3);
}
h1.display em { font-style: italic; color: var(--accent-deep); }
.lede { font-size: 17px; line-height: 1.72; color: var(--muted); max-width: 58ch; margin: 0; }
.h-sec {
  display: flex; align-items: center; gap: 12px; margin: 0 0 var(--s3);
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--faint);
}
.h-sec::after { content: ""; flex: 1; height: 1px; background: var(--line-2); }
.h-sec .n { color: var(--accent-deep); font-weight: 700; }
.h-sec.warm .n { color: var(--peach-ink); }

/* ---- Paper on stone ------------------------------------------------------ */
.card {
  background: var(--card); border: 1px solid oklch(1 0 0 / .7);
  border-radius: var(--r-lg); box-shadow: var(--shadow-1);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.card.pad { padding: var(--s4); }
.card.lift:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.card.quiet { background: var(--card-2); box-shadow: none; border-color: var(--line); }

/* ---- The conversation ---------------------------------------------------
   Marta's side is a bubble with a tight bottom-left corner and a face beside
   it; the client's side is a bubble with a tight bottom-right corner and no
   face — you do not need to be shown your own picture. */
.talk { display: flex; flex-direction: column; gap: var(--s3); }
.said { display: flex; gap: 13px; align-items: flex-start; }
.said .face {
  width: 40px; height: 40px; flex: none; display: grid; place-items: center;
  border-radius: 14px; font-size: 12.5px; font-weight: 700; color: var(--card);
  background: linear-gradient(145deg, var(--iris), var(--accent-deep));
}
.said .bubble {
  position: relative; max-width: 62ch; padding: var(--s3) var(--s3) calc(var(--s3) - 2px);
  background: var(--card); border-radius: var(--r-said); box-shadow: var(--shadow-1);
}
.said .bubble p { margin: 0 0 11px; font-size: 16px; line-height: 1.68; }
.said .bubble p:last-child { margin-bottom: 0; }
.said .bubble strong { font-weight: 650; }
.said .from { display: flex; align-items: baseline; gap: 9px; margin-bottom: 7px; }
.said .from b { font-size: 14px; font-weight: 650; }
.said .from span { font-family: var(--font-mono); font-size: 10.5px; color: var(--faint); letter-spacing: .04em; }

.mine { display: flex; justify-content: flex-end; }
.mine .bubble {
  max-width: 52ch; padding: var(--s2) var(--s3);
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: var(--r-mine); font-size: 15px; color: var(--accent-deep); font-weight: 500;
}

/* Replies: the client answers by pressing one, so they are sized and spaced
   like real controls, not like links dressed as chat. */
.replies { display: flex; flex-wrap: wrap; gap: 9px; justify-content: flex-end; }

/* ---- Buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 46px; padding: 11px 22px; cursor: pointer;
  font-size: 15px; font-weight: 600; border: 1px solid transparent; border-radius: var(--r-pill);
  transition: transform .16s var(--ease), box-shadow .22s var(--ease), background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn-primary { color: var(--card); background: var(--accent); box-shadow: 0 6px 18px oklch(0.475 0.105 258 / .26); }
.btn-primary:hover { background: var(--accent-deep); box-shadow: 0 10px 26px oklch(0.475 0.105 258 / .34); }
.btn-warm { color: var(--card); background: var(--peach-ink); box-shadow: 0 6px 18px oklch(0.505 0.115 48 / .26); }
.btn-warm:hover { box-shadow: 0 10px 26px oklch(0.505 0.115 48 / .36); }
.btn-soft { color: var(--ink); background: var(--card); border-color: var(--line-2); box-shadow: var(--shadow-1); }
.btn-soft:hover { border-color: var(--accent); color: var(--accent-deep); }
.btn-plain { color: var(--muted); background: transparent; }
.btn-plain:hover { color: var(--ink); background: oklch(1 0 0 / .6); }
.btn-sm { min-height: 42px; padding: 9px 17px; font-size: 14px; }
@media (pointer: coarse) { .btn-sm { min-height: 44px; } }

.link { color: var(--accent-deep); font-weight: 600; text-decoration: none; border-bottom: 1.5px solid var(--accent-line); }
.link:hover { border-bottom-color: var(--accent-deep); }

/* ---- Badges, chips, facts ------------------------------------------------ */
.badge {
  display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px;
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
  border-radius: var(--r-pill); border: 1px solid var(--line-2); color: var(--muted); background: var(--card);
}
.badge i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.badge.you  { color: var(--peach-ink); background: var(--peach-soft); border-color: oklch(0.760 0.115 48 / .45); }
.badge.live { color: var(--iris-ink); background: var(--iris-soft); border-color: oklch(0.640 0.135 282 / .40); }
.badge.ok   { color: var(--ok); background: var(--ok-soft); border-color: oklch(0.480 0.090 158 / .35); }

.chip {
  display: inline-flex; align-items: center; min-height: 42px; padding: 8px 16px; cursor: pointer;
  font-size: 14px; font-weight: 500; color: var(--muted);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-pill);
  transition: color .18s var(--ease), border-color .18s var(--ease), transform .18s var(--ease);
}
.chip:hover { color: var(--ink); border-color: var(--line-2); transform: translateY(-1px); }
.chip.on { color: var(--card); background: var(--accent); border-color: var(--accent); font-weight: 600; }
@media (pointer: coarse) { .chip { min-height: 44px; } }

.facts { display: grid; grid-template-columns: auto 1fr; gap: 12px var(--s4); margin: 0; font-size: 14.5px; }
.facts dt { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
             color: var(--faint); align-self: center; }
.facts dd { margin: 0; text-align: right; font-weight: 550; }

.code { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .03em; color: var(--faint); }

/* ---- Rows ---------------------------------------------------------------- */
.rows { display: flex; flex-direction: column; gap: var(--s2); }
.rowcard {
  position: relative; overflow: hidden; display: grid; grid-template-columns: 1fr auto;
  align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s4); text-decoration: none; color: inherit;
  background: var(--card); border: 1px solid oklch(1 0 0 / .7); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  transition: transform .28s var(--ease), box-shadow .28s var(--ease);
}
.rowcard::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--accent); transform: scaleY(0); transition: transform .28s var(--ease-back);
}
.rowcard.yours::before { background: var(--peach); }
.rowcard:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.rowcard:hover::before, .rowcard:focus-visible::before { transform: scaleY(1); }
.rowcard h3 { font-size: 17.5px; font-weight: 650; letter-spacing: -.016em; margin: 0 0 5px; }
.rowcard .meta { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 11px; font-size: 13.5px; color: var(--muted); }
.rowcard .meta .sep { color: var(--line-2); }
.rowcard .aside { display: flex; align-items: center; gap: var(--s3); justify-self: end; }
.rowcard .note { font-size: 13.5px; color: var(--muted); max-width: 30ch; text-align: right; }
.rowcard .note b { color: var(--ink); font-weight: 600; }
@media (max-width: 840px) {
  .rowcard { grid-template-columns: 1fr; }
  .rowcard .aside { justify-self: start; flex-wrap: wrap; }
  .rowcard .note { text-align: left; max-width: none; }
}

/* ---- Steps — where a search has got, said in words ----------------------- */
.steps { display: flex; align-items: center; gap: 5px; }
.steps i {
  width: 20px; height: 5px; border-radius: 3px; background: var(--line-2);
  transform: scaleX(.3); transform-origin: 0 50%; opacity: .5;
  transition: transform .45s var(--ease-back), opacity .35s var(--ease), background .35s var(--ease);
}
.in .steps i { transform: scaleX(1); opacity: 1; }
.in .steps i.done { background: var(--accent); }
.in .steps i.here { background: var(--iris); }
.steps i:nth-child(1){transition-delay:.04s} .steps i:nth-child(2){transition-delay:.09s}
.steps i:nth-child(3){transition-delay:.14s} .steps i:nth-child(4){transition-delay:.19s}
.steps i:nth-child(5){transition-delay:.24s} .steps i:nth-child(6){transition-delay:.29s}

/* ---- Stats --------------------------------------------------------------- */
.stat .n { font-family: var(--font-serif); font-size: clamp(34px, 4.4vw, 50px); font-weight: 600;
           line-height: 1; letter-spacing: -.035em; font-variant-numeric: tabular-nums; }
.stat .n.warm { color: var(--peach-ink); }
.stat .n.live { color: var(--iris-ink); }
.stat .k { font-size: 14px; color: var(--muted); margin-top: 9px; }

/* ---- Fields -------------------------------------------------------------- */
.field { margin-bottom: var(--s3); }
.field label { display: block; font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 7px; }
.field input {
  width: 100%; min-height: 50px; padding: 13px 16px; font-size: 15.5px; color: var(--ink);
  background: var(--card-2); border: 1.5px solid var(--line-2); border-radius: var(--r-sm); outline: none;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease);
}
.field input::placeholder { color: var(--faint); }
.field input:focus { border-color: var(--accent); background: var(--card); box-shadow: 0 0 0 4px var(--accent-soft); }
.hint { font-size: 13px; color: var(--faint); margin: -6px 0 var(--s3); }

/* ---- Motion --------------------------------------------------------------
   Quieter than Bloom on purpose. A page that talks to you should not also
   perform: bubbles arrive the way a message arrives, and nothing else moves. */
@keyframes rise    { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes pop     { from { opacity: 0; transform: translateY(16px) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes breathe { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.82); } }

.rise { animation: rise .7s var(--ease) both; }
.pop  { animation: pop .55s var(--ease-back) both; }
.d1{animation-delay:.06s} .d2{animation-delay:.14s} .d3{animation-delay:.22s} .d4{animation-delay:.30s}
.d5{animation-delay:.38s} .d6{animation-delay:.46s} .d7{animation-delay:.54s}

.js .reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js .reveal.in { opacity: 1; transform: none; }

/* Bubbles use the skill's back.out curve with a slight scale — it is the one
   easing that reads as "landed" rather than "faded in". */
.js .stagger > * { opacity: 0; transform: translateY(16px) scale(.95); transition: opacity .45s var(--ease), transform .5s var(--ease-back); }
.js .stagger.in > * { opacity: 1; transform: none; }
.stagger.in > *:nth-child(1){transition-delay:.00s} .stagger.in > *:nth-child(2){transition-delay:.09s}
.stagger.in > *:nth-child(3){transition-delay:.18s} .stagger.in > *:nth-child(4){transition-delay:.27s}
.stagger.in > *:nth-child(5){transition-delay:.36s} .stagger.in > *:nth-child(6){transition-delay:.45s}

/* ---- Switcher (not part of the design) ----------------------------------- */
.style-switch {
  position: fixed; bottom: 18px; right: 18px; z-index: 70;
  display: flex; align-items: center; gap: 4px; padding: 5px 5px 5px 13px;
  background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r-pill);
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--faint); box-shadow: var(--shadow-2);
}
.style-switch a {
  min-width: 32px; text-align: center; padding: 6px 11px; border-radius: var(--r-pill);
  text-decoration: none; color: var(--muted); font-family: var(--font-sans);
  font-size: 12px; font-weight: 600; letter-spacing: 0; text-transform: none;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.style-switch a:hover { background: var(--card-2); color: var(--ink); }
.style-switch a.on { background: var(--accent); color: var(--card); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal, .stagger > * { opacity: 1; transform: none; }
  .steps i { transform: scaleX(1); opacity: 1; }
}

/* ============================================================================
   EFFECTS LAYER
   ----------------------------------------------------------------------------
   Pushed further, but kept inside the metaphor: this page is a conversation,
   so the strongest effects are the ones a conversation actually has — a reply
   being typed, a message landing, a page handing over to the next. Anything
   that would read as a showreel stays out.
   ============================================================================ */

/* ---- 1. Cross-page transitions ------------------------------------------
   Native View Transitions. Same-origin navigation between these three files
   cross-fades and carries the shared header across instead of flashing white.
   Unsupported browsers simply navigate — nothing to fall back to. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vt-out .28s var(--ease) both; }
::view-transition-new(root) { animation: vt-in  .42s var(--ease) both; }
@keyframes vt-out { to { opacity: 0; transform: translateY(-8px) scale(.994); } }
@keyframes vt-in  { from { opacity: 0; transform: translateY(12px) scale(.994); } }
.top       { view-transition-name: topbar; }
.talk-head { view-transition-name: talkhead; }

/* ---- 2. Someone is typing ----------------------------------------------
   Marta's bubbles are preceded by three dots for a beat. It is the one effect
   here that carries meaning no static layout can: a person is composing this,
   and it is arriving now. */
.typing { display: inline-flex; align-items: center; gap: 5px; padding: 15px 18px;
          background: var(--card); border-radius: var(--r-said); box-shadow: var(--shadow-1); }
.typing i { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); opacity: .45;
            animation: typing 1.25s var(--ease) infinite; }
.typing i:nth-child(2) { animation-delay: .16s; }
.typing i:nth-child(3) { animation-delay: .32s; }
@keyframes typing { 0%,60%,100% { transform: translateY(0); opacity: .35; } 30% { transform: translateY(-5px); opacity: 1; } }
.said[data-typing] > .bubble { display: none; }
.said[data-typing].spoken > .bubble { display: block; animation: pop .5s var(--ease-back) both; }
.said[data-typing].spoken > .typing { display: none; }

/* ---- 3. Headlines opened by a mask --------------------------------------
   The line is wiped open rather than faded in — a fade says "loading", a wipe
   says "written". */
.js .wipe { clip-path: inset(0 100% 0 0); transition: clip-path 1.05s var(--ease); }
.js .wipe.in { clip-path: inset(0 0 0 0); }

/* ---- 4. Paper answers the pointer ---------------------------------------
   Two things at once, both cheap: a soft light under the cursor, and a lift.
   No tilt here — tilting a page that is speaking to you makes it a toy. */
.glow { position: relative; overflow: hidden; }
.glow::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: radial-gradient(300px circle at var(--mx, 50%) var(--my, 50%), oklch(0.640 0.135 282 / .13), transparent 66%);
  opacity: 0; transition: opacity .4s var(--ease);
}
.glow:hover::after { opacity: 1; }

/* Rows shift their content a hair on hover, which reads as depth without
   moving the row itself and reflowing the list. */
.rowcard .shift { transition: transform .38s var(--ease-back); }
.rowcard:hover .shift { transform: translateX(6px); }

/* ---- 5. The bar contracts once you start reading ------------------------ */
.top { transition: padding .3s var(--ease), background .3s var(--ease), box-shadow .3s var(--ease); }
.top.tight { padding-top: 7px; padding-bottom: 7px; box-shadow: 0 6px 20px oklch(0.285 0.028 265 / .09); }
.top.tight .mark { transform: scale(.9); transition: transform .3s var(--ease-back); }

/* ---- 6. Scroll thread ----------------------------------------------------
   A hairline that fills as you read — the same gradient as a search's steps,
   so the page and the process are measured in the same ink. */
.thread { position: fixed; inset: 0 0 auto; height: 3px; z-index: 80; transform-origin: 0 50%;
          transform: scaleX(var(--p, 0)); background: linear-gradient(90deg, var(--accent), var(--iris), var(--peach)); }

/* ---- 7. Press ------------------------------------------------------------ */
.btn { position: relative; overflow: hidden; }
.btn:active { transform: scale(.97); }
.ripple { position: absolute; border-radius: 50%; pointer-events: none; background: currentColor;
          opacity: .22; transform: scale(0); animation: ripple .6s var(--ease) forwards; }
@keyframes ripple { to { transform: scale(2.8); opacity: 0; } }

/* ---- 8. Numbers arrive lit ---------------------------------------------- */
.stat .n {
  background: linear-gradient(100deg, currentColor 30%, var(--iris) 50%, currentColor 70%);
  background-size: 260% 100%; background-position: 100% 0;
  -webkit-background-clip: text; background-clip: text;
  transition: background-position 1.6s var(--ease) .35s;
}
.in .stat .n, .stat.in .n { background-position: 0 0; }

/* ---- 9. Steps that fill left to right ----------------------------------- */
.in .steps i.here { animation: hereGlow 2.6s var(--ease) infinite; }
@keyframes hereGlow { 0%,100% { box-shadow: 0 0 0 0 oklch(0.640 0.135 282 / .40); } 55% { box-shadow: 0 0 0 5px transparent; } }

@media (prefers-reduced-motion: reduce) {
  .js .wipe { clip-path: none !important; }
  .typing { display: none !important; }
  .said[data-typing] > .bubble { display: block !important; }
  .stat .n { background: none; -webkit-background-clip: initial; background-clip: initial; color: inherit; }
  .thread { display: none; }
  @view-transition { navigation: none; }
}
