/* styles.css — "The Model", a demo portfolio for a fictional developer (Wild Digital Moments).
   Glazed ceramic maquette: warm paper, porcelain, ink, and colour as
   information. Each floor of the tower has its own glaze; the accent of the
   whole page (card rule, rail marker, focus ring, panel) follows the floor in
   view. The glaze hexes must match GLAZE in js/kit.js.
   Two families: Newsreader (names and display lines, the "engraved plaque"
   voice) and Instrument Sans (everything you read). */

/* ===== Fonts: self-hosted, no third-party request ===== */
@font-face { font-family: "Instrument Sans"; src: url("fonts/instrument-sans-400-normal.woff2?v=c178fc5e") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Instrument Sans"; src: url("fonts/instrument-sans-600-normal.woff2?v=36a59be5") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Newsreader"; src: url("fonts/newsreader-400-normal.woff2?v=48b72fa7") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Newsreader"; src: url("fonts/newsreader-600-normal.woff2?v=7cc0808d") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Newsreader"; src: url("fonts/newsreader-400-italic.woff2?v=a6974fdd") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
/* DM Mono: only for the annotation tags — the one place the page speaks in types. */
@font-face { font-family: "DM Mono"; src: url("fonts/dm-mono-400-normal.woff2?v=e1ed461a") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "DM Mono"; src: url("fonts/dm-mono-500-normal.woff2?v=c4598219") format("woff2"); font-weight: 500; font-display: swap; }

/* ===== Floor colour: registered so the page accent can ease between floors ===== */
@property --floor { syntax: "<color>"; inherits: true; initial-value: #a8673f; }
@property --floor-ink { syntax: "<color>"; inherits: true; initial-value: #7d4a2e; }

/* --floor = the glaze (rules, borders, swatches: decoration only).
   --floor-ink = the same hue darkened to >= 5.8:1 on paper (text, focus ring). */
[data-floor="pagewright"] { --floor: #2f5d9e; --floor-ink: #24497f; } /* cobalt */
[data-floor="loudspeaker"]  { --floor: #d0a03a; --floor-ink: #7a5a0c; } /* sunflower */
[data-floor="harbor"]      { --floor: #5f9483; --floor-ink: #2f6457; } /* sage-teal */
[data-floor="conveyor"]      { --floor: #bd6a4a; --floor-ink: #9a4127; } /* terracotta */
[data-floor="lantern"]   { --floor: #6b3d62; --floor-ink: #6b3d62; } /* plum */
[data-floor="about"]     { --floor: #56697a; --floor-ink: #45566a; } /* slate: the crown */
[data-floor="resume"]    { --floor: #7b5638; --floor-ink: #6b4a2f; } /* walnut: the archive */
[data-floor="blog"]      { --floor: #3b3a36; --floor-ink: #3b3a36; } /* press ink: the notice column */
[data-floor="contact"]   { --floor: #8a2f2c; --floor-ink: #8a2f2c; } /* front-door red: the lobby */

/* ===== Tokens ===== */
:root {
  transition: --floor .7s ease, --floor-ink .7s ease;
  --table: #e6e1d8;      /* matches the rendered fog/table, so the canvas fades in without a flash */
  --paper: #f8f5ef;
  --ink: #1f1d1a;
  --muted: #5f5a52;      /* 6:1 on paper */
  --line: #d6cdbf;
  --rail-w: 288px;
  --strip-h: 0px; /* no notice strip on the demo; kept as a variable because the layout offsets are built on it */
  --card-w: 368px;
  --gutter: 40px;
  --display: "Newsreader", Georgia, serif;
  --sans: "Instrument Sans", system-ui, sans-serif;
  --mono: "DM Mono", ui-monospace, monospace;
}

/* ===== Base ===== */
* { box-sizing: border-box; }
html { scroll-behavior: auto; } /* native smooth scroll fights the camera damping */
body {
  margin: 0;
  background: var(--table);
  color: var(--ink);
  font: 400 1rem/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
h1, h2, h3, h4 { margin: 0; font-weight: 600; overflow-wrap: break-word; }
p { margin: 0; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: .2em; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 2px solid var(--floor-ink); outline-offset: 3px; border-radius: 2px; }

.skip {
  position: fixed; left: 12px; top: 34px; z-index: 50;
  background: var(--ink); color: var(--paper); padding: 8px 12px;
  transform: translateY(-200%);
}
.skip:focus { transform: none; }

/* ===== CV rail (desktop: a spec sheet pinned to the left edge) ===== */
.rail {
  position: fixed; z-index: 30; top: var(--strip-h); left: 0; bottom: 0; width: var(--rail-w);
  display: flex; flex-direction: column; gap: 22px;
  padding: 30px 26px 24px;
  background: var(--paper); border-right: 1px solid var(--line);
  box-shadow: inset -3px 0 0 var(--floor); /* the current floor's glaze, down the rail's edge */
  overflow-y: auto;
}
.rail-name { font: 600 2rem/1.05 var(--display); letter-spacing: -.01em; }
.rail-name a { text-decoration: none; } /* on room pages the name is the way home */
.rail-role { margin-top: 6px; color: var(--muted); }
.rail-line { font-size: .94rem; }
.rail-stack { margin: 0; font-size: .9rem; }
.rail-stack dt { font-weight: 600; }
.rail-stack dd { margin: 2px 0 0; color: var(--muted); }
.rail-links { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.rail-links li { border-bottom: 1px solid var(--line); }
.rail-links a {
  display: flex; justify-content: space-between; align-items: center; padding: 9px 0;
  text-decoration: none; font-weight: 600; overflow-wrap: anywhere;
}
.rail-links a::after { content: "→"; font-weight: 400; color: var(--muted); transition: transform .2s; }
.rail-links a:hover::after { transform: translateX(3px); }
.rail-links .short { display: none; }

.rail-index-title { font: italic 400 1rem/1.3 var(--display); color: var(--muted); margin-bottom: 6px; }
.rail-index ol { list-style: none; margin: 0; padding: 0; }
.rail-index a {
  display: flex; gap: 10px; align-items: baseline; padding: 4px 0;
  text-decoration: none; color: var(--muted); font-size: .92rem;
}
.rail-index a:hover { color: var(--ink); }
.rail-index .n { font-variant-numeric: tabular-nums; font-size: .8rem; width: 1.4em; }
/* Each floor's number wears its glaze ink; the stop you're at goes ink + bold. */
.rail-index [data-go="about"] { --floor-ink: #45566a; }
.rail-index [data-go="pagewright"] { --floor-ink: #24497f; }
.rail-index [data-go="loudspeaker"] { --floor-ink: #7a5a0c; }
.rail-index [data-go="harbor"] { --floor-ink: #2f6457; }
.rail-index [data-go="conveyor"] { --floor-ink: #9a4127; }
.rail-index [data-go="lantern"] { --floor-ink: #6b3d62; }
.rail-index [data-go="resume"] { --floor-ink: #6b4a2f; }
.rail-index [data-go="blog"] { --floor-ink: #3b3a36; }
.rail-index [data-go="contact"] { --floor-ink: #8a2f2c; }
.rail-index .n { color: var(--floor-ink); font-weight: 600; }
.rail-index a[aria-current] { color: var(--ink); font-weight: 600; }
.rail-skip { margin-top: auto; font-size: .88rem; color: var(--muted); }

/* ===== Studio credit: logo + link, muted until hovered so it reads as a signature, not an ad ===== */
.credit { display: inline-flex; align-items: center; gap: 8px; margin-top: 14px; font-size: .78rem; color: var(--muted); text-decoration: none; }
.credit-mark { width: auto; height: 28px; flex: none; opacity: .85; transition: opacity .2s; }
.credit:hover .credit-mark, .credit:focus-visible .credit-mark { opacity: 1; }
.credit:hover span, .credit:focus-visible span { text-decoration: underline; text-underline-offset: .2em; }

/* ===== 3D stage ===== */
.stage { position: fixed; inset: 0; z-index: 0; }
/* Poster (home page): a still of the finished tower, so every device sees the
   model before the 3D boots. Fixed and full-screen like the canvas, so it can
   never shift layout; the canvas sits on top of it and fades in. */
.poster img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity .9s ease; }
.poster.off img { opacity: 0; }
.stage canvas { position: absolute; inset: 0; display: block; width: 100%; height: 100%; opacity: 0; transition: opacity 1.1s ease; touch-action: pan-y; }
.stage canvas.on { opacity: 1; }
.model-status {
  display: none;
  position: fixed; z-index: 1; left: calc(var(--rail-w) + 24px); bottom: 20px;
  font-size: .85rem; color: var(--muted);
}
.js .model-status:not([hidden]) { display: block; }

/* ===== Tour stops: each fills the screen once; the card is the caption ===== */
.tour { position: relative; z-index: 2; pointer-events: none; }
.stop {
  min-height: calc(var(--vh, 1svh) * 100);
  display: flex; align-items: center; justify-content: flex-end;
  padding: calc(var(--strip-h) + 24px) var(--gutter) 24px calc(var(--rail-w) + var(--gutter));
}

/* ----- Caption card: a museum label on the model table ----- */
.card {
  pointer-events: auto;
  position: relative;
  width: var(--card-w); max-width: 100%;
  padding: 24px 26px 22px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 3px;
  box-shadow: 0 1px 0 rgba(60, 45, 25, .04), 0 22px 44px -28px rgba(60, 45, 25, .45);
  display: flex; flex-direction: column; gap: 12px;
}
/* Every floor card carries its glaze as a top rule; the active one also gets
   a heavier tab, like a pin in the label. */
.stop[data-floor] .card { border-top: 3px solid var(--floor); }
.card::before {
  content: ""; position: absolute; left: 26px; top: -5px; width: 56px; height: 6px;
  background: var(--floor); transform: scaleX(0); transform-origin: left; transition: transform .45s cubic-bezier(.2, .7, .2, 1);
}
.card.is-active::before { transform: scaleX(1); }
.card h2 { font: 600 1.85rem/1.05 var(--display); letter-spacing: -.01em; }
.card .what { font: 400 1.2rem/1.3 var(--display); }
.card p { font-size: .95rem; }
.chips { list-style: none; margin: 2px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.chips li { font-size: .78rem; line-height: 1; padding: 6px 8px 5px; border: 1px solid color-mix(in srgb, var(--floor) 45%, var(--line)); border-radius: 2px; background: color-mix(in srgb, var(--floor) 6%, #fff); }
/* A chip whose figurine is pointed at in 3D (or that is itself hovered) wears its floor's glaze. */
.chips li[data-tech] { cursor: default; transition: background-color .2s, color .2s; }
.chips li.is-lit, .chips li[data-tech]:hover, .chips li[data-tech]:focus-visible { background: var(--floor-ink); border-color: var(--floor-ink); color: #fff; }
.card .meta { font-size: .82rem; color: var(--muted); }
.open { align-self: flex-start; font-weight: 600; font-size: .95rem; }
.open::after { content: " →"; }

/* The opening and closing plaques read like a model's title block. */
.plaque { width: calc(var(--card-w) + 40px); }
.plaque-title { font: 600 2.15rem/1.08 var(--display); letter-spacing: -.015em; }
.plaque .fine { font-size: .84rem; color: var(--muted); padding-top: 12px; border-top: 1px solid var(--line); }
.plaque-skip a { font-weight: 600; }
.plaque-links { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px 20px; font-weight: 600; }

/* ===== Plain list: a sheet of paper that slides over the model ===== */
.list {
  position: relative; z-index: 3;
  margin-left: var(--rail-w);
  background: var(--paper);
  border-top: 1px solid var(--line);
  padding: 96px 56px 64px;
}
.list-head { max-width: 760px; margin-bottom: 56px; }
.list-head h2 { font: 600 clamp(2rem, 3.2vw, 2.8rem)/1.05 var(--display); letter-spacing: -.015em; }
.list-head p { margin-top: 10px; color: var(--muted); }

/* Directory: one line per room, each with its glaze swatch (the tower's colour code). */
.directory { list-style: none; margin: 0; padding: 0; max-width: 940px; }
.directory li { display: grid; grid-template-columns: minmax(170px, 250px) minmax(0, 1fr); gap: 4px 40px; align-items: baseline; padding: 16px 0; border-top: 1px solid var(--line); }
.directory a { font: 600 1.35rem/1.2 var(--display); text-decoration: none; }
.directory a::before { content: ""; display: inline-block; width: 12px; height: 12px; margin-right: 12px; background: var(--floor); border-radius: 2px; vertical-align: .05em; }
.directory a:hover { text-decoration: underline; text-decoration-color: var(--floor); }
.directory span { color: var(--muted); }

/* ----- Room content (shared by every destination page) ----- */
.case-meta { margin-top: 4px; font-size: .9rem; color: var(--muted); }
.case-body { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }
.case-body ul, .case-body ol { margin: 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: 4px; }
.case-lede { font: italic 400 1.15rem/1.4 var(--display); }
.layers { list-style: none; padding: 0 !important; }
.layers li { display: grid; grid-template-columns: 6.5em minmax(0, 1fr); gap: 8px; }
.case-stack { font-size: .85rem; color: var(--muted); margin-top: 8px; }

/* ----- Work history (resume room) ----- */
.contact h2 { font: 600 1.9rem/1.1 var(--display); margin-bottom: 24px; }
.case-body .jobs { list-style: none; margin: 0; padding: 0; gap: 0; }
.jobs > li { display: grid; grid-template-columns: 9.5em minmax(0, 1fr); gap: 6px 24px; padding: 16px 0; border-top: 1px solid var(--line); }
.jobs ul { margin-top: 6px; }
.jobs .when { color: var(--muted); font-size: .9rem; font-variant-numeric: tabular-nums; padding-top: 3px; }
.jobs h3 { font-size: 1.05rem; margin-bottom: 4px; }
.jobs h3 span { font-weight: 400; color: var(--muted); }

/* ----- Contact ----- */
.contact { padding: 56px 0 24px; border-top: 1px solid var(--line); }
.contact-mail { font: 600 clamp(1.5rem, 3.4vw, 2.4rem)/1.2 var(--display); overflow-wrap: anywhere; }
.contact p + p { margin-top: 10px; }

.foot { position: relative; z-index: 3; margin-left: var(--rail-w); padding: 20px 56px 28px; background: var(--paper); color: var(--muted); font-size: .8rem; border-top: 1px solid var(--line); }

/* ===== The room: an open destination =====
   Without JS (or on its own page before the 3D arrives) it is simply the page,
   next to the rail. With JS it becomes a sheet beside the model, and the camera
   frames the room in the space that is left. */
.room {
  position: relative; z-index: 3;
  margin-left: var(--rail-w); min-height: 100vh;
  padding: calc(var(--strip-h) + 40px) 56px 48px;
  background: var(--paper); color: var(--ink);
  border-left: 6px solid var(--floor);
}
.room-bar { margin-bottom: 28px; }
.room-back { font-weight: 600; font-size: .92rem; }
.room-back::before { content: "\2190\00a0"; }
.dest { max-width: 660px; }
.room-where { font: italic 400 1.02rem/1.3 var(--display); color: var(--floor-ink); margin-bottom: 10px; }
.dest h1 { font: 600 clamp(2rem, 3.2vw, 2.7rem)/1.06 var(--display); letter-spacing: -.015em; }
.dest h1:focus { outline: none; } /* focus lands here on navigation; it is not an interactive element */
.dest h2 { font-size: 1rem; margin-top: 18px; color: var(--floor-ink); }
.dest h3 { font-size: 1.02rem; margin-top: 8px; }
.dest a { text-decoration-color: var(--floor); }
.room-next { margin-top: 26px; padding-top: 16px; border-top: 1px solid var(--line); font-weight: 600; }
.dest-list { list-style: none; padding: 0 !important; }
.dest-list li { padding: 10px 0; border-top: 1px solid var(--line); }
.dest-list a { font: 600 1.15rem var(--display); margin-right: 10px; }
.dest-list span { color: var(--muted); }
.room-foot { margin-top: 48px; padding-top: 16px; border-top: 1px solid var(--line); }
.js .room {
  position: fixed; top: var(--strip-h); right: 0; bottom: 0; z-index: 20;
  width: min(620px, 46vw); margin: 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding-top: 32px;
  box-shadow: -30px 0 60px -30px rgba(40, 30, 15, .4);
  animation: sheet-in .55s cubic-bezier(.2, .7, .2, 1);
}
.js .room[hidden] { display: none; }
@keyframes sheet-in { from { transform: translateX(48px); opacity: 0; } to { transform: none; opacity: 1; } }
/* While a room is open the page behind stays put; the sheet scrolls on its own. */
html.in-room { overflow: hidden; }
.js.in-room .foot { display: none; }

/* ===== Tooltip over a hovered floor ===== */
.tip {
  position: fixed; left: 0; top: 0; z-index: 35; pointer-events: none;
  max-width: 280px; padding: 10px 12px;
  background: var(--ink); color: var(--paper); border-radius: 2px;
  border-left: 4px solid var(--floor);
  box-shadow: 0 10px 30px -12px rgba(0, 0, 0, .4);
}
.tip-name { font: 600 1.05rem/1.2 var(--display); }
.tip-stack { font-size: .8rem; opacity: .85; margin-top: 3px; }

/* ===== Phones and small tablets: the rail becomes a bottom bar ===== */
@media (max-width: 899px) {
  :root { --gutter: 16px; --bar-h: 58px; }
  .rail {
    top: auto; right: 0; width: auto; height: var(--bar-h);
    flex-direction: row; align-items: center; justify-content: space-between; gap: 10px;
    padding: 8px 16px; border-right: 0; border-top: 1px solid var(--line); overflow: hidden;
  }
  .rail-name { font-size: 1.15rem; }
  .rail-role { margin-top: 1px; font-size: .74rem; white-space: nowrap; }
  .rail-line, .rail-stack, .rail-index, .rail-skip, .rail-credit { display: none; }
  .rail-id { min-width: 0; }
  .rail-role { overflow: hidden; text-overflow: ellipsis; }
  .rail-links { display: flex; flex: none; border: 0; gap: 14px; }
  .rail-links li { border: 0; }
  .rail-links a { padding: 8px 0; font-size: .88rem; white-space: nowrap; overflow-wrap: normal; }
  .rail-links a::after { content: none; }
  .rail-links .long { display: none; }
  .rail-links .short { display: inline; }

  .stop {
    align-items: flex-end; justify-content: center;
    padding: calc(var(--strip-h) + 16px) var(--gutter) calc(var(--bar-h) + 14px);
  }
  .card, .plaque { width: 100%; padding: 18px 18px 16px; gap: 9px; }
  .card h2 { font-size: 1.5rem; }
  .card .what { font-size: 1.05rem; }
  .card p { font-size: .9rem; }
  /* Phones: the card stays short so the floor is visible above it; the long
     paragraph is in the case-study panel and the plain list. */
  .card .how { display: none; }
  .plaque-title { font-size: 1.6rem; }
  .model-status { left: 16px; bottom: calc(var(--bar-h) + 12px); }

  .list { margin-left: 0; padding: 64px var(--gutter) calc(var(--bar-h) + 24px); }
  .directory li, .jobs > li { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .foot { margin-left: 0; padding: 16px var(--gutter) calc(var(--bar-h) + 16px); }
  .room { margin-left: 0; padding: calc(var(--strip-h) + 24px) var(--gutter) calc(var(--bar-h) + 24px); border-left: 0; border-top: 6px solid var(--floor); }
  /* Phones: the sheet rises from the bottom and leaves the top third to the model. */
  .js .room { top: calc(var(--vh, 1svh) * 34); bottom: var(--bar-h); width: 100%; padding-top: 18px; animation-name: sheet-up; }
  @keyframes sheet-up { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }
}
@media (max-width: 380px) {
  .rail-role { display: none; }
}

/* ===== Annotation tags =====
   Technical-drawing annotations: a monospace key with a quiet type hint, a
   thin leader and a small measured dot at the part. Warm paper, not a dark
   terminal. Placed each frame by callouts.js with transforms only. */
/* z-index 2, not above the page: the tags belong to the model, so the plain
   list, the footer and every opaque sheet that scrolls over the model covers
   them too (they were drawn on top of the list on phones). */
.callouts { position: fixed; inset: 0; z-index: 2; pointer-events: none; }
.callouts .leaders { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.leaders path { fill: none; stroke: var(--floor-ink); stroke-width: 1.1; opacity: 0; transition: opacity .25s; }
.leaders circle { fill: var(--paper); stroke: var(--floor-ink); stroke-width: 1.3; opacity: 0; transition: opacity .25s; }
.leaders .is-on { opacity: .9; }
.tag {
  position: absolute; left: 0; top: 0; pointer-events: auto;
  display: inline-flex; align-items: baseline; gap: 1px; white-space: nowrap;
  padding: 5px 8px 5px 7px; border: 1px solid color-mix(in srgb, var(--floor) 55%, var(--line));
  border-radius: 3px; background: color-mix(in srgb, var(--paper) 90%, transparent);
  box-shadow: 0 6px 16px -10px rgba(60, 45, 25, .55);
  font: 500 .74rem/1 var(--mono); color: var(--ink); cursor: pointer;
  opacity: 0; visibility: hidden; transition: opacity .25s, visibility .25s, background-color .15s, border-color .15s;
}
.tag.is-on { opacity: 1; visibility: visible; }
.tag-dest .tag-key { font-weight: 500; }
.tag-dest::before { content: ""; width: 7px; height: 7px; margin-right: 6px; border-radius: 1px; background: var(--floor); align-self: center; }
.tag-type { color: var(--floor-ink); font-weight: 400; }
.tag:hover, .tag:focus-visible { background: var(--paper); border-color: var(--floor-ink); }
.tag:active { transform-origin: center; filter: brightness(.96); }
/* The one-time invitation: the first tag says "inspect" and pulses twice. */
.tag.is-nudge::after { content: "inspect \21B5"; margin-left: 8px; padding-left: 8px; border-left: 1px solid var(--line); color: var(--muted); font-weight: 400; }
.tag.is-nudge { animation: tag-pulse 1.4s ease-out 2; }
@keyframes tag-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--floor) 45%, transparent); } 100% { box-shadow: 0 0 0 10px transparent; } }

/* ----- The inspect window ----- */
.win { padding: 0; border: 0; background: transparent; max-width: none; max-height: none; width: 100%; height: 100%; margin: 0; }
.win::backdrop { background: rgba(31, 29, 26, .22); }
.win-panel {
  position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%);
  width: min(440px, calc(100% - 24px)); max-height: 60vh; overflow-y: auto;
  background: var(--paper); border-top: 4px solid var(--floor); border-radius: 8px 8px 6px 6px;
  box-shadow: 0 24px 60px -24px rgba(40, 30, 15, .55); padding: 10px 20px 20px;
  transition: transform .25s cubic-bezier(.2, .7, .2, 1);
}
.win[open] .win-panel { animation: win-up .32s cubic-bezier(.2, .7, .2, 1); }
@keyframes win-up { from { transform: translate(-50%, 30px); opacity: 0; } to { transform: translateX(-50%); opacity: 1; } }
.win-grab { width: 42px; height: 5px; margin: 2px auto 12px; border-radius: 3px; background: var(--line); cursor: grab; touch-action: none; }
.win-close { position: absolute; top: 8px; right: 10px; width: 36px; height: 36px; border: 0; background: none; font: 400 1.5rem/1 var(--sans); color: var(--muted); cursor: pointer; }
.win-body { display: flex; flex-direction: column; gap: 9px; }
.win-title { font: 600 1.45rem/1.1 var(--display); padding-right: 32px; touch-action: none; }
.win-mono, .win-title.win-mono { font: 500 1.05rem/1.2 var(--mono); }
.win-type { color: var(--floor-ink); font-weight: 400; }
.win-sub { font: 600 1.15rem/1.15 var(--display); }
.win-status { font-size: .78rem; color: var(--floor-ink); }
.win-what { font-size: .93rem; }
.win-used { font-size: .9rem; color: var(--muted); }
.win-shown { font-size: .74rem; color: var(--muted); margin-top: -4px; }
.win-link { border: 0; padding: 0; background: none; font: 600 .9rem var(--sans); color: var(--ink); text-decoration: underline; text-decoration-color: var(--floor); text-underline-offset: .2em; cursor: pointer; }
.win-rule { border: 0; border-top: 1px solid var(--line); margin: 4px 0; width: 100%; }
.win-links { font-weight: 600; }
.win .chips { margin: 0; }

/* ----- Turn hint (all sizes) ----- */
.spin-hint:not([hidden]) {
  display: flex; align-items: center; gap: 8px; position: fixed; z-index: 2;
  left: calc(var(--rail-w) + (100vw - var(--rail-w) - var(--card-w) - 56px) / 2); top: calc(var(--strip-h) + 14px); transform: translateX(-50%);
  padding: 6px 8px 6px 14px; border-radius: 999px; white-space: nowrap;
  background: color-mix(in srgb, var(--paper) 94%, transparent); border: 1px solid var(--line);
  font-size: .82rem; box-shadow: 0 8px 20px -14px rgba(60, 45, 25, .6);
}
.spin-hint button { width: 26px; height: 26px; border: 0; background: none; font-size: 1.05rem; color: var(--muted); cursor: pointer; }
.spin-phone { display: none; }
@media (max-width: 899px) {
  .spin-hint:not([hidden]) { left: 50%; }
  .spin-desk { display: none; }
  .spin-phone { display: inline; }
}

/* ----- Phones: the caption cards become the invisible scroll track ----- */
.hint { display: none; }
@media (max-width: 899px) {
  .js .tour .card { visibility: hidden; }        /* the tour keeps its length; its text never crosses the model */
  .hint:not([hidden]) {
    display: flex; align-items: center; gap: 8px; position: fixed; z-index: 2;
    left: 50%; top: calc(var(--strip-h) + 12px); transform: translateX(-50%);
    padding: 7px 8px 7px 14px; border-radius: 999px; white-space: nowrap;
    background: color-mix(in srgb, var(--paper) 94%, transparent); border: 1px solid var(--line);
    font-size: .8rem; box-shadow: 0 8px 20px -14px rgba(60, 45, 25, .6);
  }
  .hint button { width: 28px; height: 28px; border: 0; background: none; font-size: 1.1rem; color: var(--muted); cursor: pointer; }
  .win-panel { bottom: calc(var(--bar-h) + 10px); }
}

/* ===== Reduced motion: no flights, no slides; the model is a still ===== */
@media (prefers-reduced-motion: reduce) {
  .stage canvas, .poster img { transition: none; }
  .card::before { transition: none; }
  :root { transition: none; }
  .js .room { animation: none; }
  .tag, .leaders path, .leaders circle, .win-panel { transition: none !important; }
  .tag.is-nudge, .win[open] .win-panel { animation: none; }
  .rail-links a::after { transition: none; }
}
