/* The homepage scene. Tokens, nav, type, buttons, the wall and the footer come from css/site.css.
   One meaning per material:
   maple  = what was stacked (the tower, the "fixes" buttons)
   purple = what was built (the bricks, the word "builder", the buttons that build) */
:root {
  --maple: #cfa774;
  --frame-left: calc(max(0px, (100vw - 2000px) / 2) + clamp(16px, 5vw, 80px)); /* wider than the site frame: big monitors pull the copy left */
  --t-swap: 420ms;
}
body { line-height: 1.5; }


/* Stage */
/* The canvas is transparent, so the floor's light pool is painted here, under wherever the
   tower stands (stack.js sets --pool-x and --pool-y) */
.stage {
  position: relative; height: 100svh; min-height: 640px; overflow: hidden;
  /* Drags on the scene must never select the headline sitting under the canvas */
  -webkit-user-select: none; user-select: none;
  background:
    radial-gradient(ellipse min(46vw, 820px) min(20vw, 360px) at var(--pool-x, 72%) var(--pool-y, 86%), rgba(64, 56, 76, .5), rgba(10, 10, 10, 0) 72%),
    var(--bg);
}
#scene {
  position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1;
  display: block;
  /* Vertical swipes scroll the page. stack.js claims a touch only when it lands on a block. */
  touch-action: pan-y;
  transition: opacity 600ms var(--ease-out);
}
body[data-state="loading"] #scene { opacity: 0; }

/* Two sizes only: the statement, and small text in the corner. Nothing in between. */
.copy {
  /* z-index matters: the transform makes this its own layer, and it must sit above the canvas */
  position: absolute; z-index: 3; left: var(--frame-left); top: 50%; transform: translateY(-46%);
  display: flex; flex-direction: column; gap: clamp(40px, 9vh, 120px);
  pointer-events: none;
}

/* --hw is the width of the headline block. Every line is sized from it, so the whole thing fits
   left of the tower and never slides behind it. */
.statement {
  --hw: min(46vw, 92vh, 880px);
  position: relative; z-index: 2;
  /* A dark halo so tumbling blocks behind the words never make them hard to read */
  text-shadow: 0 2px 2px rgba(0, 0, 0, .55), 0 6px 24px rgba(0, 0, 0, .75), 0 0 60px rgba(10, 10, 10, .9);
  margin: 0;
  font-family: "Big Shoulders", sans-serif;
  font-variation-settings: "opsz" 72;
  font-weight: 900;
  line-height: .8;
  letter-spacing: -0.012em;
  text-transform: uppercase;
  white-space: nowrap;
}
.statement span { display: block; }
.statement .l1, .statement .l2 { font-size: calc(var(--hw) / 6.45); line-height: .86; }
.statement .l3 { font-size: calc(var(--hw) / 3.12); line-height: .8; margin-top: .03em; }

.intro {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 16px;
  max-width: 460px;
  pointer-events: auto;
}
.intro-photo { width: 64px; height: 64px; border-radius: 50%; flex: none; object-fit: cover; box-shadow: 0 0 0 2px var(--purple-core); }
.intro p { margin: 0; }
.intro-name { font: 600 1.05rem/1.4 "Instrument Sans", sans-serif; color: var(--text-primary); }
.intro-name span { color: var(--text-muted); font-weight: 500; }
.intro-name span::before { content: "\00B7"; margin: 0 8px; color: var(--purple-soft); }
.intro-line { margin-top: 6px !important; font: 400 .98rem/1.5 "Instrument Sans", sans-serif; color: var(--text-secondary); text-wrap: pretty; }
.intro-more { color: var(--text-primary); text-decoration: underline; text-underline-offset: 4px; white-space: nowrap; }
.intro-more:hover { color: var(--white); }

/* The game note */
.note {
  position: absolute; z-index: 3; left: 0; top: 0;
  width: 320px; max-width: calc(100vw - 32px);
  will-change: transform;
}
.note-title {
  margin: 0 0 6px;
  font: 700 1.15rem/1.25 "Bricolage Grotesque", sans-serif;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
.note-body { margin: 0 0 14px; font-size: .95rem; line-height: 1.45; color: var(--text-secondary); text-wrap: pretty; }
.note-title:empty, .note-body:empty { display: none; }
body[data-state="fallen"] .note, body[data-state="built"] .note {
  background: rgba(10, 10, 10, .82);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 16px 18px;
}
/* The rebuilt stack carries no note: the layer titles say it (cut 2026-10-20) */
body[data-state="built"] .note { display: none; }
body[data-state="intact"] .note { width: 200px; }
body[data-state="intact"] .note .actions { flex-direction: column; align-items: flex-start; }
body[data-state="built"] .note, body[data-state="building"] .note { width: 250px; }

.note-title, .note-body { transition: opacity var(--t-swap) var(--ease-out), transform var(--t-swap) var(--ease-out); }
.swap-out { opacity: 0; transform: translateY(6px); }

.actions { display: none; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
body[data-state="intact"] .actions[data-for="intact"],
body[data-state="fallen"] .actions[data-for="fallen"],
body[data-state="built"]  .actions[data-for="built"] { display: flex; }
.actions-label { width: 100%; font: 500 .78rem/1 "JetBrains Mono", monospace; color: var(--text-muted); }

/* The "usual fixes" are maple, because they are more of the stack */
.chip {
  border: 0; border-radius: 3px;
  padding: 11px 16px;
  background: var(--maple); color: #1c1915;
  font-weight: 600; font-size: .95rem;
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.22);
  transition: transform var(--t-snap) var(--ease-out), box-shadow var(--t-snap) var(--ease-out);
}
.chip:active { transform: translateY(2px); box-shadow: inset 0 -1px 0 rgba(0,0,0,.22); }
.chip[disabled] { opacity: .4; cursor: default; }

.btn-plain { color: var(--text-primary); text-decoration: underline; text-underline-offset: 5px; text-decoration-color: var(--text-muted); padding-inline: 6px; }

/* The rebuilt layers. On desktop stack.js pins each one in a column beside the pier with a
   leader line to its layer; on phones they are a plain list under it. */
.tenets {
  position: absolute; z-index: 2;
  left: 16px; right: 16px; bottom: 56px;
  margin: 0; padding: 0; list-style: none;
  display: none;
}
body[data-state="built"] .tenets { display: block; }
.tenets li { opacity: 0; transition: opacity 500ms var(--ease-out); }
.tenets.in li { opacity: 1; }
.tenets a { display: block; text-decoration: none; padding: 7px 0; border-top: 1px solid var(--line); }
.tenets strong { display: block; font: 700 .95rem/1.25 "Bricolage Grotesque", sans-serif; }
.tenets span { display: block; font-size: .84rem; line-height: 1.35; color: var(--text-secondary); }
.tenets a:hover strong { color: var(--purple-soft); }
.tenets li:last-child strong { color: var(--purple-soft); }

.tenets.pinned { inset: 0; pointer-events: none; }
.tenets.pinned li { position: absolute; left: 0; top: 0; width: 340px; pointer-events: auto; will-change: transform; }
.tenets.pinned a { border: 0; padding: 0; }
/* Rebuilt: each layer's callout reads at a glance, a title and one line of what it gets you */
.tenets.pinned strong { font: 800 1.32rem/1.2 "Bricolage Grotesque", sans-serif; letter-spacing: -0.01em; color: var(--text-primary); }
.tenets.pinned li:last-child strong { color: var(--purple-soft); }
.tenets.pinned span { display: block; margin-top: 4px; max-width: 34ch; font-size: .9rem; line-height: 1.4; color: var(--text-secondary); }
@media (max-width: 1699px) {
  .tenets.pinned li { width: 280px; }
  .tenets.pinned strong { font-size: 1.14rem; }
  .tenets.pinned span { font-size: .82rem; }
}

.leaders { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; display: none; }
.leaders path { fill: none; stroke: rgba(240, 237, 244, .32); stroke-width: 1; }
.leaders circle { fill: var(--purple-soft); }

/* Handwriting belongs to the blocks only */
.hint {
  position: absolute; z-index: 2; margin: 0;
  font: 1.15rem/1 "Permanent Marker", cursive;
  color: var(--maple);
  pointer-events: none;
  opacity: 0; transition: opacity 400ms var(--ease-out);
}
.hint.on { opacity: 1; }

.toast {
  position: absolute; z-index: 3; left: 50%; top: 84px;
  transform: translate(-50%, 8px);
  margin: 0; padding: 10px 16px;
  background: var(--bg-elevated); color: var(--text-primary);
  border: 1px solid var(--line); border-radius: 3px;
  font: 500 .85rem/1.3 "JetBrains Mono", monospace;
  opacity: 0; pointer-events: none;
  transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out);
  max-width: calc(100vw - 32px); text-align: center;
}
.toast.on { opacity: 1; transform: translate(-50%, 0); }

.hud {
  position: absolute; z-index: 2;
  left: var(--frame-left); right: var(--frame-left); bottom: 22px;
  display: flex; justify-content: space-between; align-items: center;
  font: 500 .8rem/1 "JetBrains Mono", monospace; color: var(--text-muted);
}
.hud .link { font: inherit; color: var(--text-muted); }
.hud .link:hover { color: var(--text-primary); }
.hud-right { display: flex; gap: 22px; }
body[data-state="built"] #tally { visibility: hidden; }

.still { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* Below the stage: quiet on purpose */
/* The wall (css/site.css, js/wall.js): purple = built */
.after { background: var(--bg); padding: clamp(96px, 14vh, 160px) 0 0; overflow: hidden; }
@media (max-width: 760px) { .after .wall { --wall-h: 720px; } }
.after .foot { padding-top: clamp(80px, 12vh, 140px); }




/* Phone: copy on top, tower below it, layers listed under the pier */
@media (max-width: 760px) {
  .stage { min-height: 700px; }
  .copy { left: 16px; right: 16px; top: 78px; transform: none; gap: 14px; }
  .statement { position: static; --hw: calc(100vw - 52px); }
  .intro-name { font-size: .95rem; }
  .intro { position: static; max-width: none; gap: 12px; }
  .intro-photo { width: 48px; height: 48px; }
  .intro-line { font-size: .92rem; }
  .note { width: auto; right: 16px; }
  .note-title { font-size: 1rem; }
  .note-body { font-size: .9rem; margin-bottom: 10px; }
  .actions-label { display: none; }
  .chip { padding: 9px 12px; font-size: .88rem; }
  .tenets span { display: none; }
  .hud { bottom: 16px; }
  .toast { bottom: auto; top: 74px; }
}

/* Still frames: no WebGL, or reduced motion. The story is told in words instead. */
body.reduced .still,
body[data-state="still"] .still {
  position: absolute; z-index: 2; width: auto; height: auto; clip: auto; overflow: visible;
  left: clamp(16px, 5vw, 80px); bottom: 64px; max-width: 46ch; margin: 0;
  font-size: .9rem; color: var(--text-secondary);
}
body[data-state="still"] .actions[data-for="built"] { display: flex; }
body[data-state="still"] .tenets { display: block; }
body[data-state="still"] .tenets li { opacity: 1; }
body[data-state="still"] .hud { display: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0s !important; }
}

@media (max-width: 760px) { .hint { display: none; } }

/* The ghost finger that shows the pull once */
.ghost {
  position: absolute; z-index: 3; left: 0; top: 0;
  width: 30px; height: 30px; margin: -15px 0 0 -15px;
  pointer-events: none; opacity: 0;
  transition: opacity 220ms var(--ease-out);
}
.ghost.on { opacity: 1; }
.ghost span {
  display: block; width: 100%; height: 100%; border-radius: 50%;
  background: rgba(240, 237, 244, .92);
  box-shadow: 0 0 0 7px rgba(240, 237, 244, .16), 0 6px 18px rgba(0, 0, 0, .5);
  transition: transform 160ms var(--ease-out), box-shadow 160ms var(--ease-out);
}
.ghost.press span { transform: scale(.78); box-shadow: 0 0 0 12px rgba(240, 237, 244, .12), 0 3px 10px rgba(0, 0, 0, .5); }
@media (max-width: 760px) {
  body[data-state] .note { width: auto; }
  body[data-state="intact"] .note .actions { flex-direction: row; }
}

/* Phones get less text (2026-10-20): the name line, the statement, the game's one line and its
   button. The sentence under the name, the explanation under the game line, the second restart
   link (Start over does it), the pull count and the transition note all stay on desktop only. */
@media (max-width: 760px) {
  .intro-line { display: none; }
  .note-body, #restack, #tally { display: none; }
  body[data-state="building"] .note { display: none; }
  body[data-state="fallen"] .note {
    background: none; border: 0; padding: 0;
    text-shadow: 0 2px 2px rgba(0, 0, 0, .55), 0 6px 24px rgba(0, 0, 0, .75);
  }
  .note-title { margin-bottom: 10px; }
  .hud { justify-content: flex-end; }
  /* Still frames: the layer list tells it; the paragraph stays for screen readers only */
  body.reduced .still, body[data-state="still"] .still { width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
}
