/* ============================================================================
   The client portal's own stylesheet — the "Lagoon" direction, chosen 2026-08-10.
   ----------------------------------------------------------------------------
   Deliberately not part of the internal Tailwind bundle. The two worlds are
   segregated in routing, permissions and queries; sharing a stylesheet would
   be the one seam left, and it would mean a class renamed for the internal app
   could silently restyle a screen a client is looking at.

   It is plain CSS on purpose: no build step, no watcher, nothing to remember
   before a deploy. Fonts are the house faces, served from assets/fonts.

   Provenance: platform-mockups/assets/lagoon.css. If the mockup changes, the
   change is copied here on purpose rather than shared, so the shipped portal
   never moves because somebody was sketching.
   ============================================================================ */

/* ============================================================================
   Platform — "Lagoon" direction, PP (partner portal)
   ----------------------------------------------------------------------------
   Second attempt at the client's brief, and the one that reads it literally.

   Tide took Harbor and recoloured it. That is a different thing from what was
   asked, because what separates Bloom from Harbor is not the palette — it is
   the material:

       Bloom     air (spacing scale 35% wider), 36px corners with one clipped,
                 16px body, a serif that is allowed to be big, three blurred
                 fields drifting behind the paper, headlines that resolve word
                 by word, a path that draws itself.
       Harbor    tight scale, 22px corners, 15px body, monospace on every
                 label, twelve columns, a full profile, the assistant in the
                 top bar.

   Lagoon takes the MATERIAL from Bloom and the ARRANGEMENT from Harbor. So:
   Bloom's air, Bloom's soft geometry, Bloom's type, Bloom's effects — laid out
   on Harbor's twelve-column grid, with Harbor's density of information and its
   assistant in the bar.

   COLOUR: Petrol as the secondary set, exactly as asked. The sign-in is Petrol
   untouched (`body.deep`), and inside, the paper keeps Bloom's lightness with
   its hue moved onto Petrol's side of the wheel — warm ivory beside cold teal
   reads as two brands stapled at the login. Gold is gone: Bloom's warm light
   is replaced by Petrol's own water for anything live, and amber survives only
   where something waits on the client.
   ============================================================================ */

@font-face { font-family: "Fraunces"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/fraunces-500.9fe3e924d0d2.woff2") format("woff2"); }
@font-face { font-family: "Fraunces"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/fraunces-600.cc3e6b3f975c.woff2") format("woff2"); }
@font-face { font-family: "Fraunces"; font-style: italic; font-weight: 500; font-display: swap; src: url("../fonts/fraunces-italic-500.3d15406bbc1a.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/inter-400.cef6d3a6737e.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/inter-500.861c7a6706fe.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/inter-600.ca03b7ee20d3.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/inter-700.64d12f9f7d82.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;

  /* Bloom's paper, cooled onto Petrol's hue. Lightness untouched. */
  --paper:   oklch(0.976 0.008 202);
  --paper-2: oklch(0.955 0.011 202);
  --card:    oklch(1 0 0);
  --card-2:  oklch(0.982 0.006 202);

  --ink:    oklch(0.258 0.038 220);
  --muted:  oklch(0.446 0.030 218);
  --faint:  oklch(0.548 0.026 216);
  --line:   oklch(0.902 0.013 206);
  --line-2: oklch(0.846 0.019 205);

  /* Petrol as the secondary set. --accent-lit is Petrol's own accent value. */
  --accent:      oklch(0.470 0.098 208);
  --accent-deep: oklch(0.356 0.086 210);
  --accent-lit:  oklch(0.760 0.108 199);
  --accent-soft: oklch(0.946 0.030 203);
  --accent-line: oklch(0.854 0.052 203);
  --on-accent:   oklch(0.99 0.004 205);

  --deep:   oklch(0.245 0.048 218);
  --deep-2: oklch(0.315 0.068 210);
  --glow-1: oklch(0.925 0.055 196);
  --glow-2: oklch(0.795 0.095 200);

  --amber:      oklch(0.760 0.115 62);
  --amber-ink:  oklch(0.492 0.110 58);
  --amber-soft: oklch(0.945 0.042 62);

  --ok:      oklch(0.470 0.090 158);
  --ok-soft: oklch(0.930 0.036 158);
  --no:      oklch(0.520 0.150 28);
  --no-soft: oklch(0.955 0.032 28);

  /* Bloom's air, one notch in — this page carries a whole profile, so 96px of
     section spacing would turn reading into scrolling. */
  --s1: 8px; --s2: 14px; --s3: 20px; --s4: 28px; --s5: 40px; --s6: 60px; --s7: 84px;

  /* Bloom's geometry: large radii, and one corner clipped so a card reads as
     drawn rather than as a browser default. */
  --r-sm:   14px;
  --r:      24px;
  --r-lg:   32px;
  --r-leaf: 32px 32px 32px 8px;
  --r-pill: 999px;

  --shadow-1: 0 1px 2px oklch(0.258 0.038 220 / .05), 0 6px 20px oklch(0.258 0.038 220 / .06);
  --shadow-2: 0 2px 6px oklch(0.258 0.038 220 / .06), 0 22px 48px oklch(0.258 0.038 220 / .12);
  --ease:      cubic-bezier(.2, .7, .2, 1);
  --ease-expo: cubic-bezier(.16, 1, .3, 1);
  --ease-back: cubic-bezier(.34, 1.42, .64, 1);
}

/* The lights off: Petrol's own values, for the sign-in. */
body.deep {
  --paper:   oklch(0.185 0.030 220);
  --paper-2: oklch(0.212 0.034 219);
  --card:    oklch(0.243 0.038 217);
  --card-2:  oklch(0.285 0.042 215);
  --ink:     oklch(0.970 0.008 210);
  --muted:   oklch(0.790 0.018 210);
  --faint:   oklch(0.685 0.022 210);
  --line:    oklch(0.345 0.035 214);
  --line-2:  oklch(0.415 0.040 212);
  --accent:      oklch(0.760 0.108 199);
  --accent-deep: oklch(0.845 0.098 197);
  --accent-soft: oklch(0.760 0.108 199 / .13);
  --accent-line: oklch(0.760 0.108 199 / .32);
  --on-accent:   oklch(0.160 0.030 220);
  --shadow-1: 0 1px 2px oklch(0 0 0 / .30), 0 4px 14px oklch(0 0 0 / .22);
  --shadow-2: 0 18px 48px oklch(0 0 0 / .40), 0 2px 8px oklch(0 0 0 / .30);
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--paper); color: var(--ink);
  font-family: var(--font-sans); font-size: 16px; line-height: 1.62;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
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); }

/* ---- Bloom's drifting fields, in Petrol's colours ------------------------ */
.blooms { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.blooms span { position: absolute; border-radius: 50%; filter: blur(84px); opacity: .5; will-change: transform; }
.blooms .b1 { width: 46vw; height: 46vw; top: -16vw; right: -10vw; background: oklch(0.760 0.108 199 / .34); animation: drift 30s ease-in-out infinite; }
.blooms .b2 { width: 38vw; height: 38vw; bottom: -14vw; left: -12vw; background: oklch(0.545 0.105 205 / .18); animation: drift 38s ease-in-out infinite reverse; }
.blooms .b3 { width: 24vw; height: 24vw; top: 48%; right: 26%; background: oklch(0.925 0.055 196 / .40); animation: drift 34s ease-in-out -12s infinite; }
body > *:not(.blooms) { position: relative; z-index: 1; }

/* ---- Top bar (Harbor's arrangement, Bloom's softness) -------------------- */
.top { position: sticky; top: 0; z-index: 60; display: flex; align-items: center; gap: var(--s4);
       padding: var(--s2) clamp(18px, 3.4vw, 40px);
       background: color-mix(in oklab, var(--paper) 84%, transparent);
       backdrop-filter: blur(16px) saturate(1.15); border-bottom: 1px solid var(--line);
       transition: padding .3s var(--ease), box-shadow .3s var(--ease); }
.top.tight { padding-top: 8px; padding-bottom: 8px; box-shadow: 0 6px 22px oklch(0.258 0.038 220 / .08); }
.brand { display: flex; align-items: center; gap: 11px; font-weight: 650; letter-spacing: -.012em; flex: none; }
.brand .sub { display: block; font-size: 11px; font-weight: 500; color: var(--faint); letter-spacing: .04em; }
.mark { width: 34px; height: 34px; flex: none; display: grid; place-items: center; border-radius: var(--r-leaf);
        font-weight: 800; font-size: 14px; color: var(--on-accent);
        background: linear-gradient(145deg, var(--glow-2), var(--accent));
        box-shadow: 0 4px 14px oklch(0.470 0.098 208 / .28); }
.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: color-mix(in oklab, var(--ink) 5%, transparent); }
.nav a.on { color: var(--accent); background: var(--accent-soft); font-weight: 650; }
body.deep .nav a.on { color: var(--accent-deep); }
.nav a .n { margin-left: 8px; min-width: 20px; height: 20px; 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(--amber-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-size: 11.5px; color: var(--faint); }
.me { width: 38px; height: 38px; flex: none; display: grid; place-items: center; cursor: pointer;
      border-radius: var(--r-leaf); font-size: 12.5px; font-weight: 700; color: var(--on-accent);
      background: linear-gradient(145deg, var(--glow-2), var(--deep-2)); }
@media (max-width: 860px) { .nav, .who { display: none; } }

/* ---- Frame --------------------------------------------------------------- */
.wrap { max-width: 1280px; margin: 0 auto; padding: var(--s6) clamp(18px, 3.4vw, 40px) var(--s7); }

.eyebrow { display: inline-flex; align-items: center; gap: 8px; margin: 0 0 var(--s2);
           font-size: 11.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); }
body.deep .eyebrow { color: var(--accent-deep); }
.eyebrow .leaf { width: 9px; height: 9px; flex: none; border-radius: 0 9px 0 9px; background: var(--accent-lit); }
.eyebrow.live .leaf { animation: breathe 2.6s var(--ease) infinite; }

h1.display { font-family: var(--font-serif); font-weight: 600;
             font-size: clamp(36px, 5.2vw, 62px); line-height: 1.02; letter-spacing: -.03em; margin: 0 0 var(--s3); }
h1.display em { font-style: italic; color: var(--accent); }
body.deep h1.display em { color: var(--accent-deep); }
h2.big { font-family: var(--font-serif); font-weight: 600; font-size: clamp(24px, 2.6vw, 30px);
         letter-spacing: -.024em; line-height: 1.15; margin: 0 0 var(--s2); }
.lede { font-size: 17px; line-height: 1.72; color: var(--muted); max-width: 58ch; margin: 0; }

/* Bloom's section rule: no monospace. Letterspaced caps and a hairline. */
.h-sec { display: flex; align-items: center; gap: 12px; margin: 0 0 var(--s3);
         font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--faint); }
.h-sec::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.h-sec .n { color: var(--accent); }
.h-sec.warm .n { color: var(--amber-ink); }
/* Il titolo di un gruppo dentro una sezione: i colloqui fissati, in attesa, da
   valutare (voce 6). Sotto `.h-sec`, che resta il titolo della sezione: più
   piccolo, senza filetto, e nel colore del testo secondario. */
.h-sub { margin: 0 0 6px; font-size: 11.5px; font-weight: 700; letter-spacing: .1em;
         text-transform: uppercase; color: var(--muted); }

/* ---- Harbor's grid ------------------------------------------------------- */
.g12 { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--s3); align-items: start; }
.c3{grid-column:span 3}.c4{grid-column:span 4}.c5{grid-column:span 5}.c6{grid-column:span 6}
.c7{grid-column:span 7}.c8{grid-column:span 8}.c12{grid-column:span 12}
@media (max-width: 1100px) { .c3,.c4{grid-column:span 6} .c5,.c7,.c8{grid-column:span 12} }
@media (max-width: 700px) { .g12 > * { grid-column: span 12 !important; } }

.card { position: relative; background: var(--card); border: 1px solid var(--line);
        border-radius: var(--r-lg); box-shadow: var(--shadow-1);
        transition: transform .3s var(--ease-expo), box-shadow .3s var(--ease), border-color .22s var(--ease); }
body:not(.deep) .card { border-color: oklch(1 0 0 / .72); }
.card.pad { padding: var(--s4); }
.card.leaf { border-radius: var(--r-leaf); }
.card.quiet { background: var(--card-2); box-shadow: none; border-color: var(--line); }
.card.lift:hover { transform: translateY(-3px) scale(1.004); box-shadow: var(--shadow-2); border-color: var(--accent-line); }
.card.deep-panel { background: linear-gradient(165deg, var(--deep-2), var(--deep)); border-color: transparent;
                   color: oklch(0.97 0.008 210); }
.card.deep-panel .h-sec { color: oklch(0.97 0.008 210 / .5); }
.card.deep-panel .h-sec::after { background: oklch(1 0 0 / .14); }

/* ---- Buttons (Bloom's pills) --------------------------------------------- */
.btn { position: relative; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; gap: 9px;
       min-height: 48px; padding: 12px 26px; cursor: pointer; font-size: 15px; font-weight: 600; letter-spacing: -.005em;
       border: 1px solid transparent; border-radius: var(--r-pill);
       transition: transform .18s var(--ease), box-shadow .22s var(--ease), background .22s var(--ease), color .22s var(--ease), border-color .22s var(--ease); }
.btn-primary { color: var(--on-accent); background: var(--accent); box-shadow: 0 8px 22px oklch(0.470 0.098 208 / .26); }
.btn-primary:hover { background: var(--accent-deep); box-shadow: 0 14px 30px oklch(0.470 0.098 208 / .34); }
.btn-warm { color: var(--card); background: var(--amber-ink); box-shadow: 0 8px 22px oklch(0.492 0.110 58 / .26); }
.btn-warm:hover { box-shadow: 0 14px 32px oklch(0.492 0.110 58 / .38); }
.btn-ghost { color: var(--ink); background: transparent; border-color: var(--line-2); }
.btn-ghost:hover { border-color: var(--accent); background: var(--accent-soft); }
.btn-quiet { color: var(--muted); background: transparent; }
.btn-quiet:hover { color: var(--no); background: var(--no-soft); }

/* Il «Proponi» dentro la modale colloquio: stessa famiglia del bottone che
   manda davvero la richiesta (petrolio, `.btn-primary`), ma solo bordo — due
   pesi della stessa idea, non due colori diversi che si contendono l'occhio
   in una finestra piccola dove stanno vicini. */
.btn-accent-ghost { color: var(--accent-deep); background: var(--accent-soft); border-color: var(--accent-line); }
.btn-accent-ghost:hover { background: var(--accent-soft); border-color: var(--accent); }
.btn-sm { min-height: 42px; padding: 9px 18px; font-size: 14px; }
.btn-xs { min-height: 36px; padding: 7px 14px; font-size: 13px; }
@media (pointer: coarse) { .btn-sm, .btn-xs { min-height: 44px; } }
.ripple { position: absolute; border-radius: 50%; pointer-events: none; background: currentColor;
          opacity: .26; transform: scale(0); animation: ripple .62s var(--ease-expo) forwards; }
.link { color: var(--accent); font-weight: 600; text-decoration: none; border-bottom: 1.5px solid var(--accent-line); }
.link:hover { border-bottom-color: var(--accent); }

.chip { display: inline-flex; align-items: center; gap: 7px; min-height: 42px; padding: 8px 17px; 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(--on-accent); background: var(--accent); border-color: var(--accent); font-weight: 600; }
@media (pointer: coarse) { .chip { min-height: 44px; } }

.badge { display: inline-flex; align-items: center; gap: 7px; padding: 5px 13px; 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(--paper-2); }
.badge i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.badge.you  { color: var(--amber-ink); background: var(--amber-soft); border-color: oklch(0.760 0.115 62 / .45); }
.badge.live { color: var(--accent); background: var(--accent-soft); border-color: var(--accent-line); }
.badge.ok   { color: var(--ok); background: var(--ok-soft); border-color: oklch(0.470 0.090 158 / .35); }
/* Un numero, non uno stato. Senza colore di proposito: nel portale l'ambra
   vuol dire «aspetta te» e il petrolio «in corso», e prenderne una per dire
   «2 richiesti» rimetterebbe due significati sullo stesso colore. Sta accanto
   allo stato e deve pesare meno di lui. */
.badge.quiet { color: var(--muted); background: var(--paper-2); border-color: var(--line);
               font-weight: 500; }
body.deep .badge { background: oklch(1 0 0 / .06); }
.code { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .03em; color: var(--faint); }

/* ---- Filter pills (a plain GET link each — no script required) ----------- */
.pillbar { display: flex; flex-wrap: wrap; gap: 8px; }
.filter-pill { display: inline-flex; align-items: center; gap: 6px; padding: 7px 15px;
               border-radius: var(--r-pill); font: inherit; font-size: 13px; font-weight: 500;
               color: var(--muted); background: var(--card); border: 1px solid var(--line);
               cursor: pointer; text-decoration: none; transition: border-color .16s var(--ease), color .16s var(--ease), background .16s var(--ease); }
.filter-pill:hover { border-color: var(--accent-line); color: var(--ink); }
.filter-pill.is-on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-deep); font-weight: 650; }
body.deep .filter-pill.is-on { color: var(--accent); }

/* ---- Tooltip immediato --------------------------------------------------
   Lo standard del progetto, al posto dell'attributo `title`: `title` aspetta
   il mezzo secondo del browser, che su una cosa a cui si dà un'occhiata è
   quasi tutto il tempo che le si voleva dedicare, e si veste come il sistema
   operativo invece che come la pagina.

   Qui mancava del tutto. `data-tip` era già scritto in `candidate.html` e non
   mostrava niente, perché questo foglio è separato da quello dell'app interna
   (dove la regola esiste, in `tailwind/input.css`) — e una regola che non c'è
   non avvisa nessuno: l'attributo resta lì, innocuo e muto.

   `data-tip-end` ancora il fumetto al bordo destro di chi lo porta, così si
   allunga verso sinistra. Serve dentro `.rowcard`, che ha `overflow: hidden`:
   un fumetto centrato su un pallino vicino al bordo destro della card
   verrebbe tagliato a metà. */
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip);
  position: absolute; left: 50%; bottom: calc(100% + 7px); transform: translateX(-50%);
  z-index: 40; white-space: nowrap;
  background: var(--deep); color: oklch(0.97 0.008 210);
  font-size: 11.5px; font-weight: 600; line-height: 1; letter-spacing: normal;
  text-transform: none; padding: 6px 9px; border-radius: 8px;
  box-shadow: 0 4px 14px oklch(0.258 0.038 220 / .28);
  opacity: 0; pointer-events: none; transition: opacity .12s var(--ease);
}
[data-tip]:hover::after, [data-tip]:focus-visible::after { opacity: 1; }
[data-tip-end]::after { left: auto; right: 0; transform: none; }
[data-tip-below]::after { bottom: auto; top: calc(100% + 7px); }

/* ---- Bloom's facts (no monospace label) ---------------------------------- */
.facts { display: grid; grid-template-columns: auto 1fr; gap: 12px var(--s4); margin: 0; font-size: 14.5px; }
.facts dt { color: var(--faint); }
.facts dd { margin: 0; text-align: right; font-weight: 550; }
.facts dd.warn { color: var(--amber-ink); }

/* ---- Bloom's path — a search drawn as a line ----------------------------- */
.path { position: relative; margin: 0; padding: 0; list-style: none; }
.path::before { content: ""; position: absolute; left: 11px; top: 10px; bottom: 10px; width: 2px;
                background: var(--line-2); border-radius: 2px; }
.path::after { content: ""; position: absolute; left: 11px; top: 10px; width: 2px; border-radius: 2px;
               height: 0; background: linear-gradient(180deg, var(--accent), var(--accent-lit));
               transition: height 1.5s var(--ease-expo); }
.path.in::after { height: var(--reached, 0%); }
.path li { position: relative; padding: 0 0 var(--s4) 44px; }
.path li:last-child { padding-bottom: 0; }
.path li::before { content: ""; position: absolute; left: 4px; top: 4px; width: 16px; height: 16px; border-radius: 50%;
                   background: var(--card); border: 2px solid var(--line-2);
                   transition: background .4s var(--ease), border-color .4s var(--ease), box-shadow .4s var(--ease); }
/* Fuori da `.in` per la stessa ragione delle icone sulla riga: `.in` la mette
   `reveal.js` quando la sezione entra in vista, e con `prefers-reduced-motion`
   non parte mai — la scaletta restava tutta grigia, senza dire a che punto
   siamo, che è l'unica cosa che deve dire. `.in` tiene la linea che si
   allunga, che è animazione vera. */
.path li.past::before { background: var(--accent); border-color: var(--accent); }
.path li.now::before  { background: var(--accent); border-color: var(--accent);
                        box-shadow: 0 0 0 6px var(--accent-soft); }
.path .t { font-size: 15.5px; font-weight: 600; }
.path .m { font-size: 13.5px; color: var(--faint); margin-top: 2px; }
.path li.now .t { color: var(--accent-deep); }

/* ---- Skills: Bloom's softness on Harbor's data --------------------------- */
.skills { display: grid; gap: 11px; }
.skill { display: grid; grid-template-columns: 1fr 90px auto; align-items: center; gap: 14px; font-size: 14.5px; }
.skill .nm { font-weight: 550; }
.skill .bar { height: 8px; border-radius: var(--r-pill); background: color-mix(in oklab, var(--ink) 9%, transparent); overflow: hidden; }
.skill .bar i { display: block; height: 100%; width: var(--lv, 50%); border-radius: var(--r-pill); background: var(--line-2);
                transition: width 1.1s var(--ease-expo); }
.js .skill .bar i { width: 0; }
.js .in .skill .bar i, .js .skills.in .skill .bar i { width: var(--lv, 50%); }
.skill.req .nm { color: var(--accent); font-weight: 650; }
.skill.req .bar i { background: linear-gradient(90deg, var(--accent-deep), var(--accent-lit)); }
.skill .yr { font-size: 13px; color: var(--faint); white-space: nowrap; }

/* ---- Career ------------------------------------------------------------- */
.tl { list-style: none; margin: 0; padding: 0; }
.tl li { position: relative; padding: 0 0 var(--s4) var(--s5); }
.tl li:last-child { padding-bottom: 0; }
.tl li::before { content: ""; position: absolute; left: 4px; top: 6px; width: 14px; height: 14px; border-radius: 50%;
                 background: var(--card); border: 2px solid var(--line-2); }
.tl li.hi::before { background: var(--accent); border-color: var(--accent); }
.tl li::after { content: ""; position: absolute; left: 10px; top: 22px; bottom: 4px; width: 2px; background: var(--line); border-radius: 2px; }
.tl li:last-child::after { display: none; }
.tl .role { font-size: 16px; font-weight: 650; letter-spacing: -.014em; }
.tl .co { font-size: 14.5px; color: var(--muted); }
.tl .when { font-size: 13px; color: var(--faint); margin-top: 3px; }
.tl .did { font-size: 14.5px; color: var(--muted); margin-top: 8px; line-height: 1.68; }
.tl .stack { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.tl .stack span { font-size: 12.5px; color: var(--accent); background: var(--accent-soft);
                  border: 1px solid var(--accent-line); border-radius: var(--r-sm); padding: 3px 10px; }

/* ---- Rows --------------------------------------------------------------- */
.rows { display: flex; flex-direction: column; gap: var(--s2); }
/* The aside is a fixed width, not `auto`: each `.rowcard` is its own grid, so
   an `auto` column is sized off *that row's* content alone — a row with a
   "N proposti · ieri" label got a wider column than one without, and the
   badge, sitting first inside it, landed at a different x on every row. Rows
   of the same list read as a list because their badges line up; fixed-width
   is what makes that guaranteed rather than incidental. `.aside` stacks its
   own content (badge, then dots+label) instead of setting it side by side, so
   the width does not depend on which of the two happens to be longer either. */
.rowcard { position: relative; overflow: hidden; display: grid; grid-template-columns: 1fr 300px; 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 / .72); border-radius: var(--r-lg);
           box-shadow: var(--shadow-1);
           transition: transform .3s var(--ease-expo), box-shadow .3s var(--ease), border-color .22s var(--ease); }
.rowcard::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--accent);
                   transform: scaleY(0); transition: transform .3s var(--ease-expo); }
.rowcard.yours::before { background: var(--amber); }
.rowcard:hover { transform: translateY(-2px); border-color: var(--accent-line); box-shadow: var(--shadow-2); }
.rowcard:hover::before, .rowcard:focus-visible::before { transform: scaleY(1); }
.rowcard h3 { font-size: 18px; font-weight: 650; letter-spacing: -.018em; margin: 0 0 5px; }
.rowcard .meta { display: flex; flex-wrap: wrap; align-items: center; row-gap: 6px; font-size: 13.5px; color: var(--muted); }
/* A separator between whichever pieces of `.meta` actually rendered, rather
   than one glued to a specific field's edge — a field skipped for being empty
   (no `location`, say) used to leave its neighbours' two separators standing
   next to each other with nothing between. Sibling adjacency in CSS only ever
   sees what is really in the DOM, so a gap upstream cannot produce one here. */
.rowcard .meta > *:not(:first-child)::before { content: "·"; margin: 0 8px; color: var(--line-2); }
.rowcard .aside { display: flex; flex-direction: column; align-items: flex-start; gap: 9px; justify-self: start; }
.rowcard .badges { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.rowcard .note { font-size: 13.5px; color: var(--muted); max-width: 30ch; text-align: right; }
.rowcard .note b { color: var(--ink); font-weight: 600; }
.rowcard .shift { transition: transform .38s var(--ease-back); }
.rowcard:hover .shift { transform: translateX(6px); }
@media (max-width: 860px) { .rowcard { grid-template-columns: 1fr; } .rowcard .note { text-align: left; max-width: none; } }

/* Compact stage indicator for rows — Bloom's dots, not Harbor's dashes.
   ----------------------------------------------------------------------------
   Il colore sta fuori da `.in`, ed è il punto. `.in` la mette `reveal.js`
   quando la riga entra in vista, quindi legare i colori a quella classe
   voleva dire che chi ha `prefers-reduced-motion` — dove la comparsa non
   parte mai — vedeva cinque pallini grigi identici, presenti e muti. Adesso
   `.in` porta solo l'entrata, che è il suo mestiere.

   La tappa corrente è lo stesso petrolio con un anello, non ambra: l'ambra
   nel portale vuol dire «questo aspetta te» — la barretta a sinistra della
   riga, il badge «N persone da guardare» — e usarla anche per «siamo a
   questo punto» faceva dire due cose diverse allo stesso colore, sulla
   stessa card. */
.stage-dots { display: flex; align-items: center; gap: 11px; }
/* Il percorso di una ricerca, su una riga.
   ----------------------------------------------------------------------------
   Un pallino per ogni tappa, e un'icona vera solo per quella corrente. Sei
   icone tutte uguali erano sei cose da leggere per sapere una cosa sola: dove
   siamo. Cosi' il disegno cambia solo dove serve guardare, e le tappe fatte e
   quelle da fare restano leggibili di sfuggita, come una scala.

   Il pallino corrente non si limita a cambiare colore: cresce e diventa il
   disco con dentro il segno di quella tappa. E' l'unico punto della riga dove
   c'e' qualcosa da capire, quindi e' l'unico che chiede di essere guardato. */
.stage-icons { display: flex; align-items: center; gap: 7px; }
.stage-icons i { position: relative; display: grid; place-items: center;
                 width: 9px; height: 9px; flex: none; border-radius: 50%;
                 background: var(--line-2); color: var(--on-accent); }
.stage-icons i svg { width: 18px; height: 18px; display: block; }
/* Fatte: verdi. Da fare: spente. Nessuna delle due porta un segno dentro —
   sono due stati, non due informazioni da leggere una per una. */
.stage-icons i.past { background: var(--accent); }
.stage-icons i.now  { width: 28px; height: 28px; background: var(--accent); }
/* I due finali hanno il proprio colore, e si disegna solo quello vero: sono i
   due modi in cui una ricerca finisce, non due tappe una dopo l'altra. */
.stage-icons i.now.won  { background: var(--ok); }
.stage-icons i.now.lost { background: var(--no); }
/* Il finale sta un po' piu' in la': e' l'unica casella che non e' una tappa
   del lavoro, ed e' l'unica che puo' non arrivare mai. */
.stage-icons i.ending { margin-left: 5px; }

.stage-dots .lbl { font-size: 13px; color: var(--muted); white-space: nowrap; }

.stat .n { font-family: var(--font-serif); font-size: clamp(34px, 4.2vw, 50px); font-weight: 600;
           line-height: 1; letter-spacing: -.035em; font-variant-numeric: tabular-nums; }
.stat .n.warm { color: var(--amber-ink); }
.stat .n.acc { color: var(--accent); }
.stat .k { font-size: 13.5px; color: var(--muted); margin-top: 9px; }

.quote { margin: 0 0 var(--s3); padding-left: var(--s3); border-left: 3px solid var(--accent-line);
         font-size: 15.5px; line-height: 1.7; color: var(--muted); }
.quote:last-child { margin-bottom: 0; }
.quote .by { display: block; margin-top: 7px; font-size: 13px; color: var(--faint); }

.slots { display: grid; gap: 8px; }
.slot { display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
        padding: 13px 17px; border-radius: var(--r-sm); cursor: pointer; text-align: left;
        background: var(--card-2); border: 1px solid var(--line);
        transition: border-color .18s var(--ease), background .18s var(--ease), transform .18s var(--ease); }
.slot:hover { border-color: var(--accent); background: var(--card); transform: translateX(4px); }
.slot .d { font-size: 14.5px; font-weight: 600; }
.slot .h { font-size: 13px; color: var(--faint); }

.doc { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.doc:last-child { border-bottom: 0; padding-bottom: 0; }
.doc .ic { width: 36px; height: 36px; flex: none; display: grid; place-items: center; border-radius: var(--r-sm);
           color: var(--accent); background: var(--accent-soft); }
.doc .t { flex: 1; min-width: 0; }
.doc .t b { display: block; font-size: 14px; font-weight: 600; }
.doc .t span { font-size: 12.5px; color: var(--faint); }

/* ---- 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 17px; font-size: 15.5px; color: var(--ink);
               background: var(--card); 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); }
body.deep .field input { background: oklch(0 0 0 / .22); border-width: 1px; }
.field input::placeholder { color: var(--faint); }
.field input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.hint { font-size: 13px; color: var(--faint); margin: -6px 0 var(--s3); }

/* Senza JS, o con il JS rotto, la pagina deve restare leggibile: le regole che
   nascondono qualcosa sono valide solo sotto `.js`, che uno script in testa
   aggiunge all'html. È la difesa che mancava — una direzione intera è nata
   vuota perché una funzione chiamata non esisteva, e il CSS aveva già
   azzerato l'opacità di tutto.
   ---- Bloom's effects ----------------------------------------------------- */
.words .w { display: inline-block; overflow: hidden; vertical-align: top; }
.js .words .w > span { display: inline-block; transform: translateY(102%) rotate(3deg); opacity: 0; filter: blur(6px);
                   transition: transform .9s var(--ease-expo), opacity .7s var(--ease), filter .7s var(--ease); }
.words.in .w > span { transform: none; opacity: 1; filter: blur(0); }

.spot { position: relative; overflow: hidden; }
.spot::after { content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
               background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%), oklch(0.760 0.108 199 / .16), transparent 68%);
               opacity: 0; transition: opacity .45s var(--ease); }
.spot:hover::after { opacity: 1; }

.thread-bar { position: fixed; inset: 0 0 auto; height: 3px; z-index: 90; transform-origin: 0 50%;
              transform: scaleX(var(--p, 0)); background: linear-gradient(90deg, var(--accent), var(--accent-lit), var(--amber)); }

@keyframes drift   { 0%,100% { transform: translate3d(0,0,0) scale(1); } 50% { transform: translate3d(-3%, 3%, 0) scale(1.07); } }
@keyframes rise    { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
@keyframes pop     { from { opacity: 0; transform: translateY(14px) scale(.95); } to { opacity: 1; transform: none; } }
@keyframes ripple  { to { transform: scale(2.6); opacity: 0; } }
@keyframes breathe { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.82); } }
@keyframes typing  { 0%,60%,100% { transform: translateY(0); opacity: .35; } 30% { transform: translateY(-5px); opacity: 1; } }
@keyframes hereGlow{ 0%,100% { box-shadow: 0 0 0 0 oklch(0.760 0.115 62 / .40); } 55% { box-shadow: 0 0 0 6px transparent; } }

.rise { animation: rise .8s var(--ease-expo) 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}
.js .reveal { opacity: 0; transform: translateY(26px); transition: opacity .75s var(--ease), transform .75s var(--ease-expo); }
.js .reveal.in { opacity: 1; transform: none; }
.js .stagger > * { opacity: 0; transform: translateY(18px); transition: opacity .6s var(--ease), transform .6s var(--ease-expo); }
.js .stagger.in > * { opacity: 1; transform: none; }
.stagger.in > *:nth-child(1){transition-delay:.00s}.stagger.in > *:nth-child(2){transition-delay:.06s}
.stagger.in > *:nth-child(3){transition-delay:.12s}.stagger.in > *:nth-child(4){transition-delay:.18s}
.stagger.in > *:nth-child(5){transition-delay:.24s}.stagger.in > *:nth-child(6){transition-delay:.30s}

/* ---- Switcher ------------------------------------------------------------ */
.style-switch { position: fixed; bottom: 18px; right: 18px; z-index: 80; 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-size: 11.5px; color: var(--faint); box-shadow: var(--shadow-2); }
.style-switch a { min-width: 32px; text-align: center; padding: 6px 10px; border-radius: var(--r-pill);
                  text-decoration: none; color: var(--muted); font-weight: 600;
                  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(--on-accent); }

@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; }
  .words .w > span { transform: none; opacity: 1; filter: none; }
  .blooms { display: none; }
  .path::after { height: var(--reached, 0%); }
  .skill .bar i { width: var(--lv, 50%); }
}

/* ============================================================================
   THE ASSISTANT, AS A CHARACTER
   ----------------------------------------------------------------------------
   A cream blob with a tuft, a heavy dark outline and very large eyes. It lives
   in the top bar and it is the only ornament in the whole direction.

   ONE DRAWING, EIGHT FACES. Every expression is a group inside the same SVG;
   `data-mood` on the button shows one and hides the rest. No sprite sheet, no
   second request, and the body never redraws — only the face changes, which is
   what makes it read as the same creature in a different state.

   THE MOODS ARE STATES, NOT DECORATION. Each one is tied to something true:

     idle       nothing is pending
     surprised  something is genuinely waiting on the client  (+ the hop)
     thinking   an answer is being composed
     happy      the answer just landed
     wink       you are hovering it
     sleepy     you have read everything; it dozes off
     cool       zero open questions on the whole page
     love       you confirmed an interview

   NO COUNTER. A number stuck on its head dirties the drawing and duplicates
   what the amber badges in the page already say. The creature signals with
   posture: it is surprised and it hops, or it is not.

   THE EYES FOLLOW THE POINTER, and that is the only joke it is allowed.
   ============================================================================ */

.buddy-wrap { position: relative; flex: none; }

.buddy-btn {
  position: relative; display: grid; place-items: center;
  width: 46px; height: 46px; padding: 0; cursor: pointer;
  background: transparent; border: 0; border-radius: 14px;
  transition: background .2s var(--ease);
  --skin:  oklch(0.985 0.010 92);
  --line-b:oklch(0.255 0.045 250);
  --mouth: oklch(0.700 0.150 42);
  --blush: oklch(0.800 0.090 22);
  --heart: oklch(0.660 0.190 25);
}
.buddy-btn:hover { background: oklch(1 0 0 / .55); }

/* Sulla porta d'ingresso la creatura non è un comando: non c'è ancora niente
   da aprire. Fa da ritratto accanto al nome di chi ti segue — stessa faccia,
   stessi occhi che seguono il puntatore, nessun clic promesso. */
.buddy-btn.as-figure { width: 92px; height: 92px; cursor: default; background: transparent; border-radius: 0;
                       /* Appoggiata: le mani toccano la riga sotto l'intestazione, quindi
                          la figura scende di tutto il padding basso del contenitore. */
                       align-self: flex-end; margin-bottom: calc(-1 * var(--s2)); }
.buddy-btn.as-figure:hover { background: transparent; }
.buddy-btn.as-figure .buddy { width: 92px; height: 92px; }
/* Niente ondeggiamento per lei: sta appoggiata, non fluttua. */
.buddy-btn.as-figure .buddy-float { animation: none; transform: none; }

/* Il ritratto raster: sei immagini nel DOM, una sola visibile. Il quadrato ha
   le mani sull'ultima riga e i segni (puntini, ?, cuore) a destra
   dell'antenna, quindi si vede intero senza ritagli. */
.buddy img.mood { width: 100%; height: 100%; object-fit: contain; }

.buddy { display: block; width: 40px; height: 40px; overflow: visible;
         transition: transform .22s var(--ease-back); }
.buddy-btn:active .buddy { transform: scale(.93); }

.buddy .skin   { fill: var(--skin); stroke: var(--line-b); stroke-width: 3.4; stroke-linejoin: round; }
.buddy .seam   { fill: none; stroke: var(--line-b); stroke-width: 1.5; opacity: .55; }
.buddy .ink    { fill: var(--line-b); }
.buddy .stroke { fill: none; stroke: var(--line-b); stroke-width: 4.2; stroke-linecap: round; }
.buddy .mouth  { fill: var(--mouth); stroke: var(--line-b); stroke-width: 2.6; stroke-linejoin: round; }
.buddy .blush  { fill: var(--blush); opacity: .75; }
.buddy .heart  { fill: var(--heart); }
.buddy .shine  { fill: oklch(1 0 0); opacity: .9; }

/* ---- Mood switching ------------------------------------------------------ */
.buddy .mood { display: none; }
.buddy-btn[data-mood="idle"]      .m-idle,
.buddy-btn[data-mood="happy"]     .m-happy,
.buddy-btn[data-mood="wink"]      .m-wink,
.buddy-btn[data-mood="surprised"] .m-surprised,
.buddy-btn[data-mood="thinking"]  .m-thinking,
.buddy-btn[data-mood="sleepy"]    .m-sleepy,
.buddy-btn[data-mood="cool"]      .m-cool,
.buddy-btn[data-mood="love"]      .m-love { display: block; }
.buddy-btn:not([data-mood]) .m-idle { display: block; }

/* Hovering swaps the face to a wink unless the creature is busy saying
   something more important — a mood set by the page always wins. */
.buddy-btn:hover:not([data-mood="thinking"]):not([data-mood="surprised"]):not([data-mood="love"]) .mood { display: none; }
.buddy-btn:hover:not([data-mood="thinking"]):not([data-mood="surprised"]):not([data-mood="love"]) .m-wink { display: block; }

/* ---- Life ---------------------------------------------------------------- */
.buddy-float { display: block; animation: float 3.6s var(--ease) infinite; }
@keyframes float { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-2.5px) rotate(-2.5deg); } }

/* Blink: two frames out of a long loop. The eyelid is the body colour dropped
   over the eyes, so it works for every mood that has round eyes. */
.buddy .lids { animation: blink 6.8s infinite; }
@keyframes blink { 0%, 93.5%, 100% { transform: scaleY(0); } 95.5% { transform: scaleY(1); } }
.buddy .lids rect { fill: var(--skin); }
.buddy .lids { transform-box: fill-box; transform-origin: 50% 0%; }

/* Something is waiting: three hops, then a long silence. It does not escalate
   and it never repeats once the panel has been opened. */
.buddy-btn.pending .buddy-float { animation: nudge 4.6s var(--ease) infinite; }
@keyframes nudge {
  0%, 60%, 100% { transform: translateY(0) rotate(0deg); }
  64% { transform: translateY(-8px) rotate(-8deg) scale(1.04); }
  70% { transform: translateY(0) rotate(0deg) scale(.98); }
  75% { transform: translateY(-5px) rotate(6deg); }
  81% { transform: translateY(0) rotate(0deg); }
  85% { transform: translateY(-2px) rotate(-2deg); }
}

/* The little marks that ride beside the head: sparkle, question mark. */
.buddy .mark { animation: markPop 2.4s var(--ease) infinite; transform-origin: 76px 20px; }
@keyframes markPop { 0%, 100% { transform: scale(1) translateY(0); opacity: 1; } 50% { transform: scale(1.15) translateY(-2px); opacity: .75; } }

.buddy-btn[aria-expanded="true"] { background: var(--accent-soft); }
.buddy-btn[aria-expanded="true"] .buddy-float { animation: none; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .buddy-float, .buddy .lids, .buddy .mark, .buddy-btn.pending .buddy-float { animation: none !important; }
  .buddy .lids { transform: scaleY(0); }
}

/* ============================================================================
   Platform — "Harbor" direction, PP (partner portal)
   ----------------------------------------------------------------------------
   Halfway between Loom and Petrol, on purpose and in both senses.

   COLOUR: Loom's room was warm stone; Petrol's was deep teal. Harbor keeps
   Loom's structure — a light room with paper laid on it — and swaps the
   temperature to Petrol's family: cold slate at 90% lightness, petrol ink,
   and Petrol's aqua kept as the live signal. One warm note survives (amber),
   and it is spent on exactly one thing: what is waiting on the client. So the
   page reads as the same product as the dark internal instrument, seen in
   daylight, rather than as a different brand.

   DENSITY: Loom was airy and its candidate page carried a conversation and
   little else. Harbor is full. The spacing scale is tighter, the grid is 12
   columns, and the candidate screen shows everything we actually hold on a
   person — skills against the brief, the full career, education, languages,
   certifications, references we called, interview notes, documents, the stage
   of the search and the slots on offer.

   THE ASSISTANT STAYS. Marta is no longer a voice the page is written in —
   at this density that would fight the data — she is a panel that travels
   with you and answers about the person on screen. That is also the shape
   this needs to be if the panel is later wired to a real model: a bounded
   assistant with a visible scope, not a tone of voice sprayed over the UI.

   Behaviour in assets/harbor.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.9fe3e924d0d2.woff2") format("woff2"); }
@font-face { font-family: "Fraunces"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/fraunces-600.cc3e6b3f975c.woff2") format("woff2"); }
@font-face { font-family: "Fraunces"; font-style: italic; font-weight: 500; font-display: swap; src: url("../fonts/fraunces-italic-500.3d15406bbc1a.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/inter-400.cef6d3a6737e.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/inter-500.861c7a6706fe.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/inter-600.ca03b7ee20d3.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/inter-700.64d12f9f7d82.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: cold slate, light. Paper sits above it, as in Loom. */
  --room:   oklch(0.902 0.014 218);
  --room-2: oklch(0.874 0.016 216);
  --card:   oklch(0.962 0.008 216);
  --card-2: oklch(0.936 0.010 214);

  --ink:    oklch(0.265 0.042 222);
  --muted:  oklch(0.432 0.032 222);
  --faint:  oklch(0.498 0.026 220);
  --line:   oklch(0.836 0.016 216);
  --line-2: oklch(0.770 0.022 214);

  /* Petrol, from the internal instrument. Clears 6:1 on card as text. */
  --accent:      oklch(0.475 0.098 210);
  --accent-deep: oklch(0.372 0.085 212);
  --accent-soft: oklch(0.906 0.030 208);
  --accent-line: oklch(0.820 0.048 208);

  /* Aqua: the live signal, same role it had on the dark canvas. Fills only. */
  --aqua:      oklch(0.700 0.110 200);
  --aqua-ink:  oklch(0.470 0.098 202);
  --aqua-soft: oklch(0.910 0.040 200);

  /* Amber: the one warm note, and only ever "your move". */
  --amber:      oklch(0.755 0.115 62);
  --amber-ink:  oklch(0.492 0.110 58);
  --amber-soft: oklch(0.920 0.045 62);

  --ok:      oklch(0.470 0.090 160);
  --ok-soft: oklch(0.912 0.036 160);
  --no:      oklch(0.510 0.140 28);
  --no-soft: oklch(0.925 0.038 28);

  /* Tighter than Loom — this direction has to carry a full profile. */
  --s1: 6px; --s2: 10px; --s3: 16px; --s4: 22px; --s5: 32px; --s6: 48px; --s7: 68px;

  --r-sm:   10px;
  --r:      16px;
  --r-lg:   22px;
  --r-pill: 999px;
  --r-said: 16px 16px 16px 5px;
  --r-mine: 16px 16px 5px 16px;

  --shadow-1: 0 1px 2px oklch(0.265 0.042 222 / .06), 0 3px 12px oklch(0.265 0.042 222 / .06);
  --shadow-2: 0 2px 6px oklch(0.265 0.042 222 / .08), 0 16px 36px oklch(0.265 0.042 222 / .14);
  --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(--paper); color: var(--ink);
  font-family: var(--font-sans); font-size: 15px; line-height: 1.55;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  background-image:
    linear-gradient(oklch(0.265 0.042 222 / .026) 1px, transparent 1px),
    linear-gradient(90deg, oklch(0.265 0.042 222 / .026) 1px, transparent 1px);
  background-size: 30px 30px;
}
a { color: inherit; }
button, input, textarea { font: inherit; }
:focus-visible { outline: 2.5px solid var(--accent); outline-offset: 2px; border-radius: 5px; }
::selection { background: var(--aqua-soft); color: var(--ink); }

/* ---- Top bar ------------------------------------------------------------- */
.top {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; gap: var(--s4);
  padding: 10px clamp(16px, 3vw, 34px);
  background: oklch(0.902 0.014 218 / .88); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
  transition: padding .28s var(--ease), box-shadow .28s var(--ease);
}
.top.tight { padding-top: 6px; padding-bottom: 6px; box-shadow: 0 5px 18px oklch(0.265 0.042 222 / .10); }
.brand { display: flex; align-items: center; gap: 10px; font-weight: 650; font-size: 15px; letter-spacing: -.012em; flex: none; }
.brand .sub { display: block; font-family: var(--font-mono); font-size: 10px; font-weight: 400;
              color: var(--faint); letter-spacing: .06em; text-transform: uppercase; }
.mark {
  width: 32px; height: 32px; flex: none; display: grid; place-items: center; border-radius: 10px;
  font-weight: 800; font-size: 13px; color: var(--card);
  background: linear-gradient(145deg, var(--accent-lit), var(--accent-deep));
  box-shadow: 0 3px 12px oklch(0.475 0.098 210 / .32);
}
.nav { display: flex; gap: 2px; flex: 1; }
.nav a {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 13px;
  text-decoration: none; color: var(--muted); font-size: 14px; 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 / .5); }
.nav a.on { color: var(--accent-deep); background: var(--card); font-weight: 650; box-shadow: var(--shadow-1); }
.nav a .n {
  margin-left: 7px; min-width: 20px; height: 20px; padding: 0 6px;
  display: inline-grid; place-items: center; border-radius: var(--r-pill);
  font-size: 10.5px; font-weight: 700; color: var(--card); background: var(--amber-ink);
}
.top .right { display: flex; align-items: center; gap: var(--s2); flex: none; }
.who { text-align: right; line-height: 1.22; }
.who .n { font-size: 13px; font-weight: 600; }
.who .o { font-family: var(--font-mono); font-size: 10px; color: var(--faint); letter-spacing: .04em; }
.me { width: 36px; height: 36px; flex: none; display: grid; place-items: center; cursor: pointer;
      border-radius: 12px; font-size: 12px; font-weight: 700; color: var(--card);
      background: linear-gradient(145deg, var(--amber), var(--amber-ink)); }
@media (max-width: 900px) { .nav, .who { display: none; } }

/* ---- Frame --------------------------------------------------------------- */
.wrap { max-width: 1320px; margin: 0 auto; padding: var(--s5) clamp(16px, 3vw, 34px) var(--s7); }
.wrap.mid { max-width: 1080px; }

.tag { display: inline-flex; align-items: center; gap: 6px;
       font-family: var(--font-mono); font-size: 10px; font-weight: 500;
       letter-spacing: .1em; text-transform: uppercase; color: var(--faint); }
.tag .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent-lit); 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(30px, 4.2vw, 48px); 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: 16px; line-height: 1.68; color: var(--muted); max-width: 60ch; margin: 0; }

.h-sec { display: flex; align-items: center; gap: 10px; margin: 0 0 var(--s3);
         font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
         letter-spacing: .12em; text-transform: uppercase; color: var(--faint); }
.h-sec::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.h-sec .n { color: var(--accent-deep); font-weight: 700; }
.h-sec.warm .n { color: var(--amber-ink); }

/* ---- Grid ---------------------------------------------------------------- */
.g12 { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--s3); align-items: start; }
.c3{grid-column:span 3}.c4{grid-column:span 4}.c5{grid-column:span 5}.c6{grid-column:span 6}
.c7{grid-column:span 7}.c8{grid-column:span 8}.c9{grid-column:span 9}.c12{grid-column:span 12}
@media (max-width: 1100px) { .c3,.c4{grid-column:span 6} .c5,.c7,.c8,.c9{grid-column:span 12} }
@media (max-width: 700px)  { .g12 > * { grid-column: span 12 !important; } }

.card { background: var(--card); border: 1px solid oklch(1 0 0 / .65); border-radius: var(--r-lg);
        box-shadow: var(--shadow-1); transition: box-shadow .28s var(--ease), transform .28s var(--ease); }
.card.pad { padding: var(--s4); }
.card.tight { padding: var(--s3); }
.card.quiet { background: var(--card-2); box-shadow: none; border-color: var(--line); }
.card.lift:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.card.ink { background: linear-gradient(165deg, oklch(0.300 0.048 220), oklch(0.245 0.040 222));
            border-color: transparent; color: oklch(0.96 0.01 216); }
.card.ink .h-sec { color: oklch(0.96 0.01 216 / .5); }
.card.ink .h-sec::after { background: oklch(1 0 0 / .14); }

/* ---- Buttons, chips, badges ---------------------------------------------- */
.btn { position: relative; overflow: hidden;
       display: inline-flex; align-items: center; justify-content: center; gap: 8px;
       min-height: 44px; padding: 10px 20px; cursor: pointer;
       font-size: 14.5px; font-weight: 600; border: 1px solid transparent; border-radius: var(--r-pill);
       transition: transform .16s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease); }
.btn:active { transform: scale(.975); }
.btn-primary { color: var(--card); background: var(--accent); box-shadow: 0 5px 16px oklch(0.475 0.098 210 / .28); }
.btn-primary:hover { background: var(--accent-deep); box-shadow: 0 9px 24px oklch(0.475 0.098 210 / .36); }
.btn-warm { color: var(--card); background: var(--amber-ink); box-shadow: 0 5px 16px oklch(0.492 0.110 58 / .28); }
.btn-warm:hover { box-shadow: 0 9px 24px oklch(0.492 0.110 58 / .38); }
.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(--no); background: var(--no-soft); }
.btn-sm { min-height: 38px; padding: 8px 15px; font-size: 13.5px; }
.btn-xs { min-height: 32px; padding: 6px 12px; font-size: 12.5px; border-radius: var(--r-pill); }
@media (pointer: coarse) { .btn-sm, .btn-xs { min-height: 44px; } }
.ripple { position: absolute; border-radius: 50%; pointer-events: none; background: currentColor;
          opacity: .22; transform: scale(0); animation: ripple .6s var(--ease) forwards; }

.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); }

.badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px;
         font-size: 12px; 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: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.badge.you  { color: var(--amber-ink); background: var(--amber-soft); border-color: oklch(0.755 0.115 62 / .45); }
.badge.live { color: var(--aqua-ink);  background: var(--aqua-soft);  border-color: oklch(0.700 0.110 200 / .42); }
.badge.ok   { color: var(--ok); background: var(--ok-soft); border-color: oklch(0.470 0.090 160 / .35); }
.badge.on-ink { color: oklch(0.96 0.01 216); background: oklch(1 0 0 / .12); border-color: oklch(1 0 0 / .2); }

.chip { display: inline-flex; align-items: center; min-height: 38px; padding: 7px 14px; cursor: pointer;
        font-size: 13.5px; 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; } }

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

/* ---- Dense data atoms ----------------------------------------------------
   The point of this direction is fitting a whole person on one screen, so the
   small pieces are engineered to sit close together without turning into soup:
   every one of them pairs a mono label with a plain-language value. */
.kv { display: grid; grid-template-columns: auto 1fr; gap: 9px var(--s3); margin: 0; font-size: 14px; }
.kv dt { font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
         color: var(--faint); align-self: center; white-space: nowrap; }
.kv dd { margin: 0; text-align: right; font-weight: 550; }
.kv dd.warn { color: var(--amber-ink); }

/* Skills carry a strength bar, and the ones named in the brief are lit. This
   is the one place a measurement is allowed on the client's side of the table
   — it is about a tool, not about a person's worth. */
.skills { display: grid; gap: 8px; }
.skill { display: grid; grid-template-columns: 1fr 78px auto; align-items: center; gap: 11px; font-size: 13.5px; }
.skill .nm { font-weight: 550; }
.skill .bar { height: 5px; border-radius: 3px; background: oklch(0.265 0.042 222 / .12); overflow: hidden; }
.skill .bar i { display: block; height: 100%; width: 0; border-radius: 3px; background: var(--line-2);
                transition: width 1s var(--ease); }
.in .skill .bar i, .skills.in .skill .bar i { width: var(--lv, 50%); }
.skill.req .nm { color: var(--accent-deep); font-weight: 650; }
.skill.req .bar i { background: linear-gradient(90deg, var(--accent), var(--accent-lit)); }
.skill .yr { font-family: var(--font-mono); font-size: 10.5px; color: var(--faint); white-space: nowrap; }

/* Career, education, references — one list shape, three uses. */
.tl { list-style: none; margin: 0; padding: 0; }
.tl li { position: relative; padding: 0 0 var(--s3) var(--s4); }
.tl li:last-child { padding-bottom: 0; }
.tl li::before { content: ""; position: absolute; left: 3px; top: 5px; width: 9px; height: 9px;
                 border-radius: 50%; background: var(--card); border: 2px solid var(--line-2); }
.tl li.hi::before { background: var(--accent); border-color: var(--accent); }
.tl li::after { content: ""; position: absolute; left: 7px; top: 17px; bottom: 2px; width: 1px; background: var(--line); }
.tl li:last-child::after { display: none; }
.tl .role { font-size: 14.5px; font-weight: 650; }
.tl .co { font-size: 13.5px; color: var(--muted); }
.tl .when { font-family: var(--font-mono); font-size: 10.5px; color: var(--faint); letter-spacing: .04em; margin-top: 2px; }
.tl .did { font-size: 13.5px; color: var(--muted); margin-top: 5px; line-height: 1.6; }
.tl .stack { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.tl .stack span { font-family: var(--font-mono); font-size: 10.5px; color: var(--accent-deep);
                  background: var(--accent-soft); border: 1px solid var(--accent-line);
                  border-radius: 5px; padding: 2px 7px; }

.rows { display: flex; flex-direction: column; gap: var(--s2); }
/* ATTENZIONE: `.rowcard` è definita due volte in questo file — una volta nella
   sezione Lagoon più in alto, e di nuovo qui in quella Harbor. Stessa
   specificità, quindi vince questa, che viene dopo. È la copia da modificare:
   correggere solo quella sopra non produce alcun effetto sullo schermo, ed è
   costato un giro di "ma l'ho già sistemato" davanti a uno screenshot che
   mostrava ancora il difetto.

   La colonna di destra è larga fissa e non `auto`: ogni riga è la sua griglia
   a sé, quindi una colonna `auto` si misura sul contenuto di *quella* riga —
   e una riga con "1 proposto · ieri" otteneva una colonna più larga di una
   senza, spostando la pillola a un'ascissa diversa riga per riga. Righe della
   stessa lista si leggono come una lista perché le loro pillole stanno in
   colonna: la larghezza fissa è ciò che lo garantisce.

   `.aside` impila i suoi due pezzi (pillola, poi pallini) invece di
   affiancarli, e li allinea a destra: `center` — che era il valore qui prima —
   centrava la pillola sopra i pallini, così una riga con l'etichetta lunga la
   spingeva a sinistra e una senza la lasciava a destra. */
.rowcard { position: relative; overflow: hidden; display: grid; grid-template-columns: 1fr 300px;
           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 / .65); border-radius: var(--r-lg); box-shadow: var(--shadow-1);
           transition: transform .26s var(--ease), box-shadow .26s var(--ease); }
.rowcard::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
                   background: var(--accent); transform: scaleY(0); transition: transform .26s var(--ease-back); }
.rowcard.yours::before { background: var(--amber); }
.rowcard:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.rowcard:hover::before, .rowcard:focus-visible::before { transform: scaleY(1); }
.rowcard h3 { font-size: 16.5px; font-weight: 650; letter-spacing: -.016em; margin: 0 0 4px; }
/* Solo `row-gap`: la distanza orizzontale fra i pezzi la dà il margine del
   separatore, e sommarci anche un `column-gap` li allontanava del doppio. */
.rowcard .meta { display: flex; flex-wrap: wrap; align-items: center; row-gap: 6px; font-size: 13px; color: var(--muted); }
.rowcard .aside { display: flex; flex-direction: column; align-items: flex-start; gap: 9px; justify-self: start; }
.rowcard .badges { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.rowcard .rail { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
/* Lo stato, in testa alla riga dei dettagli: un pallino e una parola, non una
   pill. In alto a destra rubava la larghezza alle due pill dei numeri e le
   mandava a capo, e non e' un dato che si va a cercare — e' il contesto di
   tutto il resto della riga. Le regole nuove stanno scritte una volta sola:
   `.rowcard` e' definita due volte in questo file (vedi la nota piu' sotto),
   ma qui non c'e' niente da sovrascrivere, quindi basta che stiano dopo. */
.rowcard .meta .state { display: inline-flex; align-items: center; gap: 6px;
                        font-weight: 600; color: var(--muted); }
.rowcard .meta .state::after { content: ""; order: -1; width: 7px; height: 7px;
                               border-radius: 50%; background: currentColor; }
.rowcard .meta .state.open { color: var(--accent); }
.rowcard .note { font-size: 13px; color: var(--muted); max-width: 28ch; text-align: right; }
.rowcard .note b { color: var(--ink); font-weight: 600; }
.rowcard .shift { transition: transform .34s var(--ease-back); }
.rowcard:hover .shift { transform: translateX(5px); }
@media (max-width: 860px) { .rowcard { grid-template-columns: 1fr; } .rowcard .note { text-align: left; max-width: none; } }

.steps { display: flex; align-items: center; gap: 4px; }
.steps i { width: 18px; 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, .steps.in i { transform: scaleX(1); opacity: 1; }
.in .steps i.done, .steps.in i.done { background: var(--accent); }
.in .steps i.here, .steps.in i.here { background: var(--accent-lit); animation: hereGlow 2.6s var(--ease) infinite; }
.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}

.stat .n { font-family: var(--font-serif); font-size: clamp(30px, 3.6vw, 42px); font-weight: 600;
           line-height: 1; letter-spacing: -.035em; font-variant-numeric: tabular-nums; }
.stat .n.warm { color: var(--amber-ink); }
.stat .n.live { color: var(--aqua-ink); }
.stat .k { font-size: 13px; color: var(--muted); margin-top: 7px; }

.quote { margin: 0 0 var(--s3); padding-left: var(--s3); border-left: 3px solid var(--accent-line);
         font-size: 14px; line-height: 1.65; color: var(--muted); }
.quote:last-child { margin-bottom: 0; }
.quote .by { display: block; margin-top: 5px; font-family: var(--font-mono); font-size: 10px;
             letter-spacing: .06em; text-transform: uppercase; color: var(--faint); }

/* Interview slots on offer — a decision the client can make in one press. */
.slots { display: grid; gap: 7px; }
.slot { display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
        padding: 10px 14px; border-radius: var(--r-sm); cursor: pointer; text-align: left;
        background: var(--card-2); border: 1px solid var(--line);
        transition: border-color .18s var(--ease), background .18s var(--ease), transform .18s var(--ease); }
.slot:hover { border-color: var(--accent); background: var(--card); transform: translateX(3px); }
.slot .d { font-size: 13.5px; font-weight: 600; }
.slot .h { font-family: var(--font-mono); font-size: 11px; color: var(--faint); }

.doc { display: flex; align-items: center; gap: 11px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.doc:last-child { border-bottom: 0; padding-bottom: 0; }
.doc .ic { width: 32px; height: 32px; flex: none; display: grid; place-items: center; border-radius: 9px;
           color: var(--accent-deep); background: var(--accent-soft); }
.doc .t { flex: 1; min-width: 0; }
.doc .t b { display: block; font-size: 13.5px; font-weight: 600; }
.doc .t span { font-family: var(--font-mono); font-size: 10px; color: var(--faint); letter-spacing: .04em; }

/* ---- The assistant panel -------------------------------------------------
   Marta as a bounded surface rather than a tone of voice: a header that names
   who is answering, a scrollable thread, canned questions, and a composer.
   The scope line under the header is not decoration — if this is later wired
   to a model, the client has to be able to see what it can and cannot see. */
.assist { display: flex; flex-direction: column; overflow: hidden; padding: 0; }
.assist-head { display: flex; align-items: center; gap: 11px; padding: var(--s3) var(--s3) var(--s2);
               border-bottom: 1px solid var(--line); }
.assist-head .face { width: 38px; height: 38px; flex: none; display: grid; place-items: center;
                     border-radius: 12px; font-size: 12px; font-weight: 700; color: var(--card);
                     background: linear-gradient(145deg, var(--accent-lit), var(--accent-deep)); }
.assist-head .who-t { flex: 1; min-width: 0; }
.assist-head .who-t b { display: block; font-size: 14px; font-weight: 650; }
.assist-head .who-t span { font-size: 11.5px; color: var(--faint); }
.assist-scope { padding: 9px var(--s3); font-size: 11.5px; color: var(--muted);
                background: var(--aqua-soft); border-bottom: 1px solid var(--line); }
.assist-thread { display: flex; flex-direction: column; gap: var(--s2); padding: var(--s3);
                 max-height: 380px; overflow-y: auto; }
.assist-thread .said { display: flex; gap: 9px; align-items: flex-start; }
.assist-thread .said .f { width: 26px; height: 26px; flex: none; display: grid; place-items: center;
                          border-radius: 9px; font-size: 9.5px; font-weight: 700; color: var(--card);
                          background: linear-gradient(145deg, var(--accent-lit), var(--accent-deep)); }
/* Con la testa di Mar.ia dentro, niente riquadro colorato sotto: è già lei. */
.assist-thread .said .f:has(img) { background: none; border-radius: 0; overflow: visible; }
.assist-thread .said .f img { width: 30px; height: 30px; max-width: none; object-fit: contain; margin: -2px; }
.assist-thread .bubble { padding: 10px 13px; border-radius: var(--r-said); background: var(--card-2);
                         font-size: 13.5px; line-height: 1.6; }
.assist-thread .bubble b { font-weight: 650; }
.assist-thread .mine { display: flex; justify-content: flex-end; }
.assist-thread .mine .bubble { background: var(--accent-soft); border: 1px solid var(--accent-line);
                               border-radius: var(--r-mine); color: var(--accent-deep); font-weight: 500; }
.typing { display: inline-flex; align-items: center; gap: 4px; padding: 11px 14px;
          background: var(--card-2); border-radius: var(--r-said); }
.typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--faint); opacity: .4;
            animation: typing 1.25s var(--ease) infinite; }
.typing i:nth-child(2){animation-delay:.16s} .typing i:nth-child(3){animation-delay:.32s}
.said[data-typing] > .bubble { display: none; }
.said[data-typing].spoken > .bubble { display: block; animation: pop .45s var(--ease-back) both; }
.said[data-typing].spoken > .typing { display: none; }

.assist-asks { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 var(--s3) var(--s3); }
.ask-chip { font-size: 12.5px; padding: 7px 12px; min-height: 36px; cursor: pointer;
            color: var(--accent-deep); background: var(--card); border: 1px solid var(--accent-line);
            border-radius: var(--r-pill); transition: background .18s var(--ease), transform .18s var(--ease); }
.ask-chip:hover { background: var(--accent-soft); transform: translateY(-1px); }
@media (pointer: coarse) { .ask-chip { min-height: 44px; } }
.assist-composer { display: flex; gap: 8px; padding: var(--s3); border-top: 1px solid var(--line); background: var(--card-2); }
.assist-composer input { flex: 1; min-width: 0; min-height: 42px; padding: 10px 14px; font-size: 14px;
                         color: var(--ink); background: var(--card); border: 1px solid var(--line-2);
                         border-radius: var(--r-pill); outline: none;
                         transition: border-color .18s var(--ease), box-shadow .18s var(--ease); }
.assist-composer input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.assist-composer button { width: 42px; height: 42px; flex: none; display: grid; place-items: center;
                          border: 0; border-radius: 50%; cursor: pointer; color: var(--card); background: var(--accent); }
.sticky { position: sticky; top: 74px; }

/* ---- Fields -------------------------------------------------------------- */
.field { margin-bottom: var(--s3); }
.field label { display: block; font-size: 12.5px; font-weight: 600; color: var(--muted); margin-bottom: 6px; }
.field input { width: 100%; min-height: 48px; padding: 12px 15px; font-size: 15px; 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), background .2s var(--ease), box-shadow .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: 12.5px; color: var(--faint); margin: -4px 0 var(--s3); }

/* ---- Motion -------------------------------------------------------------- */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vt-out .26s var(--ease) both; }
::view-transition-new(root) { animation: vt-in .4s var(--ease) both; }
@keyframes vt-out { to { opacity: 0; transform: translateY(-6px); } }
@keyframes vt-in  { from { opacity: 0; transform: translateY(10px); } }
.top { view-transition-name: topbar; }

@keyframes rise    { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes pop     { from { opacity: 0; transform: translateY(12px) scale(.95); } to { opacity: 1; transform: none; } }
@keyframes typing  { 0%,60%,100% { transform: translateY(0); opacity: .35; } 30% { transform: translateY(-4px); opacity: 1; } }
@keyframes breathe { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.8); } }
@keyframes ripple  { to { transform: scale(2.8); opacity: 0; } }
@keyframes hereGlow{ 0%,100% { box-shadow: 0 0 0 0 oklch(0.700 0.110 200 / .45); } 55% { box-shadow: 0 0 0 5px transparent; } }

.rise { animation: rise .65s var(--ease) both; }
.d1{animation-delay:.05s}.d2{animation-delay:.12s}.d3{animation-delay:.19s}.d4{animation-delay:.26s}
.d5{animation-delay:.33s}.d6{animation-delay:.40s}

.wipe { clip-path: inset(0 100% 0 0); transition: clip-path .95s var(--ease); }
.wipe.in { clip-path: inset(0 0 0 0); }
.reveal { opacity: 0; transform: translateY(18px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.reveal.in { opacity: 1; transform: none; }
.stagger > * { opacity: 0; transform: translateY(14px) scale(.97); transition: opacity .42s var(--ease), transform .46s var(--ease-back); }
.stagger.in > * { opacity: 1; transform: none; }
.stagger.in > *:nth-child(1){transition-delay:.00s}.stagger.in > *:nth-child(2){transition-delay:.07s}
.stagger.in > *:nth-child(3){transition-delay:.14s}.stagger.in > *:nth-child(4){transition-delay:.21s}
.stagger.in > *:nth-child(5){transition-delay:.28s}.stagger.in > *:nth-child(6){transition-delay:.35s}

.glow { position: relative; overflow: hidden; }
.glow::after { content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
               background: radial-gradient(280px circle at var(--mx,50%) var(--my,50%), oklch(0.700 0.110 200 / .14), transparent 66%);
               opacity: 0; transition: opacity .4s var(--ease); }
.glow:hover::after { opacity: 1; }

.thread-bar { position: fixed; inset: 0 0 auto; height: 3px; z-index: 90; transform-origin: 0 50%;
              transform: scaleX(var(--p, 0)); background: linear-gradient(90deg, var(--accent), var(--accent-lit), var(--amber)); }

/* ---- Switcher ------------------------------------------------------------ */
.style-switch { position: fixed; bottom: 16px; right: 16px; z-index: 80;
                display: flex; align-items: center; gap: 4px; padding: 5px 5px 5px 12px;
                background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r-pill);
                font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
                color: var(--faint); box-shadow: var(--shadow-2); }
.style-switch a { min-width: 30px; text-align: center; padding: 6px 10px; 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) {
  @view-transition { navigation: none; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
                           transition-duration: .001ms !important; }
  .reveal, .stagger > * { opacity: 1; transform: none; }
  .wipe { clip-path: none !important; }
  .steps i { transform: scaleX(1); opacity: 1; }
  .skill .bar i { width: var(--lv, 50%); }
  .typing { display: none !important; }
  .said[data-typing] > .bubble { display: block !important; }
  .thread-bar { display: none; }
}

/* ---- The bubble, grown -----------------------------------------------------
   Same corner, same tail: the panel scales out of the mascot rather than
   appearing beside it, which is what makes the two read as one object. */
.assist-drop {
  position: absolute; top: calc(100% + 12px); right: -4px; z-index: 70;
  width: min(408px, calc(100vw - 28px));
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-2);
  transform-origin: calc(100% - 20px) -12px;
  overflow: hidden;
}
.assist-drop[hidden] { display: none; }
.assist-drop::before {
  content: ""; position: absolute; top: -7px; right: 16px; width: 14px; height: 14px;
  background: var(--card); border-left: 1px solid var(--line); border-top: 1px solid var(--line);
  transform: rotate(45deg); border-radius: 3px 0 0 0;
}
.assist-drop.opening { animation: dropIn .42s var(--ease-back) both; }
.assist-drop.closing { animation: dropOut .18s var(--ease) both; }
@keyframes dropIn  { from { opacity: 0; transform: translateY(-10px) scale(.82); } to { opacity: 1; transform: none; } }
@keyframes dropOut { to { opacity: 0; transform: translateY(-8px) scale(.9); } }

@media (max-width: 560px) {
  .assist-drop { position: fixed; top: 62px; right: 12px; left: 12px; width: auto;
                 transform-origin: calc(100% - 30px) -12px; }
}

@media (prefers-reduced-motion: reduce) {
  .buddy-float, .buddy .eyes, .buddy-btn.pending .buddy-float, .buddy-btn.pending .buddy-badge { animation: none !important; }
  .assist-drop.opening, .assist-drop.closing { animation: none !important; }
  .buddy .pupil { transition: none; }
}

/* ---- The one CTA that opens work ----------------------------------------
   A client has an account for one reason: to ask for a person. So the action
   that opens a position is not buried in a page — it rides in the bar, on
   every screen after the sign-in, and it is the only filled button up there.

   On a phone the label goes and the plus stays: the target keeps its 44px,
   and a lone plus in a portal bar is unambiguous once the page below it is
   a list of positions. */
.cta-new { flex: none; text-decoration: none; padding-left: 16px; padding-right: 18px; }
.cta-new svg { flex: none; }
@media (max-width: 720px) {
  .cta-new { padding: 0; width: 44px; min-height: 44px; border-radius: 50%; gap: 0; }
  .cta-new span, .cta-new { font-size: 0; }
  .cta-new svg { width: 18px; height: 18px; }
}

/* The big version, for the page that lists what is running. */
.cta-block { display: grid; gap: var(--s3); place-items: center; text-align: center; padding: var(--s5) var(--s4); }
.cta-block h2 { margin: 0; }
.cta-block p { margin: 0 auto; max-width: 38ch; }

/* ---- The form that opens work -------------------------------------------
   Fields grouped into islands with a heading, never one flat column: a client
   filling this in is describing a person to a stranger, and a flat column
   gives them no idea how much is left. Each island answers one question.

   The bar at the foot is anchored, so the primary action never scrolls out of
   reach on a long form. */
.island { padding: var(--s4); }
.island + .island { margin-top: var(--s3); }
.island .isl-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: var(--s4); }
.island .isl-head .no { width: 28px; height: 28px; flex: none; display: grid; place-items: center;
                        border-radius: 50%; font-size: 13px; font-weight: 700;
                        color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent-line); }
.island .isl-head h2 { font-family: var(--font-serif); font-weight: 600; font-size: 21px;
                       letter-spacing: -.02em; margin: 0; }
.island .isl-head p { margin: 3px 0 0; font-size: 14px; color: var(--faint); }
.f-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3) var(--s4); }
.f-row.one { grid-template-columns: 1fr; }
@media (max-width: 640px) { .f-row { grid-template-columns: 1fr; } }
/* Stesso sfondo degli input (`--card-2`, e bianco al fuoco): prima textarea e
   select erano bianchi e gli input grigi, e sembrava una logica — non lo era. */
.field textarea { width: 100%; min-height: 104px; padding: 12px 15px; font-size: 15px; color: var(--ink);
                  background: var(--card-2); border: 1.5px solid var(--line-2); border-radius: var(--r-sm);
                  outline: none; resize: vertical; line-height: 1.6;
                  transition: border-color .2s var(--ease), background .2s var(--ease), box-shadow .2s var(--ease); }
.field textarea:focus { border-color: var(--accent); background: var(--card); box-shadow: 0 0 0 4px var(--accent-soft); }
.field select { width: 100%; min-height: 48px; padding: 12px 15px; font-size: 15px; 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), background .2s var(--ease), box-shadow .2s var(--ease); }
.field select:focus { border-color: var(--accent); background: var(--card); box-shadow: 0 0 0 4px var(--accent-soft); }
/* L'asterisco dell'obbligatorio: uno solo in tutto il modulo, e si vede. */
.field label .req { color: var(--accent-deep); font-weight: 700; margin-left: 2px; }
.pickset { display: flex; flex-wrap: wrap; gap: 8px; }
.pick { display: inline-flex; align-items: center; gap: 7px; min-height: 42px; padding: 8px 16px; cursor: pointer;
        font-size: 14.5px; color: var(--muted); background: var(--card); border: 1.5px solid var(--line-2);
        border-radius: var(--r-pill); transition: color .18s var(--ease), border-color .18s var(--ease), background .18s var(--ease); }
.pick:hover { color: var(--ink); border-color: var(--accent-line); }
.pick.on { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.pick.add { border-style: dashed; color: var(--faint); }
@media (pointer: coarse) { .pick { min-height: 44px; } }

.save-bar { position: sticky; bottom: 0; z-index: 40; display: flex; align-items: center; gap: var(--s3);
            justify-content: space-between; margin-top: var(--s3);
            /* Bassa apposta, e UNA riga sempre: sta sopra il modulo per tutto
               il tempo, e ogni pixel suo è un pixel di campo coperto. Niente
               wrap — quando lo spazio stringe è la frase a sinistra a farsi
               da parte (sotto), non i bottoni a impilarsi. */
            padding: 10px var(--s3); border-radius: var(--r-lg);
            background: color-mix(in oklab, var(--card) 92%, transparent); backdrop-filter: blur(14px);
            border: 1px solid var(--line); box-shadow: var(--shadow-2); }
.save-bar .left { font-size: 14px; color: var(--muted); min-width: 0;
                  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Riga, per esteso: più sotto c'è un `.acts` generico (la colonna delle
   mosse sulla scheda del candidato) che dice column e min-width 220px, e
   tutto ciò che qui non viene ridichiarato lo eredita da lì. È così che
   Annulla è finito SOPRA il bottone d'invio, con la barra alta il doppio. */
.save-bar .acts { display: flex; flex-direction: row; align-items: center;
                  gap: 10px; flex-shrink: 0; min-width: 0; }
.save-bar .acts .btn { white-space: nowrap; width: auto; }
@media (max-width: 900px) { .save-bar .left { display: none; } }

/* What happens after the form is sent, said in three lines. It is the answer
   to the question every client has before pressing a button that summons work. */
.next { list-style: none; margin: 0; padding: 0; counter-reset: n; }
.next li { position: relative; padding: 0 0 var(--s3) 38px; counter-increment: n; font-size: 14.5px; color: var(--muted); }
.next li:last-child { padding-bottom: 0; }
.next li::before { content: counter(n); position: absolute; left: 0; top: -1px; width: 24px; height: 24px;
                   display: grid; place-items: center; border-radius: 50%; font-size: 12.5px; font-weight: 700;
                   color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent-line); }
.next li b { display: block; color: var(--ink); font-weight: 650; font-size: 15px; margin-bottom: 2px; }

/* ============================================================================
   THE DOOR — sign-in and first password
   ----------------------------------------------------------------------------
   Lifted from the chosen mockup's own <style>. The petrol room, the drifting
   aurora and the dotted field belong to these two screens only: after the
   door, the product is paper and light. Keeping them here rather than in a
   page-level <style> means the two screens cannot drift apart.
   ============================================================================ */

        .stage { min-height: 100vh; display: grid; grid-template-columns: 1.08fr .92fr; align-items: center; }
    @media (max-width: 940px) { .stage { grid-template-columns: 1fr; align-items: start; } }

    .aurora { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
    .aurora span { position: absolute; border-radius: 50%; filter: blur(76px); will-change: transform;
                   animation: drift 26s ease-in-out infinite; }
    .aurora .a1 { width: 60vw; height: 60vw; top: -26vw; right: -14vw; background: oklch(0.545 0.105 205 / .50); }
    .aurora .a2 { width: 44vw; height: 44vw; bottom: -20vw; left: -12vw; background: oklch(0.435 0.085 214 / .55);
                  animation-duration: 34s; animation-direction: reverse; }
    .aurora .a3 { width: 26vw; height: 26vw; top: 34%; left: 42%; background: oklch(0.760 0.108 199 / .16);
                  animation-duration: 30s; animation-delay: -8s; }
    .grid-field { position: fixed; inset: 0; z-index: 0; pointer-events: none;
      background-image: radial-gradient(circle, oklch(1 0 0 / .085) 1px, transparent 1px);
      background-size: 30px 30px;
      -webkit-mask-image: radial-gradient(96% 78% at 26% 34%, #000 12%, transparent 74%);
      mask-image: radial-gradient(96% 78% at 26% 34%, #000 12%, transparent 74%); }
    .stage > * { position: relative; z-index: 1; }

    .say { padding: clamp(36px, 5vw, 88px); max-width: 640px; }
    .say h1 { font-size: clamp(38px, 5vw, 64px); margin-bottom: var(--s4); }
    .say .lede { margin-bottom: var(--s6); color: oklch(1 0 0 / .52); }
    .proof { display: grid; gap: 13px; }
    .proof-row { display: flex; align-items: center; gap: 12px; }
    .proof .ic { width: 32px; height: 32px; flex: none; display: grid; place-items: center; border-radius: 9px;
                 color: oklch(1 0 0 / .82); background: oklch(1 0 0 / .07); border: 1px solid oklch(1 0 0 / .13); }
    .proof .tx { font-size: 13.5px; color: oklch(1 0 0 / .55); }
    .proof .tx b { color: oklch(1 0 0 / .88); font-weight: 550; }

    .cardwrap { padding: clamp(26px, 4vw, 72px) clamp(20px, 5vw, 80px) clamp(26px, 4vw, 72px) 0; }
    @media (max-width: 940px) { .cardwrap { padding: clamp(24px, 6vw, 40px) clamp(20px, 6vw, 40px) 64px; } }
    .panel { max-width: 424px; margin-left: auto; padding: clamp(26px, 3vw, 38px);
             background: linear-gradient(168deg, oklch(0.243 0.038 217 / .82), oklch(0.212 0.034 219 / .90));
             backdrop-filter: blur(22px) saturate(1.25); border: 1px solid var(--line-2); border-radius: 24px;
             box-shadow: var(--shadow-2); position: relative; overflow: hidden; }
    .panel::before { content: ""; position: absolute; inset: 0 0 auto; height: 1px;
                     background: linear-gradient(90deg, transparent, oklch(1 0 0 / .30) 30%, oklch(1 0 0 / .30) 70%, transparent); }
    .panel h2 { font-family: var(--font-serif); font-weight: 600; font-size: 27px; letter-spacing: -.022em; margin: 13px 0 5px; }
    .panel .sub { font-size: 14px; color: var(--muted); margin: 0 0 var(--s4); }
    .row-end { display: flex; justify-content: flex-end; margin: -2px 0 var(--s3); }
    .panel .btn-primary { width: 100%; }
    .panel .foot { margin-top: var(--s4); padding-top: var(--s3); border-top: 1px solid var(--line);
                   text-align: center; font-size: 12.5px; color: var(--faint); line-height: 1.7; }
    .sig { display: flex; align-items: center; gap: 12px; margin-top: var(--s5); }
    .sig .t { font-size: 13px; color: oklch(1 0 0 / .5); }
    .sig .t b { display: block; color: oklch(1 0 0 / .9); font-size: 14.5px; font-weight: 600; }
  
/* ---- Messages the mockups never had to show -----------------------------
   A refused sign-in and a rejected field. Both live on the deep side of the
   product, so they are drawn against it rather than against paper. */
.notice { padding: 12px 15px; border-radius: var(--r-sm); font-size: 14px; line-height: 1.55;
          margin: 0 0 var(--s3); }
.notice.bad { color: oklch(0.92 0.05 25); background: oklch(0.55 0.16 25 / .16);
              border: 1px solid oklch(0.62 0.17 25 / .40); }
body:not(.deep) .notice.bad { color: var(--no); background: var(--no-soft);
                              border-color: oklch(0.52 0.15 28 / .30); }
.field-error { margin: 7px 0 0; font-size: 13px; line-height: 1.5; color: oklch(0.80 0.11 25); }
body:not(.deep) .field-error { color: var(--no); }
/* Django renders its own labels for the password fields; keep them in the
   portal's voice rather than the framework's. */
.panel .field ul { margin: 7px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--faint); }

/* --- Formazione, lingue e certificazioni ---------------------------------
   Tre elenchi corti, affiancati: da soli occuperebbero tre schede intere per
   dire nove righe in tutto. Su schermo stretto tornano uno sotto l'altro,
   perché a quel punto le colonne sono più strette delle parole che contengono. */
.trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s4); }
@media (max-width: 900px) { .trio { grid-template-columns: 1fr; gap: var(--s3); } }
.trio h3 { font-size: 11px; font-weight: 700; letter-spacing: .15em; text-transform: uppercase;
           color: var(--faint); margin: 0 0 12px; }
.trio p { margin: 0 0 11px; font-size: 14px; }
.trio p:last-child { margin-bottom: 0; }
.trio p b { font-weight: 650; }
.trio p span { display: block; font-size: 13px; color: var(--faint); margin-top: 2px; line-height: 1.5; }

/* ---- La richiesta del cliente, tagliata a due righe ----------------------
   Una richiesta lunga era la cosa piu' alta della pagina e spingeva la bacheca
   sotto la piega, quando la bacheca e' la ragione per cui uno apre questa
   pagina.

   Il taglio vive sotto `.js` di proposito: senza JavaScript non si taglia
   niente. Un riquadro chiuso da uno script che non parte e' testo che sparisce
   — e questo e' il testo che il cliente ci ha scritto lui. */
.brief { font-size: 16px; line-height: 1.72; color: var(--muted); margin: 0;
         white-space: pre-line; }
.js .brief[data-clamp] { display: -webkit-box; -webkit-box-orient: vertical;
                         -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.js .brief[data-clamp].open { display: block; overflow: visible; }
.brief-more { margin-top: 10px; padding: 0; border: 0; background: none; cursor: pointer;
              font: inherit; font-size: 14px; font-weight: 600; color: var(--accent);
              text-decoration: underline; text-underline-offset: 3px; }
.brief-more:hover { color: var(--accent-deep); }

/* ---- The pipeline, five columns wide -------------------------------------
   Kept as columns rather than a list because the question a client asks here
   is "how many are where", and a column answers it without being read. Empty
   stages stay: a board that hides them redraws itself whenever somebody moves
   and then nothing sits still long enough to be recognised. */
/* Niente `align-items: start` qui: il valore normale di una griglia è
   `stretch`, ed è quello che tiene le cinque colonne alte uguali. Con `start`
   ognuna si accorcia sul proprio contenuto, quindi appena qualcuno entra in
   una colonna quella cresce e le altre restano indietro — una fila di scalini
   invece di una bacheca. */
.pipe { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--s2); }
@media (max-width: 900px) { .pipe { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .pipe { grid-template-columns: 1fr; } }

/* Il testo che dice che qui si fa, non si guarda. Due versioni, una per chi ha
   il JavaScript e una per chi no — le regole stanno qui e non nel template
   perche' `html.js` la mette lo script prima che si disegni qualcosa, e cosi'
   non si vede mai la frase sbagliata comparire e sparire. */
.pipe-intro { margin: 0 0 var(--s3); font-size: 14px; line-height: 1.6; color: var(--muted);
              padding-left: var(--s3); border-left: 2px solid var(--accent-line); }
.js .no-js-only { display: none; }
html:not(.js) .js-only { display: none; }

/* La colonna: una carta vera, con la sua intestazione appoggiata sopra la
   pila. La riga colorata in cima e' la sola cosa che distingue una colonna
   dall'altra a colpo d'occhio — il testo lo si legge dopo. */
.pipe-col { position: relative; background: var(--card-2); border: 1px solid var(--line);
            border-radius: var(--r-sm); padding: var(--s2); min-height: 132px;
            transition: background .2s var(--ease), border-color .2s var(--ease),
                        box-shadow .2s var(--ease); }
.pipe-col::before { content: ""; position: absolute; left: var(--s2); right: var(--s2); top: 0;
                    height: 3px; border-radius: 0 0 3px 3px; background: var(--line-2); }
.pipe-col.theirs { background: var(--amber-soft); border-color: oklch(0.760 0.115 62 / .38); }
.pipe-col.theirs::before { background: var(--amber); }
.pipe-col.closed { opacity: .72; }
.pipe-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
             margin: 4px 0 var(--s2); }
.pipe-head .lbl { font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
                  color: var(--faint); line-height: 1.3; }
.pipe-head .num { font-family: var(--font-serif); font-size: 19px; font-weight: 600; color: var(--ink);
                  font-variant-numeric: tabular-nums; }
.pipe-col.theirs .pipe-head .num { color: var(--amber-ink); }

/* La scheda: iniziali, nome, e un dettaglio sotto. Le iniziali sono la stessa
   pastiglia che la persona porta sulla sua scheda piu' in basso — e' la stessa
   persona, e riconoscerla senza leggere e' meta' del lavoro di una bacheca. */
.pipe-card { display: block; padding: 9px 10px; margin-bottom: 6px; text-decoration: none;
             color: inherit; background: var(--card); border: 1px solid var(--line);
             border-radius: 11px; box-shadow: var(--shadow-1);
             transition: transform .2s var(--ease), border-color .2s var(--ease),
                         box-shadow .2s var(--ease); }
.pipe-card:last-child { margin-bottom: 0; }
.pipe-card:hover { transform: translateY(-1px); border-color: var(--accent-line);
                   box-shadow: var(--shadow-2); }
.pipe-card:active { transform: translateY(0) scale(.985); }
.pipe-card .who { display: flex; align-items: center; gap: 7px; }
.pipe-card .ini { flex: none; display: grid; place-items: center; width: 22px; height: 22px;
                  border-radius: 7px; font-size: 9.5px; font-weight: 700; letter-spacing: .02em;
                  color: var(--card); background: linear-gradient(145deg, var(--glow-2), var(--accent)); }
.pipe-card b { font-size: 13.5px; font-weight: 600; line-height: 1.25; }
.pipe-card .det { display: block; margin-top: 5px; padding-left: 29px; font-size: 12px;
                  color: var(--faint); }

/* Trascinabile: lo dice il cursore, che e' l'unico posto dove un'interfaccia
   puo' dirlo prima che qualcuno ci provi. Solo dove il trascinamento c'e'
   davvero — `[data-pipe]` lo mette la pagina solo a chi puo' agire. */
[data-pipe] .pipe-card[data-person] { cursor: grab; }
[data-pipe] .pipe-card[data-person]:active { cursor: grabbing; }
.pipe-card.dragging { opacity: .45; box-shadow: none; }

/* Dove si puo' lasciare, mentre si sta trascinando: le caselle buone si
   accendono, le altre restano quello che sono. Meglio dirlo prima che dopo —
   una casella che accetta il gesto per poi rifiutarlo e' peggio di una che
   non lo accetta. */
.pipe.is-dragging .pipe-col[data-drop] { border-style: dashed; border-color: var(--accent); }
.pipe.is-dragging .pipe-col[data-drop] .pipe-head .lbl { color: var(--accent-deep); }
.pipe-col.drop-over { background: var(--accent-soft); border-color: var(--accent);
                      border-style: solid; box-shadow: 0 0 0 3px var(--accent-soft); }
.pipe-col[data-drop]::after { content: attr(data-drop-tip); display: none; margin-top: var(--s2);
                              font-size: 11.5px; font-weight: 600; color: var(--accent-deep);
                              line-height: 1.35; }
.pipe.is-dragging .pipe-col[data-drop]::after { display: block; }

/* Vuota: una frase, non un trattino. «—» resta una casella rotta finche' non
   si capisce che vuol dire «qui non c'e' nessuno». */
.pipe-empty { display: block; padding: var(--s2) 0; font-size: 12.5px; color: var(--faint);
              text-align: center; border: 1px dashed var(--line-2); border-radius: 10px; }

@media (prefers-reduced-motion: reduce) {
  .pipe-card, .pipe-col { transition: none; }
  .pipe-card:hover { transform: none; }
}

/* ---- Language switch -----------------------------------------------------
   Small, present everywhere, and never the loudest thing on the screen: it is
   a preference somebody sets once, not an action they take often. */
.lang { display: inline-flex; gap: 3px; padding: 3px; border-radius: var(--r-pill);
        background: color-mix(in oklab, var(--ink) 5%, transparent); }
.lang form { margin: 0; display: inline; }
.lang-btn { display: inline-flex; align-items: center; gap: 5px; min-height: 32px; padding: 5px 10px;
            cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--muted);
            background: transparent; border: 0; border-radius: var(--r-pill);
            transition: color .18s var(--ease), background .18s var(--ease); }
.lang-btn:hover { color: var(--ink); background: var(--card); }
.lang-btn.on { color: var(--on-accent); background: var(--accent); }
.lang-btn .code { letter-spacing: .04em; }
body.deep .lang { background: oklch(1 0 0 / .07); }
body.deep .lang-btn:hover { background: oklch(1 0 0 / .10); }
@media (pointer: coarse) { .lang-btn { min-height: 44px; } }

/* ---- After an action -----------------------------------------------------
   One line, at the top of the page it happened on. Not a toast that fades:
   somebody who pressed a button and looked away must still be able to find out
   whether it worked. */
.flash-wrap { max-width: 1280px; margin: 0 auto; padding: var(--s3) clamp(18px, 3.4vw, 40px) 0; }
.flash { margin: 0 0 var(--s2); padding: 13px 17px; border-radius: var(--r-sm);
         font-size: 15px; line-height: 1.55; }
.flash.success { color: var(--accent-deep); background: var(--accent-soft); border: 1px solid var(--accent-line); }
.flash.error { color: var(--no); background: var(--no-soft); border: 1px solid oklch(0.520 0.150 28 / .30); }

/* ---- La riga di stato, sotto il nome -------------------------------------
   A che punto siamo, detto una volta. Prima erano fino a cinque pillole in
   fila, e due dicevano la stessa cosa con parole diverse: «Colloquio fissato»
   e «Colloquio 23 febbraio, 11:11».

   Il colore lo porta chi ha la palla, con le tre tinte che il portale usa
   ovunque: ambra quando tocca al cliente (o quando il colloquio sta per
   cominciare), petrolio quando la mossa e' nostra, verde quando e' chiusa.

   `state-line` e non `state`: `state` esisteva gia', ed e' la parola dello
   stato dentro la riga di una ricerca (`_search_row.html`). Chiamandola uguale
   quella parola si e' ritrovata addosso uno sfondo, un bordo e un padding —
   cioe' un bottone «Aperta», in mezzo a una lista, che non si poteva premere. */
.state-line { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px;
              margin: 14px 0 0; padding: 11px 16px; border-radius: var(--r-sm);
              background: var(--card-2); border: 1px solid var(--line); font-size: 14.5px; }
.state-line .dot { width: 9px; height: 9px; flex: none; border-radius: 50%; background: var(--accent); }
.state-line b { font-weight: 650; }
.state-line .sep { color: var(--line-2); }
.state-line .when { color: var(--muted); }
.state-line.you { background: var(--amber-soft); border-color: oklch(0.755 0.115 62 / .45); }
.state-line.you .dot { background: var(--amber-ink); }
.state-line.ok { background: var(--ok-soft); border-color: oklch(0.470 0.090 160 / .35); }
.state-line.ok .dot { background: var(--ok); }

/* ---- La scatola delle mosse ----------------------------------------------
   L'unico posto della pagina con dei bottoni, e per questo si distingue: il
   bordo prende il colore dell'accento e il titolo pure. Prima le mosse
   stavano nell'header sotto una scaletta di stato, vestite da testo, e non si
   capiva piu' cosa fosse un'informazione e cosa un comando. */
.card.do { border-color: var(--accent-line); }
.card.do .h-sec { color: var(--accent-deep); }
.do-ask { margin: 0 0 var(--s3); font-size: 13.5px; line-height: 1.6; font-weight: 650; color: var(--amber-ink); }
.do-live { display: flex; align-items: center; gap: 9px; margin: 0 0 var(--s3);
           font-size: 13.5px; font-weight: 650; color: var(--amber-ink); }
.do-live .pulse { width: 8px; height: 8px; flex: none; border-radius: 50%;
                  background: var(--amber-ink); animation: breathe 2s var(--ease) infinite; }

/* ---- La colonna delle mosse, in testa alla scheda di una persona ---------
   Un bottone solo, ed e' la mossa di adesso. Le altre restano li' ma come
   testo su cui si clicca: tre pill identiche una sotto l'altra chiedevano di
   leggerle tutte e tre per capire cosa stessimo chiedendo, e non stavamo
   chiedendo tre cose.

   Quale sia il bottone lo decide il server (`presenters._next_move`, vestito
   da `views._cta_weights`), non il CSS: qui ci sono solo i due pesi. */
.acts { display: flex; flex-direction: column; gap: 9px; min-width: 220px; }
/* Largo quanto la colonna, senza doverlo scrivere addosso a ogni bottone:
   erano cinque `style="width:100%"` uguali, e il sesto sarebbe stato quello
   dimenticato. */
.acts .btn { width: 100%; }

/* L'ordine vero della colonna, che non e' quello dell'HTML: la mossa di
   adesso in cima, sotto la scaletta di dove siamo. Cosi' l'HTML resta scritto
   nell'ordine in cui si raccontano le mosse — colloquio, si', no — e il
   bottone si legge comunque per primo, che sia il primo o il secondo. */
.acts .mini-path { order: -2; }
.acts .act-lead { order: -1; }

/* Le mosse che non sono quella di adesso: stessa forma, peso diverso. Un
   bordo invece del pieno — non del testo. Erano testo, e si leggevano come
   voci di elenco: nessuno preme una voce di elenco.

   `.act-quiet` esce dal server (`views._cta_weights`) e qui vale quanto un
   `btn btn-soft btn-sm`, cosi' la classe che decide il peso resta una sola. */
.act-quiet { display: inline-flex; align-items: center; justify-content: center;
             width: 100%; min-height: 38px; padding: 8px 15px; gap: 8px;
             font-family: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
             color: var(--ink); background: var(--card);
             border: 1px solid var(--line-2); border-radius: var(--r-pill);
             box-shadow: var(--shadow-1); text-decoration: none;
             transition: border-color .2s var(--ease), color .2s var(--ease), background .2s var(--ease); }
.act-quiet:hover { border-color: var(--accent); color: var(--accent-deep); }
@media (pointer: coarse) { .act-quiet { min-height: 44px; } }
/* Il no vira al rosso solo quando ci passi sopra, dove serve a dire cosa stai
   per fare — non prima, quando servirebbe solo a farti paura. */
.act-quiet.act-no:hover, .btn-no:hover { color: var(--no); border-color: var(--no); background: var(--no-soft); }

/* La scaletta in testa all'isola: dove siamo, prima di cosa puoi fare.
   Le stesse quattro tappe della card «Dove siamo» piu' in basso, ridotte a
   quello che ci sta in una colonna stretta — una riga per tappa, il pallino a
   sinistra e la linea che li tiene insieme.

   Il colore lo porta lo stato, non l'animazione d'ingresso: legarlo a `.in`
   voleva dire che con `prefers-reduced-motion` restavano quattro pallini grigi
   identici. Stesso errore gia' pagato sui pallini della riga di una ricerca. */
.mini-path { list-style: none; margin: 0 0 var(--s2); padding: 0 0 0 17px; position: relative; }
.mini-path::before { content: ""; position: absolute; left: 4px; top: 7px; bottom: 7px;
                     width: 1.5px; background: var(--line-2); }
.mini-path li { position: relative; display: flex; align-items: baseline; gap: 6px;
                padding: 3px 0; font-size: 12.5px; line-height: 1.35; color: var(--faint); }
.mini-path li::before { content: ""; position: absolute; left: -17px; top: 8px;
                        width: 9px; height: 9px; border-radius: 50%;
                        background: var(--card); border: 1.5px solid var(--line-2); }
.mini-path li.past { color: var(--muted); }
.mini-path li.past::before { background: var(--line-2); border-color: var(--line-2); }
/* Dove sei: pieno, con l'anello attorno. Petrolio e non ambra — nel portale
   l'ambra vuol dire «aspetta te», e qui si dice solo a che punto siamo. */
.mini-path li.now { color: var(--ink); font-weight: 650; }
.mini-path li.now::before { background: var(--accent); border-color: var(--accent);
                            box-shadow: 0 0 0 3px var(--accent-soft); }
.mini-path li .on { margin-left: auto; font-size: 11.5px; font-weight: 500; color: var(--faint); }
.acts > form { margin: 0; }

/* Il no. Stessa pill degli altri — la forma dice «sono una mossa come le
   altre», non il colore — e il rosso arriva solo quando ci passi sopra, dove
   serve a dire cosa stai per fare. */
.btn-no { color: var(--muted); }
.btn-no:hover { color: var(--no); border-color: var(--no); background: var(--no-soft); }

/* ---- La riga sotto il nome: cosa fa, e il suo CV -------------------------
   Il CV non e' una delle mosse e non sta con loro: e' il documento della
   persona di cui parla la pagina, e si va a prendere sempre — anche da un
   accesso in sola lettura, anche dopo averlo gia' scaricato. Quindi qui, a
   destra della qualifica, dove lo si cerca.

   Una veste sola, ed e' un link. Ne aveva due — pill piena finche' nessuno
   l'aveva aperto, link dopo — e quel peso che cambiava diceva una cosa non
   piu' vera: che scaricarlo fosse una delle decisioni della pagina.

   `baseline`: la parola del link sta sulla stessa riga di scrittura della
   qualifica, altrimenti si legge come una didascalia staccata. */
.ident-line { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 16px;
              font-size: 16px; color: var(--muted); }
/* La freccia: e' lei che dice «scarica» prima che si legga la parola. */
.cv-arrow { width: 15px; height: 15px; flex: none; vertical-align: -2px; }
/* Il link resta un pezzo di testo — `inline`, non `inline-flex` — cosi' la
   sua riga di scrittura e' la stessa della qualifica accanto: la baseline di
   una scatola flex la detta il primo figlio, che qui e' la freccia, e il
   testo finiva mezzo carattere piu' su. `nowrap` perche' la freccia e le due
   parole sono una cosa sola e non si spezzano a fine riga. */
.cv-get { font-size: 14px; white-space: nowrap; }
.cv-get .cv-arrow { margin-right: 6px; }

/* La casella del perche', dentro la finestra del no. */
.ask-dialog textarea { width: 100%; padding: 11px 14px; font-size: 14.5px; color: var(--ink);
                       background: var(--card); border: 1.5px solid var(--line-2);
                       border-radius: var(--r-sm); outline: none; resize: vertical; font-family: inherit; }
.ask-dialog textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* ---- Notices that are not errors ----------------------------------------- */
.notice.info { color: var(--accent-deep); background: var(--accent-soft); border: 1px solid var(--accent-line);
               padding: 14px 17px; border-radius: var(--r-sm); font-size: 15px; line-height: 1.6; }

/* ---- Chiedere un colloquio, in una finestra vera --------------------------
   Senza `.js` il `<dialog>` porta `open` scritto a mano: un `<dialog>` con
   quell'attributo ma mai aperto via script è un riquadro normale nel flusso
   della pagina, non un modale — niente sfondo, niente top layer. È lo stato
   "funziona anche rotto" di questo controllo.

   Sotto `.js`, portal.js lo chiude appena la pagina è pronta e mostra al suo
   posto il bottone piccolo: da lì `showModal()` lo promuove davvero, con lo
   sfondo scurito e senza ereditare la larghezza di nessun genitore — motivo
   per cui esiste, al posto del `<details>` di prima che si allargava dentro
   la colonna stretta dell'header. */
/* Nascosto in HTML e basta — non sotto `.js`: se lo script si rompe a metà,
   prima di arrivare a scoprirlo, un bottone invisibile è meglio di uno
   visibile e morto. Lo scopre solo `interviewDialog()`, a riprova che è
   arrivata fin lì.

   La riga sotto è quello che lo nasconde davvero: `.btn` dichiara il suo
   display, e una regola d'autore vince sempre su `[hidden]` del browser. Senza,
   l'attributo c'era e il bottone si vedeva lo stesso — sulla bacheca di una
   ricerca restava sotto le colonne, a finestra chiusa. */
[data-interview-open][hidden] { display: none; }
/* Le tre finestre del portale hanno la stessa forma: chiedere un colloquio,
   dire di no col suo perche', confermare una mossa. Una forma sola perche'
   sono lo stesso momento — la pagina si ferma e ti chiede una cosa. */
.interview-dialog, .ask-dialog, .confirm-dialog {
                    border: 1px solid var(--line-2); border-radius: var(--r-lg); padding: 0;
                    max-width: 480px; width: min(92vw, 480px); max-height: 86vh;
                    background: var(--card); color: var(--ink); box-shadow: 0 24px 60px -15px rgba(0,0,0,.35); }
.interview-dialog::backdrop, .ask-dialog::backdrop, .confirm-dialog::backdrop {
                    background: oklch(0.2 0.02 250 / .5); backdrop-filter: blur(2px); }

/* La conferma e' piu' stretta di una finestra che chiede dei dati: dentro non
   c'e' niente da compilare, una domanda e due strade. */
.confirm-dialog { width: min(92vw, 420px); }
.confirm-body { margin: 0 0 var(--s3); font-size: 14.5px; line-height: 1.65; color: var(--muted); }
/* La riga di note dentro la conferma: facoltativa, e si vede che lo e' —
   niente asterischi, niente bordo acceso finche' non ci si scrive. */
.confirm-note { display: block; margin: 0 0 var(--s3); font-size: 13px; color: var(--faint); }
.confirm-note span { display: block; margin-bottom: 6px; }
.confirm-note textarea { width: 100%; padding: 10px 13px; font-family: inherit; font-size: 14.5px;
                         color: var(--ink); background: var(--card); border: 1.5px solid var(--line-2);
                         border-radius: var(--r-sm); outline: none; resize: vertical; }
.confirm-note textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.confirm-acts { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }
.confirm-acts .btn { min-width: 120px; }
.idlg-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
             padding: 16px 20px; border-bottom: 1px solid var(--line); }
.idlg-head b { font-family: var(--font-serif); font-size: 17px; font-weight: 650; }
.idlg-head button { flex: none; width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--line-2);
                     background: var(--card-2); color: var(--faint); cursor: pointer; font-size: 16px;
                     line-height: 1; display: grid; place-items: center; }
.idlg-head button:hover { color: var(--ink); border-color: var(--accent-line); }
.idlg-body { padding: 20px; overflow-y: auto; }

/* Il gesto di aggiungere un orario: una casella, un bottone, e la pillola che
   ne esce finisce nella lista sotto. Nascosti senza `.js` — senza script non
   farebbero niente — e il `<noscript>` accanto scopre tre caselle semplici al
   loro posto: stesso nome di campo (`slot`), stessa cosa per il server. */
.slot-add, [data-slot-list] { display: none; }
.js .slot-add { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }
.js [data-slot-list] { display: grid; gap: 8px; }
.slot-add input[type="datetime-local"] { min-height: 46px; padding: 11px 14px;
                                         font-size: 14.5px; color: var(--ink); background: var(--card);
                                         border: 1.5px solid var(--line-2); border-radius: var(--r-sm); outline: none; }
.slot-add input[type="datetime-local"]:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
/* Giorno, ora, minuti: tre caselle sulla stessa riga, il giorno prende il resto. */
.slot-pick { display: flex; gap: 8px; flex-wrap: wrap; }
.slot-pick input[type="date"] { flex: 1 1 160px; width: auto; min-width: 0; }
.slot-pick select { flex: 0 0 auto; width: auto; min-width: 84px; }
.slot-pick input[type="date"], .slot-pick select { min-height: 46px; padding: 11px 14px; font-size: 14.5px;
                                                   color: var(--ink); background: var(--card);
                                                   border: 1.5px solid var(--line-2); border-radius: var(--r-sm); outline: none; }
.slot-pick input[type="date"]:focus, .slot-pick select:focus { border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }

[data-slot-list] .slot { cursor: default; position: relative; padding-right: 40px; }
[data-slot-list] .slot:hover { transform: none; border-color: var(--line); }
[data-slot-list] .slot-remove { position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
                                 width: 24px; height: 24px; border-radius: 50%; border: 0; background: none;
                                 color: var(--faint); cursor: pointer; font-size: 15px; line-height: 1; }
[data-slot-list] .slot-remove:hover { color: var(--no); background: var(--no-soft); }

/* Le tre caselle del `<noscript>`: esistono nel DOM solo quando lo script non
   gira, quindi questa regola non ha bisogno di essere guardata da `.js` — sotto
   `.js` semplicemente non trova niente da vestire. */
.slots input[type="datetime-local"] { width: 100%; min-height: 46px; padding: 11px 14px; font-size: 14.5px;
                                      color: var(--ink); background: var(--card); border: 1.5px solid var(--line-2);
                                      border-radius: var(--r-sm); outline: none; }

/* Le pastiglie di "dove". Il pallino del radio non serve: la pastiglia accesa
   dice già tutto, e lasciarlo visibile fa due controlli per una scelta sola. */
.chips { display: flex; flex-wrap: wrap; gap: 9px; }
/* Il pulsante vero resta nel DOM per la tastiera e per il modulo, ma non occupa
   spazio: grande un punto e chiuso dentro la sua etichetta. Prima ereditava la
   larghezza piena dei campi e, posizionato rispetto alla finestra, sbordava a
   destra con una barra di scorrimento orizzontale (collaudo del 2026-10-06). */
.chips .chip { position: relative; }
.chips .chip input { position: absolute; opacity: 0; pointer-events: none;
                     inset: 0; width: 1px; height: 1px; margin: 0; }
.chips .chip:has(input:checked) { color: var(--on-accent, var(--card)); background: var(--accent);
                                  border-color: var(--accent); font-weight: 600; }
.chips .chip:focus-within { box-shadow: 0 0 0 4px var(--accent-soft); }


/* ============================================================================
   Entrare nel portale.

   Chi ha appena scritto la propria password non deve trovare una pagina: deve
   vederla mettere a fuoco. Il contenuto arriva sfocato e diventa nitido, e il
   titolo si scopre dall'alto come inchiostro che asciuga.

   Niente si sposta. Le cose che volano da un punto all'altro dello schermo
   attirano l'occhio sul movimento e non su quello che c'e' scritto, e su una
   pagina che dice "Buongiorno Anna, tre cose aspettano te" la frase e' la
   cosa. Qui l'unico movimento e' la nitidezza che aumenta — la stessa cosa che
   fa un obiettivo, e nessuno la legge come un'animazione.

   Accade una volta: `is-welcome` sta sull'<html> solo sulla prima pagina dopo
   l'ingresso (`portal.views.home` consuma il segno leggendolo). Ricaricare non
   rimette a fuoco niente, perche' una cosa che si ripete a ogni F5 smette di
   essere un ingresso e diventa un difetto della pagina.
   ============================================================================ */
:root.is-welcome .top,
:root.is-welcome .wrap {
  animation: portal-focus 760ms var(--ease-expo) both;
}

@keyframes portal-focus {
  from {
    opacity: 0;
    filter: blur(11px);
    /* Appena piu' grande, un dodicesimo di percento: quel tanto che basta
       perche' la messa a fuoco sembri una lente che si assesta e non una
       dissolvenza. Piu' di cosi' e' uno zoom, e uno zoom si vede. */
    transform: scale(1.012);
  }
  to { opacity: 1; filter: blur(0); transform: none; }
}

/* Il titolo si scopre dall'alto, appena dopo che la pagina ha messo a fuoco.
   Una maschera, non uno spostamento: le lettere stanno gia' al loro posto e
   vengono scoperte, come una riga di stampa che asciuga. */
:root.is-welcome .wrap .display {
  animation: portal-ink 900ms 160ms var(--ease-expo) both;
}

@keyframes portal-ink {
  from { clip-path: inset(0 0 100% 0); opacity: .2; }
  to { clip-path: inset(0 0 -12% 0); opacity: 1; }
}

/* Le animazioni che la pagina ha gia' — `rise`, `stagger` — partirebbero
   insieme a questa e si sommerebbero: due movimenti sullo stesso elemento si
   leggono come un'esitazione. Durante l'ingresso stanno ferme; ci pensa la
   messa a fuoco, che le riguarda tutte. */
:root.is-welcome .wrap .rise { animation: none; }

@media (prefers-reduced-motion: reduce) {
  :root.is-welcome .top,
  :root.is-welcome .wrap,
  :root.is-welcome .wrap .display { animation: none; filter: none; clip-path: none; }
}

/* ---- L'assistente della nuova ricerca ------------------------------------
   Riusa il filo, le bolle e il composer del pannello assistente (qui sopra);
   queste righe sono solo quello che la pagina della nuova ricerca aggiunge:
   la textarea al posto dell'input — ci si incolla una job description, non
   una riga —, l'etichetta sui campi compilati, e il lampo che accompagna un
   valore appena arrivato nel modulo. */
/* La scatola di Mar.ia: protagonista, non una card fra le card. La testata
   è il petrolio della porta — il colore con cui il portale si presenta — e
   attorno c'è un alone d'accento che la stacca dalla carta della pagina. Il
   filo dei messaggi resta chiaro: il buio è la cornice, non la stanza. */
.assist-box { overflow: hidden; border-color: transparent;
              /* Solo l'ombra lunga: l'anello chiaro provato prima disegnava
                 un bordo fantasma attorno alla testata scura. */
              box-shadow: 0 16px 44px oklch(0.245 0.048 218 / .22); }
.assist-box .assist-head { background: linear-gradient(165deg, var(--deep-2), var(--deep));
                           border-bottom: none; padding: 14px var(--s3); }
.assist-box .assist-head .who-t b { color: oklch(0.97 0.008 210); }
.assist-box .assist-head .who-t span { color: oklch(0.97 0.008 210 / .88); font-size: 12.5px; line-height: 1.35; }
/* La mascotte sul petrolio: il tratto blu-notte del disegno sparirebbe nel
   buio della testata, quindi il contorno qui schiarisce. */
.assist-box .assist-head .buddy .skin { stroke: oklch(0.97 0.008 210 / .35); }
/* `.btn` dichiara il suo display, e una regola d'autore vince sempre su
   `[hidden]` del browser: senza questa riga il bottone nascosto si vede. */
[data-assistant-open][hidden] { display: none; }
/* ---- Incarichi ------------------------------------------------------------
   La riga di un incarico non è una porta: non c'è una pagina dietro, quindi
   niente moto d'invito al passaggio del mouse. E le carte sono pillole-link
   piccole nella riga dei dettagli. */
.rowcard.still:hover { transform: none; border-color: var(--line); box-shadow: none; }
.rowcard.still:hover .shift { transform: none; }
.rowcard.still:hover::before { transform: none; }
.paper { display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px;
         font-size: 12.5px; font-weight: 600; color: var(--accent);
         background: var(--accent-soft); border: 1px solid var(--accent-line);
         border-radius: 999px; text-decoration: none;
         transition: background .18s var(--ease), transform .18s var(--ease); }
.paper:hover { transform: translateY(-1px); border-color: var(--accent); }
/* Le pillole delle carte stanno nella .meta della riga, ma non sono voci di
   un elenco puntato: niente separatore davanti. */
.rowcard .meta > .paper:not(:first-child)::before { content: none; margin: 0; }

/* Il bottone e la Mar.ia che ammicca al suo fianco: vivono e spariscono
   insieme, e la stessa storia di `[hidden]` vale per il contenitore. */
.assist-cta { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s4); }
.assist-cta[hidden] { display: none; }
.assist-cta img { flex: none; object-fit: contain; }
/* La X per rimandarla in spalla: sul petrolio della testata, chiara e
   discreta; quello che ha già scritto nel modulo resta. */
.assist-close { flex: none; width: 30px; height: 30px; display: grid; place-items: center;
                border: 0; border-radius: 999px; background: transparent; cursor: pointer;
                color: oklch(0.97 0.008 210 / .7); transition: background .18s var(--ease), color .18s var(--ease); }
.assist-close:hover { background: oklch(0.97 0.008 210 / .14); color: oklch(0.97 0.008 210); }
.assist-close:focus-visible { outline: 2px solid oklch(0.97 0.008 210 / .8); outline-offset: 2px; }
/* La discesa. Chiuso, il contenitore è una riga di griglia a 0fr — alto
   niente — e aperto va a 1fr: il riquadro «Cosa succede dopo» scende con la
   transizione, senza misurare nessuna altezza a mano. `assist-clip` è il
   ritaglio che tiene dentro la chat mentre la riga cresce. */
.assist-reveal { display: grid; grid-template-rows: 0fr; margin-bottom: 0;
                 transition: grid-template-rows .55s var(--ease), margin-bottom .55s var(--ease); }
/* Stessa storia del bottone qui sopra: `display: grid` è una regola d'autore
   e vincerebbe su `[hidden]` del browser. */
.assist-reveal[hidden] { display: none; }
.assist-reveal.open { grid-template-rows: 1fr; margin-bottom: var(--s3); }
.assist-clip { min-height: 0; overflow: hidden; }
.assist-reveal .assist-box { opacity: 0; transform: translateY(-10px);
                             transition: opacity .5s var(--ease), transform .55s var(--ease); }
.assist-reveal.open .assist-box { opacity: 1; transform: none; }
/* Il filo è la stanza, non uno spioncino: spazio riservato ai fumetti anche
   a conversazione appena nata (min-height), e un tetto che insegue il
   viewport — testata e composer devono restarci dentro, ancorati com'è
   ancorata la colonna. */
.assist-box .assist-thread { min-height: min(380px, 42vh);
                             max-height: min(680px, calc(100vh - 330px)); }
/* L'uscita di scena di «Cosa succede dopo» quando Mar.ia prende la spalla:
   prima lui si dissolve, con calma, e solo a scena vuota entra lei — due
   tempi, non un incrocio. `[hidden]` dopo la dissolvenza, e la solita
   guardia: `.card` non dichiara un display suo, ma la riga costa niente e
   il bottone ci ha già fregato due volte. */
[data-what-next] { transition: opacity .55s var(--ease); }
[data-what-next].leaving { opacity: 0; }
[data-what-next][hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .assist-reveal, .assist-reveal .assist-box, [data-what-next] { transition: none; }
}
.assist-composer textarea { flex: 1; min-width: 0; min-height: 42px; max-height: 160px;
                            padding: 10px 14px; font-size: 14px; line-height: 1.55; resize: none;
                            font-family: inherit; color: var(--ink); background: var(--card);
                            border: 1px solid var(--line-2); border-radius: 16px; outline: none;
                            transition: border-color .18s var(--ease), box-shadow .18s var(--ease); }
.assist-composer textarea::placeholder { color: var(--faint); }
.assist-composer textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.assist-composer button:disabled { opacity: .45; cursor: default; }
.ai-note { margin-left: 8px; font-size: 10.5px; font-weight: 650; color: var(--accent-deep);
           background: var(--accent-soft); border: 1px solid var(--accent-line);
           border-radius: var(--r-pill); padding: 2px 8px; vertical-align: 1px; }
.ai-lit { animation: aiLit 1.6s var(--ease) both; }
@keyframes aiLit { 0% { box-shadow: 0 0 0 4px var(--accent-soft); border-color: var(--accent); }
                   100% { box-shadow: none; } }
@media (prefers-reduced-motion: reduce) { .ai-lit { animation: none; } }

/* ---- L'anteprima dell'archivio ---------------------------------------------
   Schede anonime sulla ricerca appena aperta: monogramma, fatti minimi, le
   skill per cui la persona è in rosa. Ogni scheda è una <label> attorno alla
   sua casella, così si sceglie cliccando ovunque — e senza JavaScript resta
   un modulo qualunque: caselle, bottone, POST. */
.preview-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--s3); }
.preview-card { position: relative; display: flex; flex-direction: column; gap: 10px;
                padding: var(--s3); border-radius: var(--r-leaf); cursor: pointer;
                background: var(--card-2); border: 1.5px solid var(--line-2);
                transition: border-color .18s var(--ease), box-shadow .18s var(--ease); }
.preview-card:hover { border-color: var(--accent-line); }
.preview-card:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.preview-card input[type="checkbox"] { position: absolute; top: 14px; right: 14px;
                                       width: 18px; height: 18px; accent-color: var(--accent); }
.preview-card .who { display: flex; flex-direction: column; gap: 2px; padding-right: 26px; }
.preview-card .who b { font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.preview-card .who span { font-size: 12.5px; color: var(--muted); }
.preview-card .blurb { margin: 0; font-size: 13.5px; line-height: 1.55; color: var(--muted); }
.preview-card .blurb.written { animation: blurbIn .7s var(--ease) both; }
/* I tre puntini mentre il modello scrive la frase: gli stessi della chat,
   in formato francobollo. Se la frase non arriva, spariscono loro — mai
   puntini eterni su una scheda che sta benissimo sui suoi fatti. */
.preview-card .blurb .dots { display: inline-flex; gap: 4px; align-items: center; padding: 2px 0; }
.preview-card .blurb .dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--faint);
                               opacity: .4; animation: typing 1.25s var(--ease) infinite; }
.preview-card .blurb .dots i:nth-child(2) { animation-delay: .16s; }
.preview-card .blurb .dots i:nth-child(3) { animation-delay: .32s; }
@media (prefers-reduced-motion: reduce) { .preview-card .blurb .dots i { animation: none; } }
@keyframes blurbIn { from { opacity: 0; transform: translateY(3px); } }
@media (prefers-reduced-motion: reduce) { .preview-card .blurb.written { animation: none; } }
.preview-card .hits { display: flex; flex-wrap: wrap; gap: 5px; margin-top: auto; }
.preview-card.picked { cursor: default; border-color: var(--line); }
.preview-card .picked-note { position: absolute; top: 12px; right: 12px; }


/* ---- La campanella del portale -------------------------------------------
   Una porta nel chrome, non un allarme: il numero compare solo quando c'è
   qualcosa di aperto e mai letto, e sparisce appena si apre la pagina. */
.bell { position: relative; display: grid; place-items: center; width: 38px; height: 38px;
        border-radius: 50%; color: var(--muted); text-decoration: none;
        transition: background .18s var(--ease), color .18s var(--ease); }
.bell:hover { background: var(--accent-soft); color: var(--accent-deep); }
.bell-n { position: absolute; top: 2px; right: 0; min-width: 16px; height: 16px;
          padding: 0 4px; border-radius: 8px; background: var(--accent);
          color: var(--card); font-size: 10px; font-weight: 700;
          display: grid; place-items: center; line-height: 1; }
