/* ==========================================================================
   LittleMan Dev · /walkthrough
   ------------------------------------------------------------------------
   Loaded AFTER site.css, which supplies every token, the cursor, the nav, the
   type scale and the primitives. This file does two things and nothing else:

     A  puts the camera back. The home page is a document; this page is the
        fly-through, so #stage.fly reverts to a fixed 3D stage with panels
        stacked on Z. Everything is scoped to .fly so site.css's document
        layout is left intact for the page it belongs to.

     B  the demos. Each panel carries one live, running demonstration of a
        thing I would otherwise have to claim in a sentence.

     01  the stage (camera restored)
     02  panel furniture
     03  demo shell
     04  easing lab
     05  magnetic buttons & pointer readout
     06  performance gauge
     07  tilt cards
     08  interface states
     09  type specimen
     10  responsive frame
     11  handover cards
     12  flat fallback & responsive
   ========================================================================== */

/* ---------- 01  the stage ---------------------------------------------- */

body.wt { overflow-x: hidden; }

.driver { position: relative; width: 100%; z-index: 0; }

#stage.fly {
  position: fixed; inset: 0; z-index: 10;
  padding: 0;
  /* Shorter focal length than a subtle depth effect would use: at 1150px a
     panel passing the camera really does swell past you. */
  perspective: 1150px;
  perspective-origin: 50% 46%;
  pointer-events: none;
}

#stage.fly .panel {
  position: absolute; top: 50%; left: 50%;
  width: min(1180px, calc(100vw - var(--gutter) * 2));
  margin: 0;
  transform: translate(-50%, -50%);
  transform-style: preserve-3d;
  perspective: none;
  will-change: transform, opacity, filter;
  pointer-events: none;
  backface-visibility: hidden;
}
#stage.fly .panel.is-live { pointer-events: auto; }

/* The reveal transition from site.css would fight the camera for control of
   the same transform, so it is switched off here, on this page the camera
   owns every panel's position, every frame. */
#stage.fly .panel .panel-inner,
#stage.fly .panel .rise {
  opacity: 1;
  transform: none;
  transition: none;
}

/* Panels are SURFACES, not floating text.
   This is what makes the fly-through read as travel. With transparent panels
   every panel in the scene shows through every other one, so the only way to
   keep the focused one legible is to fade the rest out early, and once you
   do that, all you perceive is a crossfade. Give each panel an opaque face
   and the depth sorts itself out: the near one occludes the far ones, a
   passing panel swells until its surface fills the frame, and you come out
   the other side of it. That is the whole effect. */
#stage.fly .panel-inner {
  padding: clamp(1.4rem, 2.5vw, 2.5rem);
  border-radius: 26px;
  background: linear-gradient(160deg, var(--bg-2), var(--bg) 78%);
  border: 1px solid var(--line-soft);
  box-shadow:
    0 1px 0 color-mix(in srgb, var(--accent-2) 7%, transparent) inset,
    0 50px 120px -50px var(--shadow);
}

/* This page's ground is the corridor, so the home page's reading scrim, which
   washes the centre of the frame to calm it behind live text, is the wrong
   instrument. Panels here are opaque; they do their own calming. */
body.wt .vignette {
  background: radial-gradient(ellipse at 50% 45%,
    transparent 36%,
    color-mix(in srgb, var(--bg) 55%, transparent) 80%,
    color-mix(in srgb, var(--bg) 82%, transparent) 100%);
  opacity: .8;
}
body.wt #field { opacity: var(--field-op); }

/* the motion toggle, three bars that taper into a vanishing point when the
   camera is on, and sit flat and parallel when it is off */
.motion-toggle {
  display: flex; align-items: center; gap: .5rem; flex-shrink: 0;
  padding: .34rem .7rem .34rem .55rem; border-radius: 30px;
  border: 1px solid var(--line); background: var(--card-2);
  font-family: var(--font-mono); font-size: .6rem; font-weight: 500;
  letter-spacing: .16em; color: var(--ink-soft);
  transition: border-color .4s var(--ease), color .4s var(--ease),
              background .4s var(--ease);
}
.motion-toggle:hover { border-color: var(--electric); color: var(--ink); }
.motion-toggle .ico { display: grid; gap: 2.5px; width: 15px; place-items: center; }
.motion-toggle .ico i {
  display: block; height: 1.5px; width: 100%; border-radius: 2px;
  background: currentColor; opacity: .55;
  transition: transform .5s var(--ease), opacity .5s var(--ease);
}
.motion-toggle[aria-pressed='true'] {
  border-color: color-mix(in srgb, var(--electric) 55%, transparent);
  color: var(--ink);
}
.motion-toggle[aria-pressed='true'] .ico i { background: var(--electric); opacity: 1; }
.motion-toggle[aria-pressed='true'] .ico i:nth-child(1) { transform: scaleX(.45); }
.motion-toggle[aria-pressed='true'] .ico i:nth-child(2) { transform: scaleX(.72); }
.motion-toggle[aria-pressed='true'] .ico i:nth-child(3) { transform: scaleX(1); }

/* The back-link has to stay on one line. At four wrapped words it made the
   nav 105px tall, and since the nav floats over a fixed stage that meant it
   covered the top of every panel, the eyebrow on each one simply vanished
   behind it. Two labels, one per width, instead of one that wraps. */
.nav-demo { white-space: nowrap; }
.nav-demo .nd-short { display: none; }

@media (max-width: 700px) {
  .nav-demo .nd-long { display: none; }
  .nav-demo .nd-short { display: inline; }
}

/* ---------- 02  panel furniture ---------------------------------------- */

/* .h-sec carries its own bottom margin; .h-hero does not, because on the home
   page it is always followed by a list with its own spacing. Here it is
   followed by a paragraph, so it needs one. */
.h-hero + .lede,
.h-hero + .wt-lede { margin-top: 1.1rem; }

.wt-lede { max-width: 58ch; }
.wt-centered { max-width: 62ch; margin-inline: auto; }
.center { text-align: center; }
.eyebrow.center { justify-content: center; }
.cta-row.center { justify-content: center; }

/* copy on the left, the running demo on the right */
.wt-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(1.4rem, 3vw, 3rem);
  align-items: center;
}

.btn-sm { padding: .62rem 1.3rem; font-size: .64rem; margin-top: 1.2rem; }

/* the "what you get" strip that closes most panels */
.wt-get {
  margin-top: clamp(1.1rem, 2.2vw, 1.9rem);
  padding-top: clamp(.9rem, 1.8vw, 1.4rem);
  border-top: 1px solid var(--line-soft);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 1.1rem;
  align-items: start;
}
.wt-get b {
  font-family: var(--font-mono); font-size: .6rem; font-weight: 500;
  letter-spacing: .22em; text-transform: uppercase;
  color: var(--accent); white-space: nowrap; padding-top: .18rem;
}
.wt-get p { font-size: .92rem; color: var(--ink-soft); line-height: 1.55; max-width: 78ch; }

/* hero table of contents */
.wt-toc {
  list-style: none; display: flex; flex-wrap: wrap; gap: .5rem;
  margin-top: 1.8rem; padding-top: 1.4rem; border-top: 1px solid var(--line-soft);
}
.wt-toc button {
  font-family: var(--font-mono); font-size: .62rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint);
  padding: .42rem .8rem; border-radius: 30px;
  border: 1px solid var(--line-soft);
  transition: color .35s var(--ease), border-color .35s var(--ease),
              background .35s var(--ease), transform .35s var(--ease);
}
.wt-toc button:hover {
  color: var(--ink); border-color: var(--electric);
  background: var(--glow); transform: translateY(-2px);
}

/* ---------- 03  demo shell --------------------------------------------- */

.demo {
  border: 1px solid var(--line-soft);
  border-radius: 20px;
  background: var(--card);
  padding: clamp(1rem, 2vw, 1.6rem);
  min-width: 0;
}
.demo-cap {
  margin-top: .9rem;
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .1em;
  color: var(--ink-faint); line-height: 1.5;
}

/* ---------- 04  easing lab --------------------------------------------- */

.ease-track {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr) 9rem;
  align-items: center; gap: .8rem;
  padding: .55rem 0;
}
.ease-name, .ease-note {
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .1em;
  color: var(--ink-faint);
}
.ease-note { text-align: right; }
.ease-track.is-house .ease-name,
.ease-track.is-house .ease-note { color: var(--accent); }

.ease-rail {
  position: relative; height: 2px; border-radius: 2px;
  background: var(--line-soft);
}
.ease-dot {
  position: absolute; top: 50%; left: 0;
  width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%;
  background: var(--ink-faint);
  /* the run itself is applied from JS, so all three start on the same frame */
}
.ease-track.is-house .ease-dot {
  background: linear-gradient(140deg, var(--electric), var(--cursor-blue));
  box-shadow: 0 0 14px var(--glow);
}

/* ---------- 05  magnetic buttons & pointer readout --------------------- */

.magnet-field {
  display: flex; flex-wrap: wrap; gap: .8rem;
  justify-content: center; align-items: center;
  min-height: 8.5rem;
}
.mag { will-change: transform; }

.cursor-read, .perf-read {
  display: grid; gap: .5rem;
  margin-top: 1.1rem; padding-top: 1rem;
  border-top: 1px solid var(--line-soft);
}
.cursor-read { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cursor-read dt, .perf-read dt {
  font-family: var(--font-mono); font-size: .54rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-faint);
}
.cursor-read dd, .perf-read dd {
  font-family: var(--font-mono); font-size: .85rem; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.perf-read { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .8rem 1rem; }
.perf-read dd { font-size: .78rem; color: var(--accent); }

/* ---------- 06  performance gauge -------------------------------------- */

.gauge { text-align: center; padding: .6rem 0 .2rem; }
.gauge-num {
  display: block;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(3rem, 7vw, 4.6rem); line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 6px 40px var(--glow);
}
.gauge-lbl {
  font-family: var(--font-mono); font-size: .56rem; letter-spacing: .24em;
  text-transform: uppercase; color: var(--ink-faint);
}

/* ---------- 07  tilt cards --------------------------------------------- */

.tilt-row {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem; margin-top: 1.6rem;
  perspective: 1000px;
}
.tcard {
  position: relative; overflow: hidden;
  padding: 1.5rem 1.3rem 1.6rem;
  border-radius: 18px;
  border: 1px solid var(--line-soft);
  background: linear-gradient(160deg, var(--card-2), var(--card));
  transform-style: preserve-3d;
  will-change: transform;
  transition: box-shadow .5s var(--ease);
  box-shadow: 0 10px 40px -20px var(--shadow);
}
.tcard:hover { box-shadow: 0 30px 70px -28px var(--shadow); }
.tcard-idx {
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .2em;
  color: var(--accent);
}
.tcard h3 {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.25rem; margin: .5rem 0 .5rem;
}
.tcard p { font-size: .88rem; color: var(--ink-soft); line-height: 1.55; }

/* the highlight that tracks the pointer across the card */
.tcard-shine {
  position: absolute; inset: 0; pointer-events: none;
  opacity: 0; transition: opacity .45s var(--ease);
  background: radial-gradient(
    18rem 18rem at var(--sx, 50%) var(--sy, 50%),
    color-mix(in srgb, var(--cursor-pale) 16%, transparent) 0%,
    transparent 62%);
}
.tcard:hover .tcard-shine { opacity: 1; }

/* ---------- 08  interface states --------------------------------------- */

.state-btn { position: relative; min-width: 11.5rem; }
.state-btn .sb-spin {
  position: absolute; top: 50%; right: 1.05rem;
  width: 13px; height: 13px; margin-top: -6.5px;
  border: 2px solid color-mix(in srgb, #fff 45%, transparent);
  border-top-color: #fff; border-radius: 50%;
  opacity: 0; transition: opacity .25s var(--ease);
}
.state-btn[data-state='loading'] { padding-right: 2.6rem; }
.state-btn[data-state='loading'] .sb-spin {
  opacity: 1; animation: sbspin .7s linear infinite;
}
@keyframes sbspin { to { transform: rotate(360deg); } }
.state-btn[disabled] { opacity: .75; }

.state-out {
  margin-top: 1.1rem; min-height: 6.2rem;
  border: 1px dashed var(--line);
  border-radius: 14px;
  display: grid; place-items: center;
  padding: 1rem;
  text-align: center;
  transition: border-color .5s var(--ease), background .5s var(--ease);
}
.state-out .state-empty,
.state-out .state-msg {
  font-size: .88rem; color: var(--ink-soft); line-height: 1.5;
  display: grid; gap: .45rem; justify-items: center;
  animation: statein .5s var(--ease);
}
@keyframes statein {
  from { opacity: 0; transform: translateY(8px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
.se-mark, .sm-mark { font-size: 1.5rem; line-height: 1; }
.state-out[data-state='success'] {
  border-style: solid;
  border-color: color-mix(in srgb, #35d39a 45%, transparent);
  background: color-mix(in srgb, #35d39a 7%, transparent);
}
.state-out[data-state='success'] .sm-mark { color: #35d39a; }
.state-out[data-state='error'] {
  border-style: solid;
  border-color: color-mix(in srgb, #ff6b6b 45%, transparent);
  background: color-mix(in srgb, #ff6b6b 7%, transparent);
}
.state-out[data-state='error'] .sm-mark { color: #ff6b6b; }
.state-out[data-state='loading'] { border-color: var(--electric); }

/* the skeleton that stands in while it is thinking */
.sk-row { display: grid; gap: .5rem; width: min(100%, 17rem); }
.sk-row i {
  display: block; height: .6rem; border-radius: 4px;
  background: linear-gradient(90deg,
    var(--line-soft) 25%, color-mix(in srgb, var(--accent) 16%, transparent) 50%,
    var(--line-soft) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.3s linear infinite;
}
.sk-row i:nth-child(2) { width: 82%; }
.sk-row i:nth-child(3) { width: 60%; }
@keyframes shimmer { to { background-position: -200% 0; } }

.state-legend {
  list-style: none; display: flex; flex-wrap: wrap; gap: .4rem;
  margin-top: 1rem;
}
.state-legend li {
  font-family: var(--font-mono); font-size: .55rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint);
  padding: .3rem .6rem; border-radius: 20px;
  border: 1px solid var(--line-soft);
  transition: all .35s var(--ease);
}
.state-legend li.on {
  color: var(--ink); border-color: var(--electric); background: var(--glow);
}

/* ---------- 09  type specimen ------------------------------------------ */

.type-demo {
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(1.2rem, 3vw, 2.6rem);
  margin-top: 1.4rem; align-items: start;
}
.type-specimen {
  border: 1px solid var(--line-soft); border-radius: 18px;
  background: var(--card); padding: clamp(1rem, 2vw, 1.5rem);
  display: grid; gap: .9rem;
}
.ts-row { display: grid; gap: .25rem; }
.ts-tag {
  font-family: var(--font-mono); font-size: .52rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--ink-faint);
}
.ts-sample { display: block; color: var(--ink); line-height: 1.15; }
.ts-1 { font-family: var(--font-display); font-weight: 700; font-size: clamp(1.6rem, 3.4vw, 2.5rem); }
.ts-2 { font-family: var(--font-display); font-weight: 600; font-size: clamp(1.2rem, 2.4vw, 1.7rem); }
.ts-3 { font-family: var(--font-body); font-weight: 300; font-size: 1.1rem; color: var(--ink-soft); }
.ts-4 { font-family: var(--font-body); font-weight: 400; font-size: .92rem; color: var(--ink-soft); }
.ts-5 { font-family: var(--font-mono); font-weight: 500; font-size: .85rem; color: var(--accent); }

.type-rules { list-style: none; display: grid; gap: .7rem; margin-top: 1.1rem; }
.type-rules li {
  font-size: .88rem; color: var(--ink-soft); line-height: 1.5;
  padding-left: 1.1rem; position: relative;
}
.type-rules li::before {
  content: ''; position: absolute; left: 0; top: .55rem;
  width: 5px; height: 5px; border-radius: 50%; background: var(--electric);
}
.type-rules b { color: var(--ink); font-weight: 600; }

/* ---------- 10  responsive frame --------------------------------------- */

.resp-demo { margin-top: 1.5rem; }
.resp-frame {
  position: relative;
  width: min(100%, 62rem);
  margin: 0 auto;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--bg-2);
  overflow: hidden;
  transition: width .1s linear;
}
.resp-page { pointer-events: none; user-select: none; }

.rp-bar {
  display: flex; align-items: center; gap: .3rem;
  padding: .5rem .7rem; border-bottom: 1px solid var(--line-soft);
  background: var(--card-2);
}
.rp-bar i { width: 7px; height: 7px; border-radius: 50%; background: var(--line); }
.rp-url {
  margin-left: .6rem; font-family: var(--font-mono); font-size: .55rem;
  color: var(--ink-faint); white-space: nowrap; overflow: hidden;
}
.rp-body { padding: .9rem; display: grid; gap: .9rem; }

.rp-nav { display: flex; align-items: center; justify-content: space-between; }
.rp-logo { width: 3.4rem; height: .55rem; border-radius: 3px; background: var(--electric); }
.rp-links { display: flex; gap: .35rem; }
.rp-links i { width: 1.5rem; height: .4rem; border-radius: 3px; background: var(--line); }

.rp-hero { display: grid; grid-template-columns: 1.1fr 1fr; gap: .9rem; align-items: center; }
.rp-copy { display: grid; gap: .4rem; }
.rp-h { height: 1.1rem; border-radius: 4px; background: var(--ink-faint); opacity: .7; }
.rp-p { height: .45rem; border-radius: 3px; background: var(--line); }
.rp-p.short { width: 62%; }
.rp-btn {
  width: 4.6rem; height: 1.1rem; border-radius: 20px; margin-top: .3rem;
  background: linear-gradient(135deg, var(--electric), var(--cursor-blue));
}
.rp-art {
  aspect-ratio: 4 / 3; border-radius: 8px;
  background:
    radial-gradient(circle at 30% 30%, color-mix(in srgb, var(--electric) 30%, transparent), transparent 60%),
    var(--card);
  border: 1px solid var(--line-soft);
}
.rp-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; }
.rp-cards span {
  height: 3.1rem; border-radius: 8px;
  background: var(--card); border: 1px solid var(--line-soft);
}

/* the layout re-thinks itself as the frame narrows */
.resp-frame[data-w='tablet'] .rp-hero { grid-template-columns: 1fr; }
.resp-frame[data-w='tablet'] .rp-cards { grid-template-columns: repeat(2, 1fr); }
.resp-frame[data-w='phone'] .rp-hero { grid-template-columns: 1fr; }
.resp-frame[data-w='phone'] .rp-links { display: none; }
.resp-frame[data-w='phone'] .rp-cards { grid-template-columns: 1fr; }
.resp-frame[data-w='phone'] .rp-cards span:nth-child(n+3) { display: none; }
.resp-frame[data-w='phone'] .rp-art { aspect-ratio: 16 / 9; }

.resp-grip {
  position: absolute; top: 0; right: 0; height: 100%; width: 18px;
  display: grid; place-items: center;
  background: linear-gradient(90deg, transparent, var(--glow));
  border-left: 1px solid var(--line);
  cursor: ew-resize;
  touch-action: none;
}
body.custom-cursor .resp-grip { cursor: none !important; }
.grip-lines { display: flex; gap: 2px; }
.grip-lines i { width: 1.5px; height: 16px; border-radius: 2px; background: var(--accent); }
.resp-grip:hover { background: linear-gradient(90deg, transparent, var(--glow), var(--glow)); }

/* ---------- 11  handover cards ----------------------------------------- */

.deliver-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .9rem; margin-top: 1.5rem;
}
.dcard {
  padding: 1.25rem 1.15rem;
  border-radius: 16px;
  border: 1px solid var(--line-soft);
  background: var(--card);
  position: relative; overflow: hidden;
  transition: transform .5s var(--ease), border-color .5s var(--ease);
}
.dcard::before {
  content: ''; position: absolute; inset: 0 auto auto 0;
  width: 100%; height: 2px;
  background: linear-gradient(90deg, var(--electric), transparent);
  transform: scaleX(0); transform-origin: left;
  transition: transform .55s var(--ease);
}
.dcard:hover { transform: translateY(-4px); border-color: var(--line); }
.dcard:hover::before { transform: scaleX(1); }
.dc-n {
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .2em;
  color: var(--accent);
}
.dcard h3 {
  font-family: var(--font-display); font-weight: 600; font-size: 1.05rem;
  margin: .45rem 0 .4rem;
}
.dcard p { font-size: .85rem; color: var(--ink-soft); line-height: 1.5; }

/* ---------- 12  flat fallback & responsive ------------------------------ */

/* When the camera is off, reduced motion, a very short window, or the
   visitor pressed FLAT, this becomes an ordinary document. The demos all
   still run; only the travel between them stops. */
body.wt.flat #stage.fly {
  position: relative; inset: auto; perspective: none;
  pointer-events: auto; padding: 7.5rem 0 2rem;
}
body.wt.flat #stage.fly .panel {
  position: relative; top: auto; left: auto;
  transform: none !important; opacity: 1 !important; filter: none !important;
  margin: 0 auto clamp(3.5rem, 10vh, 7rem);
  pointer-events: auto;
}
body.wt.flat .driver,
body.wt.flat .dots,
body.wt.flat .scroll-hint { display: none; }
body.wt.flat #field { opacity: calc(var(--field-op) * .6); }

@media (max-width: 1000px) {
  .wt-split { grid-template-columns: 1fr; gap: 1.1rem; }
  .type-demo { grid-template-columns: 1fr; }
  .tilt-row { grid-template-columns: 1fr; }
  .deliver-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ease-track { grid-template-columns: 6.5rem minmax(0, 1fr); }
  .ease-note { display: none; }
}

@media (max-width: 700px) {
  #stage.fly { perspective: 760px; perspective-origin: 50% 43%; }
  #stage.fly .panel { width: calc(100vw - var(--gutter) * 2); }
  #stage.fly .panel-inner { padding: 1.05rem .95rem; border-radius: 20px; }
  .wt-get { grid-template-columns: 1fr; gap: .4rem; }
  .deliver-grid { grid-template-columns: 1fr; }
  .cursor-read { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .3rem; }
  .perf-read { grid-template-columns: 1fr; }
  .resp-demo { display: none; }   /* a resize demo on a phone is a joke */
  .wt-toc { gap: .35rem; }
}

@media (prefers-reduced-motion: reduce) {
  .ease-dot, .sk-row i, .state-btn .sb-spin { animation: none !important; }
  .tcard, .mag { transform: none !important; }
}
