/* grappa.chat — shared stylesheet.
 *
 * Extracted from the inline <style> of index.html when the site grew past one
 * page (vjt, 2026-09-13: "lo splittiamo in piu pagine"). One file for every
 * page and both languages: the alternative was ten copies of the same sheet.
 * The strict grappa CSP is script-src 'self', a same-origin stylesheet passes.
 */
/* Palette borrowed from cicchetto's default (dark) theme so the landing and
   the client read as one product: near-black bg, sky-blue accent, light ink.
   --accent/--bg/--ink/--muted/--line map 1:1 to cic --accent/--bg/--fg/
   --muted/--border; --accent-2 + --glow are lighter/soft derivatives for the
   brand gradient and button bloom. */
:root{
  --bg:#0a0a0a; --panel:#111111; --ink:#e0e0e0; --muted:#8b949e;
  --accent:#5fafd7; --accent-2:#8fd0f0; --line:#1f1f1f; --glow:rgba(95,175,215,.20);
  /* Every top-level section of the home is separated the same way: a gap, a
     hairline, then breathing room under it. One pair of knobs, because vjt
     (2026-09-14: "e' tutto ammassato") should not need six edits to loosen
     the page. */
  --sec-gap:76px; --sec-pad:44px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg);
  color:var(--ink);
  font:16px/1.6 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  -webkit-font-smoothing:antialiased;
  min-height:100vh; display:flex; flex-direction:column;
}
a{color:var(--accent-2); text-decoration:none}
a:hover{text-decoration:underline}
.wrap{width:100%; max-width:760px; margin:0 auto; padding:clamp(24px,6vw,64px) 20px; flex:1}

/* Matrix-rain backdrop lifted from cicchetto's login page (three pure-CSS
   drift layers: far/mid/near via element + ::before + ::after, plus a static
   accent glow bloom). Toned DOWN from the login's opacity .6 → .26 and softer
   accent mixes + slower loops per vjt "un po' meno invasivo": present but it
   doesn't fight the copy. position:fixed z-index:-1 = sits behind content,
   doesn't scroll-tile with the document. Reduced-motion freezes all drifts. */
.matrix{
  position:fixed; inset:0; z-index:-1; pointer-events:none; overflow:hidden;
  opacity:.26;
  background-image:
    repeating-linear-gradient(0deg,
      color-mix(in srgb,var(--accent) 8%,transparent) 0 2px, transparent 2px 16px),
    radial-gradient(65% 55% at 50% 34%,
      color-mix(in srgb,var(--accent) 10%,transparent), transparent 72%);
  background-size:100% 340px, 100% 100%;
  background-repeat:repeat, no-repeat;
  animation:matrix-far 16s linear infinite;
}
.matrix::before,.matrix::after{content:""; position:absolute; inset:0}
.matrix::before{
  background-image:
    repeating-linear-gradient(0deg,
      color-mix(in srgb,var(--accent) 10%,transparent) 0 2px, transparent 2px 11px),
    repeating-linear-gradient(90deg,
      color-mix(in srgb,var(--accent) 6%,transparent) 0 1px, transparent 1px 14px);
  background-size:100% 240px, 100% 100%;
  animation:matrix-mid 10.5s linear infinite;
}
.matrix::after{
  background-image:repeating-linear-gradient(0deg,
    color-mix(in srgb,var(--accent) 14%,transparent) 0 3px, transparent 3px 13px);
  background-size:100% 170px;
  animation:matrix-near 6.5s linear infinite;
}
@keyframes matrix-far{from{background-position:0 0,0 0}to{background-position:0 340px,0 0}}
@keyframes matrix-mid{from{background-position:0 0,0 0}to{background-position:0 240px,0 0}}
@keyframes matrix-near{from{background-position:0 0}to{background-position:0 170px}}

header .mark{
  font-size:clamp(44px,12vw,88px); font-weight:700; letter-spacing:-.02em;
  line-height:1.1; margin:0;
  background:linear-gradient(180deg,var(--accent-2),var(--accent));
  -webkit-background-clip:text; background-clip:text; color:transparent;
  text-shadow:0 0 40px var(--glow);
}
header .mark::before{content:"🍸 "; -webkit-text-fill-color:initial; filter:none}
.tag{color:var(--muted); font-size:clamp(15px,3.4vw,19px); margin:18px 0 0}
.tag b{color:var(--ink); font-weight:600}

/* EN|IT language switcher — a small flag pair at the top of the column. The
   active language is a static pill, the other a link to its URL (/ or /it/).
   i18n.js pins a `lang` cookie on click so the bare-/ nginx negotiation honors
   the explicit choice; with no JS the links still navigate. */
.lang-switcher{display:flex; justify-content:flex-end; gap:6px; margin:0 0 6px; font-size:13px}
.lang-switcher a,.lang-switcher span{display:inline-flex; align-items:center; gap:5px;
  padding:5px 10px; min-height:32px; border-radius:8px; border:1px solid var(--line); line-height:1}
.lang-current{color:var(--ink); background:var(--panel); border-color:var(--accent)}
.lang-link{color:var(--muted)}
.lang-link:hover{color:var(--ink); text-decoration:none; border-color:var(--accent); box-shadow:0 0 16px var(--glow)}

.cta{display:flex; flex-wrap:wrap; gap:12px; margin:34px 0 8px}
.btn{
  display:inline-flex; align-items:center; padding:12px 20px; border-radius:10px;
  border:1px solid var(--accent); background:linear-gradient(180deg,rgba(95,175,215,.16),rgba(95,175,215,.06));
  color:var(--accent-2); font-weight:600;
}
.btn.primary{background:linear-gradient(180deg,var(--accent-2),var(--accent)); color:#04121a; border-color:var(--accent-2)}
.btn.ghub{color:var(--ink)}
.btn.ghub svg{margin-right:8px}
.btn:hover{text-decoration:none; box-shadow:0 0 24px var(--glow)}
.sub{color:var(--muted); font-size:14px; margin:10px 0 0}

.what{margin-top:var(--sec-gap); border-top:1px solid var(--line); padding-top:var(--sec-pad)}
.what h2{font-size:13px; text-transform:uppercase; letter-spacing:.14em; color:var(--muted); font-weight:600; margin:0 0 18px}
.grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:14px}
.card{background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:18px}
.card .n{display:flex; align-items:center; gap:9px; color:var(--accent-2); font-weight:700; margin:0 0 6px}
.stage{font-size:10px; text-transform:uppercase; letter-spacing:.1em; font-weight:600; padding:2px 8px; border-radius:999px; border:1px solid var(--line); color:var(--muted)}
.stage.alpha{color:var(--accent-2); border-color:rgba(95,175,215,.4)}
.stage.beta{color:var(--accent-2); border-color:rgba(95,175,215,.4)}
.card p{margin:0; color:var(--muted); font-size:14px}

.note{margin-top:40px; color:var(--muted); font-size:14px; line-height:1.7}
.note code{background:var(--panel); border:1px solid var(--line); padding:1px 6px; border-radius:6px; color:var(--ink)}

/* "Is this for you?" — a yes/no two-column decision aid (green ✓ / red ✗),
   plus a separate self-hosting teaser card. Reuses the panel/line tokens. */
.foryou{margin-top:var(--sec-gap); border-top:1px solid var(--line); padding-top:var(--sec-pad)}
.foryou h2{font-size:13px; text-transform:uppercase; letter-spacing:.14em; color:var(--muted); font-weight:600; margin:0 0 18px}
.fy-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(250px,1fr)); gap:14px; align-items:start}
.fy-col{background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:18px}
.fy-h{margin:0 0 12px; font-weight:700; font-size:14px}
.fy-col.yes .fy-h{color:#5fd7a7}
.fy-col.no  .fy-h{color:#d78f8f}
.fy-col ul{list-style:none; margin:0; padding:0}
.fy-col li{position:relative; padding:0 0 10px 24px; color:var(--muted); font-size:13.5px; line-height:1.5}
.fy-col li:last-child{padding-bottom:0}
.fy-col li::before{position:absolute; left:0; top:0; font-weight:700}
.fy-col.yes li::before{content:"✓"; color:#5fd7a7}
.fy-col.no  li::before{content:"✗"; color:#d78f8f}
/* `.teaser` is the one-line pointer at a page that carries the long version;
   `.selfhost` is the same panel used on its own. Stacked teasers sit close
   together — the 44px gap is for the first one only, or the home reads as a
   list of unrelated boxes. */
.selfhost,.teaser{margin-top:56px; background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:20px}
.selfhost p,.teaser p{margin:0; color:var(--muted); font-size:13.5px; line-height:1.6}
.selfhost a,.teaser a{font-weight:600}
.teaser + .teaser{margin-top:14px}

footer{border-top:1px solid var(--line); color:var(--muted); font-size:13px}
footer .wrap{padding:22px 20px; display:flex; gap:16px; flex-wrap:wrap; align-items:center; justify-content:space-between}
footer a{color:var(--muted)}

/* Screenshot gallery + pure-CSS :target lightbox — keeps the "no JS" rule.
   Thumbs are a responsive grid (portraits cropped to a common height, top-
   aligned so the header shows); the desktop shot spans the full row. Tapping
   a thumb opens a fixed full-screen overlay for detail on mobile; the overlay
   is itself a link back to #shots, so a tap anywhere (or ✕) closes it. */
.shots{margin-top:var(--sec-gap); border-top:1px solid var(--line); padding-top:var(--sec-pad)}
.shots h2{font-size:13px; text-transform:uppercase; letter-spacing:.14em; color:var(--muted); font-weight:600; margin:0 0 6px}
.shots .lead{color:var(--muted); font-size:14px; margin:0 0 20px}
.shot-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(118px,1fr)); gap:14px}
.shot{display:block; background:var(--panel); border:1px solid var(--line); border-radius:12px; overflow:hidden}
.shot:hover{text-decoration:none; border-color:var(--accent); box-shadow:0 0 20px var(--glow)}
.shot img{display:block; width:100%; height:210px; object-fit:cover; object-position:top center; background:var(--bg)}
.shot figcaption{padding:9px 12px; color:var(--muted); font-size:12px; border-top:1px solid var(--line)}
.shot.wide{grid-column:1/-1}
.shot.wide img{height:auto; object-fit:contain; max-height:440px}

/* Client tabs — radio + :checked, not :target, because the lightbox below
   already owns :target and the two would fight over the fragment. */
.tabs input{position:absolute; opacity:0; pointer-events:none}
.tab-bar{display:flex; gap:8px; margin:0 0 18px}
.tab-bar label{cursor:pointer; padding:7px 14px; border:1px solid var(--line); border-radius:999px;
               color:var(--muted); font-size:13px; background:var(--panel)}
.tab-bar label:hover{border-color:var(--accent); color:var(--ink)}
.tab-panel{display:none}
#tab-cicchetto:checked ~ .tab-bar label[for="tab-cicchetto"],
#tab-shottino:checked ~ .tab-bar label[for="tab-shottino"],
#tab-resentin:checked ~ .tab-bar label[for="tab-resentin"],
#tab-cordiale:checked ~ .tab-bar label[for="tab-cordiale"]{color:var(--ink); border-color:var(--accent); box-shadow:0 0 20px var(--glow)}
#tab-cicchetto:checked ~ #panel-cicchetto,
#tab-shottino:checked ~ #panel-shottino,
#tab-resentin:checked ~ #panel-resentin,
#tab-cordiale:checked ~ #panel-cordiale{display:block}
#tab-cicchetto:focus-visible ~ .tab-bar label[for="tab-cicchetto"],
#tab-shottino:focus-visible ~ .tab-bar label[for="tab-shottino"],
#tab-resentin:focus-visible ~ .tab-bar label[for="tab-resentin"],
#tab-cordiale:focus-visible ~ .tab-bar label[for="tab-cordiale"]{outline:2px solid var(--accent); outline-offset:2px}
.panel-note{color:var(--muted); font-size:13px; margin:0 0 16px}

.lightbox{position:fixed; inset:0; z-index:100; display:none; align-items:center; justify-content:center;
          padding:16px; background:rgba(5,7,9,.93); cursor:zoom-out}
.lightbox:target{display:flex}
.lightbox img{max-width:96vw; max-height:94vh; width:auto; height:auto; border-radius:8px;
              border:1px solid var(--line); box-shadow:0 12px 60px rgba(0,0,0,.6)}
.lightbox .x{position:fixed; top:12px; right:18px; color:var(--ink); font-size:26px; line-height:1; opacity:.75}

.end{margin-top:var(--sec-gap); border-top:1px solid var(--line); padding-top:calc(var(--sec-pad) + 8px); text-align:center}
.end h2{font-size:clamp(22px,5vw,30px); color:var(--ink); font-weight:700; margin:0 0 8px; letter-spacing:-.01em}
.end p{color:var(--muted); font-size:14px; margin:0 0 22px}
.btn.big{padding:15px 30px; font-size:17px}

/* "What's shipping" board — populated client-side from /status.json (see
   status.js). The one section that needs JS: it ships hidden (the [hidden]
   attribute) and status.js reveals it once there's data, so no-JS / fetch-fail
   degrades to the page reading exactly as before. Columns reuse the .what card
   look; issue cards are compact links, chips echo the .stage pill. */
.board{margin-top:var(--sec-gap); border-top:1px solid var(--line); padding-top:var(--sec-pad)}
.board h2{font-size:13px; text-transform:uppercase; letter-spacing:.14em; color:var(--muted); font-weight:600; margin:0 0 6px}
.board .lead{color:var(--muted); font-size:14px; margin:0 0 20px}
.board .lead a{color:var(--accent-2)}
.cols{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:14px; align-items:start}
.b-col{background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:14px}
.b-col-h{display:flex; align-items:center; justify-content:space-between; margin:0 0 12px}
.b-col-name{font-size:11px; text-transform:uppercase; letter-spacing:.12em; color:var(--accent-2); font-weight:700}
.b-col-n{font-size:11px; color:var(--muted); background:var(--bg); border:1px solid var(--line); border-radius:999px; padding:1px 8px; min-width:22px; text-align:center}
.b-empty{color:var(--line); text-align:center; margin:8px 0 4px; font-size:18px}
.b-card{display:block; padding:9px 11px; margin:0 0 8px; border:1px solid var(--line); border-radius:9px; background:var(--bg)}
.b-card:last-child{margin-bottom:0}
.b-card:hover{text-decoration:none; border-color:var(--accent); box-shadow:0 0 16px var(--glow)}
.b-num{color:var(--muted); font-size:12px; font-weight:700; margin-right:6px}
.b-title{color:var(--ink); font-size:13.5px; line-height:1.45}
.b-chips{display:flex; flex-wrap:wrap; gap:5px; margin-top:7px}
.b-chip{font-size:10px; text-transform:uppercase; letter-spacing:.08em; color:var(--accent-2); border:1px solid rgba(95,175,215,.4); border-radius:999px; padding:1px 7px}
/* "Where we're heading" — the long-term roadmap epics, a flat card grid under
   the pipeline columns (they are epics, not pipeline items). Reuses .b-card. */
.roadmap{margin-top:34px}
.roadmap h3{font-size:11px; text-transform:uppercase; letter-spacing:.12em; color:var(--accent-2); font-weight:700; margin:0 0 6px}
.roadmap .lead{margin:0 0 16px}
.rm-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:10px; align-items:start}
.rm-grid .b-card{margin:0}
.whoami{text-align:center; margin:30px 0 0; font-size:14px}
.whoami a{color:var(--accent-2)}

/* "What people say" — testimonials, rendered client-side from /quotes.json by
   quotes.js (same progressive-enhancement pattern as the status board: ships
   hidden, revealed only when there's data). Quote panels reuse the .card look. */
.says{margin-top:var(--sec-gap); border-top:1px solid var(--line); padding-top:var(--sec-pad)}
.says h2{font-size:13px; text-transform:uppercase; letter-spacing:.14em; color:var(--muted); font-weight:600; margin:0 0 6px}
.says .lead{color:var(--muted); font-size:14px; margin:0 0 20px}
.quote-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:14px; align-items:stretch}
.quote{background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:18px; margin:0; display:flex; flex-direction:column}
.quote blockquote{margin:0 0 14px; color:var(--ink); font-size:14px; line-height:1.62}
.quote blockquote::before{content:"\201C"; color:var(--accent); font-size:24px; line-height:0; margin-right:2px; vertical-align:-5px; font-weight:700}
.quote figcaption{margin-top:auto; color:var(--muted); font-size:12.5px; line-height:1.45}
.quote figcaption b{color:var(--accent-2); font-weight:600}

/* "News" — milestones, rendered client-side from /news.json by news.js (same
   progressive-enhancement pattern as the testimonials/board: ships hidden,
   revealed only when there's data). A dated list: accent date on the left,
   the milestone on the right; collapses to stacked rows on narrow screens. */
.news{margin-top:var(--sec-gap); border-top:1px solid var(--line); padding-top:var(--sec-pad)}
.news h2{font-size:13px; text-transform:uppercase; letter-spacing:.14em; color:var(--muted); font-weight:600; margin:0 0 6px}
.news .lead{color:var(--muted); font-size:14px; margin:0 0 20px}
.news ul{list-style:none; margin:0; padding:0}
.news-item{display:flex; gap:16px; padding:0 0 16px; align-items:baseline}
.news-item:last-child{padding-bottom:0}
.news-when{flex:0 0 auto; min-width:88px; color:var(--accent-2); font-size:12.5px; font-weight:700; letter-spacing:.02em; font-variant-numeric:tabular-nums}
.news-body{color:var(--ink); font-size:14px; line-height:1.6}
.news-link{white-space:nowrap}
@media (max-width:440px){
  .news-item{flex-direction:column; gap:3px}
  .news-when{min-width:0}
}

@media (prefers-reduced-motion:reduce){
  .matrix,.matrix::before,.matrix::after{animation:none}
}

/* ---------------------------------------------------------------------------
   Multi-page additions (2026-09-13). Everything above this line came from the
   single-page landing; everything below exists because the site now has /news,
   /install, /self-host and /pipeline next to the home.
   --------------------------------------------------------------------------- */

/* Site nav — the row of pages under the brand. Plain links, the current one
   marked with aria-current and a pill. Wraps on narrow screens. */
.sitenav{display:flex; flex-wrap:wrap; gap:8px; margin:26px 0 0; font-size:13px}
.sitenav a,.sitenav span{display:inline-flex; align-items:center; padding:6px 12px;
  border-radius:999px; border:1px solid var(--line); background:var(--panel); color:var(--muted); line-height:1}
.sitenav a:hover{color:var(--ink); text-decoration:none; border-color:var(--accent); box-shadow:0 0 16px var(--glow)}
.sitenav [aria-current]{color:var(--ink); border-color:var(--accent)}

/* Subpage header — smaller than the home's giant wordmark: the brand stays a
   link back to /, the page title carries the weight. */
header .backmark{font-size:clamp(20px,5vw,26px); font-weight:700; letter-spacing:-.01em; margin:0;
  background:linear-gradient(180deg,var(--accent-2),var(--accent));
  -webkit-background-clip:text; background-clip:text; color:transparent}
header .backmark::before{content:"🍸 "; -webkit-text-fill-color:initial}
header .backmark a{color:transparent}
header .backmark a:hover{text-decoration:none}
.page-title{font-size:clamp(28px,7vw,44px); line-height:1.15; margin:20px 0 0; letter-spacing:-.02em; color:var(--ink)}

/* Sections on subpages: same rhythm as .what/.shots without repeating them. */
.block{margin-top:44px; border-top:1px solid var(--line); padding-top:30px}
/* The one paragraph that sits between a page title and its first section.
   `.lead` is deliberately scoped per-section, so a standalone opener needs its
   own class rather than borrowing one that would style nothing. */
.intro{color:var(--muted); font-size:14px; line-height:1.7; margin:20px 0 0; max-width:70ch}

.block:first-of-type{border-top:0; padding-top:0}
.block h2{font-size:13px; text-transform:uppercase; letter-spacing:.14em; color:var(--muted); font-weight:600; margin:0 0 6px}
.block h3{font-size:15px; color:var(--ink); font-weight:700; margin:26px 0 8px}
.block .lead{color:var(--muted); font-size:14px; margin:0 0 20px}
.block p{color:var(--muted); font-size:14px; line-height:1.7}
.block p strong{color:var(--ink)}
.block ul{color:var(--muted); font-size:14px; line-height:1.7; padding-left:20px}

/* Copy-paste blocks. Monospace everywhere already, so the job here is the box
   and the horizontal scroll: an apt sources line must never widen the page. */
pre.cmd{background:var(--panel); border:1px solid var(--line); border-radius:10px;
  padding:14px 16px; overflow-x:auto; margin:0 0 14px; color:var(--ink); font-size:13px; line-height:1.55}
pre.cmd code{white-space:pre}
.cmd-note{color:var(--muted); font-size:12.5px; margin:-6px 0 20px}
code.inline{background:var(--panel); border:1px solid var(--line); padding:1px 6px; border-radius:6px; color:var(--ink); font-size:13px}

/* "→ all the news" style link at the end of a truncated list. */
.more{margin:22px 0 0; font-size:13.5px}

/* Distro picker on /install — same radio+:checked trick as the client tabs on
   the home, different names so the two never collide if they ever share a page. */
.distro input{position:absolute; opacity:0; pointer-events:none}
#d-deb:checked ~ .tab-bar label[for="d-deb"],
#d-rpm:checked ~ .tab-bar label[for="d-rpm"],
#d-arch:checked ~ .tab-bar label[for="d-arch"],
#d-docker:checked ~ .tab-bar label[for="d-docker"]{color:var(--ink); border-color:var(--accent); box-shadow:0 0 20px var(--glow)}
#d-deb:checked ~ #p-deb,
#d-rpm:checked ~ #p-rpm,
#d-arch:checked ~ #p-arch,
#d-docker:checked ~ #p-docker{display:block}
#d-deb:focus-visible ~ .tab-bar label[for="d-deb"],
#d-rpm:focus-visible ~ .tab-bar label[for="d-rpm"],
#d-arch:focus-visible ~ .tab-bar label[for="d-arch"],
#d-docker:focus-visible ~ .tab-bar label[for="d-docker"]{outline:2px solid var(--accent); outline-offset:2px}

/* The pipeline diagram: a belt of stations the packages travel along, drawn in
   SVG and animated in CSS. Two clankers walk the belt carrying a crate each,
   and drop it off at the signing station. It is decorative — aria-hidden,
   and prefers-reduced-motion stops every loop (the belt still reads as a
   diagram when frozen, which is the point of animating positions and not
   opacity). */
.belt{width:100%; height:auto; display:block; margin:0 0 8px; border:1px solid var(--line);
  border-radius:12px; background:var(--panel)}
.belt .station{fill:var(--bg); stroke:var(--line)}
.belt .station-lit{stroke:var(--accent)}
.belt .label{fill:var(--muted); font:600 9px ui-monospace,Menlo,Consolas,monospace; letter-spacing:.06em}
.belt .rail{stroke:var(--line); stroke-width:2}
.belt .bot{fill:var(--accent); opacity:.9}
.belt .bot-dark{fill:var(--bg)}
.belt .eye{fill:var(--accent-2)}
.belt .crate{fill:var(--accent-2); opacity:.85}
.belt .spark{fill:var(--accent-2)}
.belt .walk-a{animation:belt-walk 11s linear infinite}
.belt .walk-b{animation:belt-walk 11s linear infinite; animation-delay:-5.5s}
.belt .crate-carried{animation:belt-lift 11s linear infinite}
.belt .walk-b .crate-carried{animation-delay:-5.5s}
.belt .bob{animation:belt-bob .5s ease-in-out infinite alternate}
.belt .blink{animation:belt-blink 2.4s steps(1,end) infinite}
.belt .sign{animation:belt-sign 11s linear infinite}
@keyframes belt-walk{
  0%{transform:translateX(0)}
  92%{transform:translateX(520px)}
  92.01%{transform:translateX(520px); opacity:0}
  100%{transform:translateX(520px); opacity:0}
}
/* The crate rides inside the walking group, so it only needs the last beat:
   at the signing station it lifts off the clanker's hands and is gone. */
@keyframes belt-lift{
  0%,86%{transform:translateY(0); opacity:.85}
  93%{transform:translateY(-16px); opacity:0}
  100%{transform:translateY(-16px); opacity:0}
}
@keyframes belt-bob{from{transform:translateY(0)}to{transform:translateY(-1.5px)}}
@keyframes belt-blink{0%,88%{opacity:1}90%,96%{opacity:.15}98%{opacity:1}}
@keyframes belt-sign{0%,58%{opacity:0}64%,88%{opacity:1}94%,100%{opacity:0}}
@media (prefers-reduced-motion:reduce){
  .belt .walk-a,.belt .walk-b,.belt .crate-carried,
  .belt .bob,.belt .blink,.belt .sign{animation:none}
  .belt .sign{opacity:1}
}

/* Numbered steps under the belt — the same cards as .what, with a step chip. */
.steps{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:14px; align-items:start}
.step{background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:16px}
.step .n{display:flex; align-items:center; gap:9px; color:var(--accent-2); font-weight:700; margin:0 0 6px; font-size:14px}
.step .num{font-size:10px; letter-spacing:.1em; font-weight:600; padding:2px 8px; border-radius:999px;
  border:1px solid rgba(95,175,215,.4); color:var(--accent-2)}
.step p{margin:0; color:var(--muted); font-size:13.5px; line-height:1.6}
