/* =====================================================================
   THE STAGE — terminaldeck.dev hero.
   Rebuilt 2026-08-29 as ONE full-viewport scene driven by ONE clock.

   Two rules held the whole way through:

   1. This file describes SHAPE and REST. It contains no @keyframes and
      no transitions on anything the story touches. Every moving value
      arrives from hero.js as a transform, an opacity, or a custom
      property, so a frame at t = 9.4s is the same frame every time and
      the loop can be scrubbed, paused and seeked.
   2. The composition is the frame. No card, no border, no rounded box
      around the scene — the machines stand at real distances from each
      other across the whole page, which is what makes a packet crossing
      the field read as travel rather than decoration.

   Positions are --x / --y / --w percentages of .h-fld, so the same objects
   re-form into a tall narrow constellation at 860px and below without a
   second set of components.
   ===================================================================== */

.h-stage {
  position: relative;
  min-height: calc(100dvh - var(--topbar-h));
  padding: var(--s-8) var(--s-8) var(--s-10);
  overflow: hidden;              /* things enter and leave the frame */
  display: flex;
  isolation: isolate;
}
@media (max-width: 900px) { .h-stage { padding: var(--s-6) var(--s-4) var(--s-8); } }

.h-fld {
  position: relative;
  width: 100%;
  max-width: 1400px;
  margin-inline: auto;
  min-height: 620px;
}

/* every placed object reads its own slot ----------------------------- */
.h-obj, .h-say, .h-beat {
  position: absolute;
  left: var(--x, 0); top: var(--y, 0); width: var(--w, 22%);
}
.h-obj, .h-beat { will-change: transform, opacity; }
.h-say { z-index: 3; }
.h-scene { position: absolute; inset: 0; pointer-events: none; }
.h-wires { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.h-packets { position: absolute; inset: 0; pointer-events: none; z-index: 3; }

.h-obj   { z-index: 2; }
.h-say   { z-index: 2; }
.h-commons { z-index: 4; }
.h-cursor  { z-index: 6; }
.h-beat    { z-index: 5; }

/* ---------------------------------------------------------------------
   THE PAGE'S OWN VOICE — quiet type standing in the field
   --------------------------------------------------------------------- */
.h-say { --x: 0; --y: 17%; --w: 42%; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-5); }
.h-say-chips { display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* The four facts above the headline. The site's own .chip is the store's
   filter control — it has a pointer cursor and a hover state, and these are
   not pressable — so they carry the shape without the affordance. Values are
   the approved design's chip, verbatim. */
.h-badge {
  display: inline-flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 var(--s-2);
  border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--surface-2);
  font-size: var(--t-2xs); font-weight: 500; color: var(--ink-2);
  letter-spacing: 0.01em; white-space: nowrap;
}
.h-badge-mono { font-family: var(--font-mono); }
.h-say h1 {
  font-size: clamp(2rem, 1rem + 2.4vw, 3rem);
  line-height: 1.06; letter-spacing: -0.036em; font-weight: 580;
  margin: 0;
}
.h-say-lede { font-size: var(--t-lg); line-height: 1.45; color: var(--ink-3); max-width: 32ch; margin: 0; }
.h-say-cta { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.h-say-note { font-size: var(--t-sm); color: var(--ink-4); margin: 0; }
.h-say-cta .btn svg { width: 18px; height: 18px; }

/* ---------------------------------------------------------------------
   WIRES — no line exists unless something is travelling on it. The faint
   resting set is there only to hold the constellation together.
   --------------------------------------------------------------------- */
.h-w-rest { fill: none; stroke: var(--ink); stroke-width: 1; opacity: 0.07; stroke-dasharray: 2 6; stroke-linecap: round; }
.h-w-live { fill: none; stroke: var(--accent); stroke-width: 1.25; stroke-linecap: round; opacity: 0; }

/* travelling work ----------------------------------------------------- */
.h-pk { position: absolute; left: 0; top: 0; display: grid; place-items: center; }
.h-pk-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 5px var(--accent-soft); }
.h-pk-chip {
  white-space: nowrap;
  font: 500 var(--t-2xs)/1 var(--font-mono);
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  padding: 5px var(--s-2) 5px 6px;
  display: inline-flex; align-items: center; gap: 6px;
  box-shadow: var(--shadow-2);
}
.h-pk-chip::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); flex: none; }

/* ---------------------------------------------------------------------
   THE DECK — where the person types
   --------------------------------------------------------------------- */
.h-deck { --x: 0; --y: 75%; --w: 41%; display: grid; gap: var(--s-3); }

.h-deck-accounts { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.h-acct {
  display: inline-flex; align-items: center; gap: 6px;
  font: 400 var(--t-2xs)/1 var(--font-mono); color: var(--ink-4);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 5px var(--s-2);
  background: var(--surface);
}
.h-acct i { position: relative; width: 5px; height: 5px; border-radius: 50%; flex: none; }
.h-acct i::before { content: ''; position: absolute; inset: 0; border-radius: 50%; background: var(--ink-4); opacity: calc(0.45 + 0.25 * var(--live, 0)); }
.h-acct i::after  { content: ''; position: absolute; inset: 0; border-radius: 50%; background: var(--accent); opacity: var(--live, 0); }
.h-acct-note { font-size: var(--t-2xs); color: var(--ink-4); margin-left: var(--s-1); }

.h-deck-bar {
  position: relative;
  display: flex; align-items: center; gap: var(--s-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-4) var(--s-4) var(--s-4) var(--s-5);
  box-shadow: var(--shadow-2);
  border-top: 1px solid var(--card-top, var(--line));
}
.h-deck-bar::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: var(--shadow-3); opacity: calc(var(--focus, 0) * 0.5); pointer-events: none;
}
.h-deck-bar::after {
  content: ''; position: absolute; inset: -4px; border-radius: calc(var(--r-lg) + 4px);
  border: 1px solid var(--accent-line); box-shadow: 0 0 0 3px var(--accent-soft);
  opacity: var(--focus, 0); pointer-events: none;
}
.h-deck-prompt { font: 400 var(--t-base)/1 var(--font-mono); color: var(--accent); opacity: .8; flex: none; }
.h-deck-type { flex: 1 1 auto; display: flex; align-items: center; min-width: 0; min-height: 1.25em; }
.h-deck-text { font: 400 var(--t-base)/1.25 var(--font-mono); color: var(--ink); white-space: pre; letter-spacing: -0.01em; }
.h-deck-caret { width: 1.5px; height: 1.15em; background: var(--accent); flex: none; margin-left: 1px; opacity: 0; }
.h-deck-send {
  flex: none; position: relative; width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center; border: 1px solid var(--line); background: var(--surface-2);
}
.h-deck-send::before {
  content: ''; position: absolute; inset: -1px; border-radius: 50%;
  background: var(--accent); opacity: var(--on, 0);
}
.h-deck-send svg { position: relative; width: 16px; height: 16px; stroke-width: 2; }

/* ---------------------------------------------------------------------
   A MACHINE
   --------------------------------------------------------------------- */
.h-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 1px solid var(--card-top, var(--line));
  border-radius: var(--r-lg);
  padding: var(--s-3) var(--s-4) var(--s-4);
  display: grid; gap: 10px;
  box-shadow: var(--shadow-1);
}
.h-mac    { --x: 50%;   --y: 9%;  --w: 18.5%; }
.h-pc     { --x: 80.5%; --y: 25%; --w: 19.5%; }
.h-srv    { --x: 59%;   --y: 47%; --w: 18.5%; }

.h-card-head { display: flex; align-items: center; gap: var(--s-2); }
.h-card-dev { width: 15px; height: 15px; flex: none; stroke: var(--ink-4); fill: none; }
.h-card-machine { font: 500 var(--t-xs)/1 var(--font-ui); color: var(--ink-2); letter-spacing: -0.005em; flex: 1 1 auto; white-space: nowrap; }
.h-card-state { position: relative; width: 16px; height: 16px; flex: none; display: grid; place-items: center; }
.h-card-state::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  border: 1.5px solid var(--accent); opacity: var(--ask, 0);
  transform: scale(var(--askS, 1));
}
.h-pip { width: 7px; height: 7px; border-radius: 50%; position: relative; }
.h-pip::before { content: ''; position: absolute; inset: 0; border-radius: 50%; background: var(--ink-4); opacity: calc(0.42 + 0.28 * var(--live, 0)); }
.h-pip::after  { content: ''; position: absolute; inset: -0.5px; border-radius: 50%; background: var(--accent); opacity: var(--live, 0); }

.h-card-body { display: grid; gap: var(--s-2); }
.h-card-who { display: flex; align-items: baseline; gap: var(--s-2); }
.h-card-who b { font: 500 var(--t-sm)/1.2 var(--font-mono); color: var(--ink); letter-spacing: -0.015em; }
.h-card-acct {
  font: 400 var(--t-2xs)/1 var(--font-mono); color: var(--ink-4);
  border: 1px solid var(--line); border-radius: var(--r-pill); padding: 3px 6px;
}
.h-card-work {
  display: flex; align-items: center; gap: 6px; min-height: 1.35em;
  font: 400 var(--t-2xs)/1.35 var(--font-mono); color: var(--ink-3);
  white-space: nowrap; overflow: hidden;
}
.h-card-tick { width: 11px; height: 11px; flex: none; stroke: var(--ink-4); fill: none; opacity: 0; }

.h-rail { height: 2px; border-radius: 2px; background: var(--line-soft); overflow: hidden; }
.h-rail-fill { display: block; height: 100%; background: var(--accent); transform: scaleX(0); transform-origin: left center; }

.h-tags { display: flex; gap: 5px; flex-wrap: nowrap; margin-top: 2px; }
.h-tag {
  font: 400 var(--t-2xs)/1 var(--font-mono); color: var(--ink-4);
  border: 1px solid var(--line); border-radius: var(--r-sm); padding: 3px 5px;
  background: var(--surface-2); white-space: nowrap;
}
.h-tag-new { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }

.h-ask {
  justify-self: start;
  font: 500 var(--t-2xs)/1 var(--font-mono); color: var(--accent);
  border: 1px solid var(--accent-line); border-radius: var(--r-pill);
  padding: 4px var(--s-2); background: var(--accent-soft);
}

/* ---------------------------------------------------------------------
   THE SHARED LEDGER
   --------------------------------------------------------------------- */
.h-ledger {
  --x: 79%; --y: 68%; --w: 21%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 1px solid var(--card-top, var(--line));
  border-radius: var(--r-lg);
  padding: var(--s-3) var(--s-4) var(--s-4);
  display: grid; gap: var(--s-3);
  box-shadow: var(--shadow-1);
}
.h-ledger-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }
.h-ledger-name { font: 500 var(--t-xs)/1 var(--font-ui); color: var(--ink-2); }
.h-ledger-count { font: 400 var(--t-2xs)/1 var(--font-mono); color: var(--ink-4); font-variant-numeric: tabular-nums; }
/* the list and its empty slots occupy the SAME grid cell, so a waiting
   line and a landed one sit on exactly the same baseline */
/* `padding: 0; list-style: none` is not decoration. The concept this came
   from carried a global `ul, ol { list-style: none; padding: 0 }` reset;
   terminaldeck.dev's stylesheet resets list MARGINS only, on purpose, because
   its prose pages want real bullets. Without these two the UA's 40px
   padding-inline-start pushed this list out of the slot column it is stacked
   on, and the ledger drew a grey placeholder dot beside every filled line. */
.h-ledger-list  { grid-area: 2 / 1; display: grid; gap: 7px; margin: 0; padding: 0; list-style: none; }
.h-ledger-slots { grid-area: 2 / 1; display: grid; gap: 7px; pointer-events: none; }
.h-ledger-slots i { display: block; height: 14px; position: relative; }
.h-ledger-slots i::before {
  content: ''; position: absolute; left: 0; top: 5px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--ink-4); opacity: 0.3;
}
.h-ledger-line {
  display: flex; align-items: center; gap: var(--s-2);
  font: 400 var(--t-2xs)/1.3 var(--font-mono); color: var(--ink-3);
  white-space: nowrap; overflow: hidden;
}
.h-ledger-line i { width: 4px; height: 4px; border-radius: 50%; background: var(--accent); flex: none; }
.h-ledger-done {
  font: 500 var(--t-2xs)/1 var(--font-mono); color: var(--accent);
  border-top: 1px solid var(--line-soft); padding-top: var(--s-3); margin-top: 1px;
}

/* ---------------------------------------------------------------------
   THE PHONE — the same sessions, in your hand
   --------------------------------------------------------------------- */
.h-phone { --x: 45%; --y: 60%; --w: 10.5%; min-width: 128px; }
.h-phone-body {
  position: relative; aspect-ratio: 100 / 168;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: 18px; padding: 5px;
  box-shadow: var(--shadow-1);
}
.h-phone-notch { position: absolute; left: 50%; top: 8px; width: 26%; height: 4px; border-radius: 3px; background: var(--line-strong); transform: translateX(-50%); opacity: .6; }
.h-phone-screen {
  position: relative; height: 100%; border-radius: 14px; overflow: hidden;
  background: var(--surface-3); padding: 20px 8px 8px;
}
.h-ph-live, .h-ph-ask { position: absolute; left: 8px; right: 8px; top: 20px; display: grid; gap: 6px; }
.h-ph-title { font: 400 9px/1 var(--font-ui); color: var(--ink-4); margin-bottom: 2px; }
.h-ph-row {
  display: flex; align-items: center; gap: 5px;
  font: 400 9px/1.25 var(--font-mono); color: var(--ink-3);
  background: var(--surface); border: 1px solid var(--line-soft); border-radius: 5px;
  padding: 7px 6px; white-space: nowrap; overflow: hidden;
}
.h-ph-row b { font-weight: 400; }
.h-ph-row span { margin-left: auto; color: var(--ink-4); font-size: 8px; }
.h-ph-row .h-pip { width: 5px; height: 5px; flex: none; }
.h-ph-foot {
  position: absolute; left: 8px; right: 8px; bottom: 8px;
  font: 400 8px/1 var(--font-mono); color: var(--ink-4);
  border-top: 1px solid var(--line-soft); padding-top: 7px;
}
.h-ph-ask { gap: 6px; }
.h-ph-from { font: 400 9px/1 var(--font-mono); color: var(--ink-4); }
.h-ph-q { font: 500 10px/1.3 var(--font-ui); color: var(--ink); letter-spacing: -0.01em; }
.h-ph-btns { display: grid; gap: 4px; margin-top: 2px; }
.h-ph-btn {
  position: relative; overflow: hidden;
  font: 500 9px/1 var(--font-ui); text-align: center;
  border: 1px solid var(--line); border-radius: 5px; padding: 6px 4px; color: var(--ink-3);
  background: var(--surface);
}
.h-ph-yes { color: var(--accent-fg); background: var(--accent); border-color: transparent; }
.h-ripple { position: absolute; left: 50%; top: 50%; width: 60px; height: 60px; margin: -30px 0 0 -30px; border-radius: 50%; background: var(--accent-fg); opacity: 0; }

/* ---------------------------------------------------------------------
   COMMONS — arrives mid-flight
   --------------------------------------------------------------------- */
.h-commons {
  --x: 63%; --y: -13%; --w: 20%; min-width: 208px;
  display: flex; align-items: center; gap: var(--s-3);
  background: var(--surface); border: 1px solid var(--accent-line);
  border-radius: var(--r-lg); padding: var(--s-3);
  box-shadow: var(--shadow-3);
}
.h-commons-ic { width: 18px; height: 18px; flex: none; stroke: var(--accent); fill: none; }
.h-commons-txt { display: grid; gap: 2px; min-width: 0; }
.h-commons-txt b { font: 500 var(--t-xs)/1.2 var(--font-ui); color: var(--ink); letter-spacing: -0.01em; }
.h-commons-txt span { font: 400 var(--t-2xs)/1 var(--font-mono); color: var(--ink-4); }

/* ---------------------------------------------------------------------
   THE CURSOR — a real pointer, and it really clicks
   --------------------------------------------------------------------- */
.h-cursor { position: absolute; left: 0; top: 0; width: 25px; height: 27px; }
.h-cursor svg { width: 100%; height: 100%; overflow: visible; }
.h-cursor path {
  fill: var(--ink);
  stroke: var(--surface); stroke-width: 2.4; stroke-linejoin: round;
  paint-order: stroke fill;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .22));
}

/* ---------------------------------------------------------------------
   THE CLOSING LINE
   --------------------------------------------------------------------- */
.h-beat {
  --x: 44%; --y: 40%; --w: 54%;
  margin: 0; text-align: center;
  font-size: clamp(1.25rem, 0.7rem + 1.1vw, 1.75rem);
  line-height: 1.25; letter-spacing: -0.028em; font-weight: 500;
  color: var(--ink); opacity: 0;
}
.h-beat span { display: inline-block; will-change: transform, opacity; }

/* =====================================================================
   NARROW — the same story re-formed as a tall column. Work moves down
   the machines and comes back up; the phone stands beside the ledger so
   the hand-off and the answer are both on screen at once.
   ===================================================================== */
/* =====================================================================
   NARROW — the same story, re-formed. Not the wide layout shrunk: the
   machines become a column the work runs DOWN, the phone stands to the
   left of the last machine so the hand-off and the answer are both on
   screen at once, and every card collapses to one identity row so all
   seven objects fit a phone without the story falling below the fold.
   Measured at 390x844: field 358 x 830, nothing overlapping.
   ===================================================================== */
@media (max-width: 860px) {
  .h-fld { min-height: 890px; }

  .h-say  { --x: 0; --y: 0; --w: 100%; gap: var(--s-3); }
  .h-say h1 { font-size: clamp(1.6rem, 1rem + 3vw, 2.15rem); }
  .h-say-lede { font-size: 0.9375rem; max-width: none; }
  .h-say-cta { gap: var(--s-2); width: 100%; }
  .h-say-cta .btn-lg { flex: 1 1 auto; justify-content: center; }

  .h-deck { --x: 0; --y: 33.7%; --w: 100%; gap: var(--s-2); }
  .h-deck-bar { padding: var(--s-3) var(--s-3) var(--s-3) var(--s-4); }
  .h-deck-text, .h-deck-prompt { font-size: var(--t-md); }

  .h-mac    { --x: 0;   --y: 46.0%; --w: 76%; }
  .h-pc     { --x: 24%; --y: 59.0%; --w: 76%; }
  .h-phone  { --x: 0;   --y: 71.5%; --w: 32%; min-width: 0; }
  .h-srv    { --x: 32%; --y: 72.0%; --w: 68%; }
  .h-ledger { --x: 32%; --y: 83.0%; --w: 68%; }
  .h-commons { --x: 18%; --y: -9%; --w: 68%; min-width: 0; }
  .h-beat   { --x: 0; --y: 37%; --w: 100%; }

  /* one identity row: device, agent, account, state */
  .h-card { grid-template-columns: auto auto 1fr auto; align-items: center; gap: 7px 7px; padding: 10px 11px 12px; }
  .h-card-head, .h-card-body { display: contents; }
  .h-card-dev     { grid-row: 1; grid-column: 1; }
  .h-card-machine { grid-row: 1; grid-column: 2; }
  .h-card-who     { grid-row: 1; grid-column: 3; }
  .h-card-state   { grid-row: 1; grid-column: 4; }
  .h-card-work    { grid-row: 2; grid-column: 1 / -1; }
  .h-rail         { grid-row: 3; grid-column: 1 / -1; }
  .h-tags, .h-ask { grid-row: 4; grid-column: 1 / -1; }
  .h-tags .h-tag:not(.h-tag-new) { display: none; }

  .h-ledger { padding: 10px 12px 12px; gap: var(--s-2); }
  .h-ph-row span { display: none; }
  .h-commons { padding: var(--s-2) var(--s-3); }
}

@media (max-width: 460px) {
  .h-say-cta { flex-direction: column; align-items: stretch; }
}

/* The approved hero does not draw this line at any width — the three account
   chips beside it already say it, and a sentence counting them is the page
   explaining its own picture. It arrived here as a rule that had escaped its
   media query, plus a stray brace the parser threw away; kept as written,
   because what it renders is what was signed off, and made a deliberate rule
   rather than an accident. */
.h-acct-note { display: none; }


/* ---------------------------------------------------------------------
   DEPTH — one rule for every raised thing. --lift comes from the
   timeline: 0 at rest, 1 when the object has just been given work. In
   light that is a shadow lifting off the page, in dark (where the
   palette carries no drop shadows) it is the edge firming up, so an
   arrival reads as physical in both.
   --------------------------------------------------------------------- */
.h-card::before, .h-ledger::before, .h-phone-body::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: var(--shadow-2); opacity: var(--lift, 0); pointer-events: none;
}
.h-card::after, .h-ledger::after, .h-phone-body::after {
  content: ''; position: absolute; inset: -1px; border-radius: calc(var(--r-lg) + 1px);
  border: 1px solid var(--line-strong); opacity: calc(var(--lift, 0) * 0.42); pointer-events: none;
}
.h-phone-body::before, .h-phone-body::after { border-radius: 19px; }

/* the work line can never push the tick out of the card */
.h-card-work > span { min-width: 0; overflow: hidden; text-overflow: clip; }
