/* =========================================================
   TOKENS
   ========================================================= */
:root{
  --ink:#F3F1ED;
  --ink-soft:#C9C6C0;
  --muted:#8E8B85;
  --bg:#111114;
  --bg-2:#17171B;
  --card:#1B1B20;
  --card-2:#212128;
  --line:rgba(255,255,255,.09);
  --line-2:rgba(255,255,255,.16);
  --accent:#F5B942;
  --accent-ink:#2A1C00;
  --accent-soft:rgba(245,185,66,.16);
  --cool:#7FB3E8;
  --good:#6FD28A;

  --sky-1:#05070E;
  --sky-2:#0B1428;
  --sky-3:#17304F;
  --sky-4:#2E5675;
  --ridge-1:#070A12;
  --ridge-2:#0D1522;
  --ridge-3:#152132;
  --water:#13283F;

  --cork:#3A2A1C;
  --cork-2:#4A3626;

  --shadow:0 24px 60px -24px rgba(0,0,0,.65);
  --radius:22px;
  --radius-sm:14px;
  --wrap:1180px;

  --font:"Geist",system-ui,-apple-system,sans-serif;
  --display:"Bricolage Grotesque","Geist",system-ui,sans-serif;
  --mono:"Geist Mono",ui-monospace,monospace;
  --hand:"Gaegu","Comic Sans MS",cursive;
}

:root[data-theme="day"]{
  --ink:#14151A;
  --ink-soft:#3C3E45;
  --muted:#75736E;
  --bg:#F5F2EB;
  --bg-2:#EFEBE2;
  --card:#FFFFFF;
  --card-2:#FBF9F5;
  --line:rgba(0,0,0,.09);
  --line-2:rgba(0,0,0,.16);
  --accent:#E8912B;
  --accent-ink:#FFFFFF;
  --accent-soft:rgba(232,145,43,.16);
  --cool:#3E7FC1;
  --good:#2E9E55;

  --sky-1:#8EC5E8;
  --sky-2:#BBD9EC;
  --sky-3:#E5CBA8;
  --sky-4:#F3D9B4;
  --ridge-1:#5E6E7D;
  --ridge-2:#7C8C99;
  --ridge-3:#9AA8B3;
  --water:#A8C8DC;

  --cork:#C89B63;
  --cork-2:#D8AE78;

  --shadow:0 24px 60px -28px rgba(20,21,26,.22);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font);
  font-size:17px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  transition:background .5s ease,color .5s ease;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
ul,ol{margin:0;padding:0;list-style:none}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 24px}
.section{padding:120px 0;position:relative;background:var(--sec-bg);--sec-bg:var(--bg)}
.section.journey,.section.app,.section.life{--sec-bg:var(--bg-2)}
.journey,.app,.life{--sec-bg:var(--bg-2)}

/* =========================================================
   SECTION TEXTURES
   Each section gets a quiet pattern of its own so the page
   doesn't read as one flat sheet of dark. All of them are
   painted in a ::before behind the content.
   ========================================================= */
.section::before,.work::before,.notes::before{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:var(--tex,none);
  background-size:var(--tex-size,auto);
  opacity:var(--tex-o,1);
  mask:var(--tex-mask,none);
}
.section > *,.work > *,.notes > *{position:relative;z-index:1}

/* graph paper */
.intro{
  --tex:linear-gradient(var(--line) 1px,transparent 1px),
        linear-gradient(90deg,var(--line) 1px,transparent 1px);
  --tex-size:34px 34px,34px 34px;
  --tex-o:.55;
  --tex-mask:radial-gradient(ellipse 70% 80% at 20% 50%,#000,transparent 75%);
}
/* soft dot field */
.sites{
  --tex:radial-gradient(var(--line-2) 1px,transparent 1px);
  --tex-size:26px 26px;
  --tex-o:.5;
  --tex-mask:linear-gradient(to bottom,transparent,#000 25%,#000 75%,transparent);
}
/* diagonal weave */
.app{
  --tex:repeating-linear-gradient(135deg,var(--line) 0 1px,transparent 1px 11px);
  --tex-o:.8;
  --tex-mask:radial-gradient(ellipse 90% 70% at 70% 40%,#000,transparent 78%);
}
/* binary rain, with a pool of light where the crate sits */
.stack{
  --tex:radial-gradient(ellipse 60% 45% at 50% 46%,var(--accent-soft),transparent 70%);
  --tex-o:1;
}
.binary{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  overflow:hidden;
  font-family:var(--mono);
  font-size:13px;line-height:1.5;
  color:var(--ink);
  opacity:.12;
  white-space:pre;
  user-select:none;
  /* densest behind the logo grid, thinning out under the heading so it
     never competes with the type */
  mask:radial-gradient(ellipse 72% 54% at 50% 62%,#000 12%,transparent 76%);
}
.binary span{display:block}
.binary b{font-weight:400;color:var(--accent);opacity:.9}
/* contour echo of the journey map */
.process{
  --tex:repeating-radial-gradient(ellipse at 15% 110%,transparent 0 44px,var(--line) 44px 45px),
        repeating-radial-gradient(ellipse at 88% -10%,transparent 0 52px,var(--line) 52px 53px);
  --tex-o:.75;
}
/* grain, so the corkboard sits on something */
.life{
  --tex:repeating-linear-gradient(94deg,var(--line) 0 1px,transparent 1px 6px);
  --tex-o:.5;
  --tex-mask:linear-gradient(to bottom,#000,transparent 40%,transparent 60%,#000);
}
/* the work section sits on a wide warm pool of light */
.work{
  --tex:radial-gradient(ellipse 70% 55% at 50% 72%,color-mix(in srgb,var(--accent) 12%,transparent),transparent 70%);
  --tex-o:1;
}
.center{text-align:center}
.mt{margin-top:40px}

/* ---------- type ---------- */
.kicker{
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--muted);
  margin:0 0 18px;
}
.h2{
  font-family:var(--display);
  font-size:clamp(34px,5.4vw,64px);
  line-height:1;
  letter-spacing:-.04em;
  font-weight:800;
  margin:0 0 18px;
  white-space:pre-line;
}
.lead{
  font-size:clamp(16px,1.6vw,19px);
  color:var(--muted);
  max-width:56ch;
  margin:0 0 48px;
}
.center.lead{margin-left:auto;margin-right:auto}
.hint{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin:32px 0 0}

/* handwritten asides */
.hand{
  font-family:var(--hand);
  font-size:21px;
  line-height:1.3;
  color:var(--muted);
  transform:rotate(-1.4deg);
  margin:0;
}

mark.hl{
  background:linear-gradient(to top,var(--accent-soft) 0 .55em,transparent .55em);
  color:inherit;
  padding:0 .08em;
  border-radius:3px;
}
.hero-title mark.hl{
  background:var(--accent);
  color:var(--accent-ink);
  padding:0 .12em;
  border-radius:8px;
}
s.strike{color:var(--muted);text-decoration-color:var(--accent);text-decoration-thickness:3px}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:8px;
  padding:13px 22px;border-radius:999px;
  font-size:14px;font-weight:600;font-family:var(--font);
  border:1px solid var(--line-2);
  transition:transform .2s cubic-bezier(.2,.8,.3,1),background .2s,border-color .2s;
  white-space:nowrap;cursor:pointer;
}
.btn:hover{transform:translateY(-2px)}
.btn.primary{background:var(--accent);color:var(--accent-ink);border-color:transparent}
.btn.ghost{background:transparent;color:var(--ink)}
.btn.ghost:hover{background:var(--card)}
.btn.small{padding:9px 16px;font-size:13px}

/* =========================================================
   TORN PAPER EDGES
   The pseudo-element is filled with the section's own colour
   and clipped to a ragged line, so each section looks like a
   sheet of paper laid over the one before it.
   ========================================================= */
.torn{position:relative;z-index:2}
/* A shallower tear that reaches less far up, so it sits behind the
   section above instead of climbing over its content. */
.torn::before{
  content:"";position:absolute;z-index:0;
  left:0;right:0;top:-18px;height:20px;
  background:var(--sec-bg);
  clip-path:var(--torn-top);
  pointer-events:none;
  filter:drop-shadow(0 -2px 3px rgba(0,0,0,.22));
}
:root[data-theme="day"] .torn::before{filter:drop-shadow(0 -2px 3px rgba(20,21,26,.08))}
.torn-bot::after{
  content:"";position:absolute;z-index:0;
  left:0;right:0;bottom:-18px;height:20px;
  background:var(--sec-bg);
  clip-path:var(--torn-bottom);
  pointer-events:none;
  filter:drop-shadow(0 2px 3px rgba(0,0,0,.22));
}
:root[data-theme="day"] .torn-bot::after{filter:drop-shadow(0 2px 3px rgba(20,21,26,.08))}

/* =========================================================
   TOP BAR
   ========================================================= */
.topbar{
  position:fixed;top:0;left:0;right:0;z-index:60;
  display:flex;justify-content:space-between;align-items:center;
  padding:18px 24px;pointer-events:none;
}
.topbar-pill{
  pointer-events:auto;
  display:inline-flex;align-items:center;gap:8px;
  padding:9px 16px;border-radius:999px;
  background:rgba(20,20,24,.6);
  backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.12);
  color:#F3F1ED;
  font-size:12.5px;font-weight:600;font-family:var(--font);
  cursor:pointer;
  transition:transform .2s,background .2s;
}
:root[data-theme="day"] .topbar-pill{
  background:rgba(255,255,255,.7);
  border-color:rgba(0,0,0,.1);
  color:#14151A;
}
.topbar-pill:hover{transform:translateY(-1px)}
.dot-star{color:var(--accent)}
.theme-icon{font-size:14px}

/* =========================================================
   HERO
   ========================================================= */
/* Extra scroll space lets the copy leave while the photograph holds.
   JS measures the existing hero height; without JS the normal layout stays. */
.hero-track{position:relative;background:var(--bg)}
.hero-track.is-scrolling{height:calc(var(--hero-height,100svh) + 70svh)}
.hero-track.is-scrolling .hero{position:sticky;top:0}
.hero-scene{
  position:absolute;inset:0;z-index:0;
  transform-origin:34% 64%;will-change:transform;
}
.hero-copy{will-change:transform,opacity}
.hero-scrim{will-change:opacity}
/* The photo is 16:9. A full-height hero on a short, wide window is far
   taller than that, and object-fit: cover throws away the sides to
   make up the difference. Capping the height against the width keeps
   the hero close to the photo's own shape, so much less is lost. */
.hero{
  position:relative;
  height:min(100svh,64vw);
  min-height:min(100svh,560px);
  overflow:hidden;isolation:isolate;
}
.sky{
  position:absolute;inset:0;
  background:linear-gradient(to bottom,var(--sky-1) 0%,var(--sky-2) 34%,var(--sky-3) 62%,var(--sky-4) 100%);
  transition:background .6s ease;
}
.stars{position:absolute;inset:0}
.star{position:absolute;border-radius:50%;background:#fff;animation:twinkle var(--dur) ease-in-out infinite alternate}
:root[data-theme="day"] .star{opacity:0!important}
@keyframes twinkle{from{opacity:.15}to{opacity:1}}

.moon{
  position:absolute;top:12%;right:22%;
  width:70px;height:70px;border-radius:50%;
  background:radial-gradient(circle at 36% 34%,#FFF8E6,#F2E3BE 60%,#DCC79A);
  box-shadow:0 0 70px 24px rgba(255,241,206,.3),0 0 180px 60px rgba(255,241,206,.12);
  transition:all .6s ease;
}
:root[data-theme="day"] .moon{
  background:radial-gradient(circle at 40% 36%,#FFFBEF,#FFD98A 60%,#FFC24D);
  box-shadow:0 0 90px 36px rgba(255,201,90,.45),0 0 240px 90px rgba(255,201,90,.2);
  top:18%;right:18%;width:92px;height:92px;
}
.glow{position:absolute;left:0;right:0;bottom:22%;height:40%;background:radial-gradient(ellipse at 60% 100%,rgba(245,185,66,.22),transparent 65%)}

.ridge{position:absolute;left:-5%;right:-5%;bottom:0;transition:background .6s ease}
.ridge-3{height:46%;background:var(--ridge-3);
  clip-path:polygon(0 56%,9% 40%,17% 50%,26% 28%,36% 44%,45% 22%,56% 42%,66% 26%,75% 46%,85% 32%,94% 48%,100% 38%,100% 100%,0 100%);opacity:.85}
.ridge-2{height:36%;background:var(--ridge-2);
  clip-path:polygon(0 62%,8% 48%,18% 60%,28% 40%,40% 56%,52% 38%,63% 54%,74% 40%,86% 58%,96% 46%,100% 54%,100% 100%,0 100%)}
.ridge-1{height:22%;background:var(--ridge-1);
  clip-path:polygon(0 48%,12% 34%,24% 46%,38% 30%,52% 44%,66% 32%,80% 46%,92% 36%,100% 44%,100% 100%,0 100%);z-index:3}
.water{
  position:absolute;left:0;right:0;bottom:14%;height:16%;
  background:linear-gradient(to bottom,var(--water),color-mix(in srgb,var(--water) 70%,#000));
  z-index:2;overflow:hidden;transition:background .6s ease;
}
.water-shimmer{
  position:absolute;inset:0;
  background:repeating-linear-gradient(to bottom,rgba(255,255,255,.1) 0 1px,transparent 1px 7px);
  animation:drift 9s linear infinite;opacity:.5;
}
@keyframes drift{to{transform:translateY(7px)}}

.city{position:absolute;left:0;right:0;bottom:14%;height:20%;z-index:4;pointer-events:none}
.win{position:absolute;width:2px;height:2px;border-radius:1px;background:var(--accent);
  box-shadow:0 0 6px 2px rgba(245,185,66,.5);animation:flicker var(--dur) ease-in-out infinite alternate}
@keyframes flicker{from{opacity:.4}to{opacity:1}}
:root[data-theme="day"] .win{opacity:.25!important;box-shadow:none}

.foreground{
  position:absolute;left:0;right:0;bottom:0;height:16%;z-index:5;background:var(--ridge-1);
  clip-path:polygon(0 40%,10% 30%,22% 42%,34% 26%,48% 40%,60% 28%,72% 42%,86% 30%,100% 40%,100% 100%,0 100%);
}

.hero-photo{position:absolute;inset:0;z-index:6;display:none}
/* Keep the starting crop intact; the parent scene supplies scroll zoom. */
.hero-photo img{
  width:100%;height:100%;object-fit:cover;object-position:var(--focus,50% 50%);
  /* The scene now zooms with scroll, carrying the photo and Me pin together. */
  transform:none;
}
.hero-scrim{
  position:absolute;inset:0;z-index:7;display:none;
  background:
    linear-gradient(to right,rgba(6,8,14,calc(var(--scrim,.62)*1.15)) 0%,rgba(6,8,14,calc(var(--scrim,.62)*.55)) 48%,rgba(6,8,14,.12) 100%),
    linear-gradient(to top,rgba(6,8,14,.78) 0%,transparent 42%);
}
/* the daytime photo is bright and busy, so its wash has to work harder
   than the night one to keep the headline and subtitle readable */
:root[data-theme="day"] .hero-scrim{
  background:
    linear-gradient(to right,rgba(250,247,240,calc(var(--scrim,.62)*1.55)) 0%,rgba(250,247,240,calc(var(--scrim,.62)*.9)) 42%,rgba(250,247,240,.14) 100%),
    linear-gradient(to top,rgba(250,247,240,.8) 0%,transparent 46%);
}
/* the phone crop is portrait and you sit low and left in it, so the
   two desktop washes — one from the left, one from the bottom —
   stacked right on top of you and buried the whole picture. On a
   narrow screen the copy is a band across the middle instead, so the
   wash runs down the photo and only thickens behind that band. */
@media (max-width:680px) and (orientation:portrait){
  /* the night photo is already dark and the copy on it is white, so
     its wash stays light — enough to lift the text off the city
     lights, not enough to flatten them */
  .hero-scrim{
    background:linear-gradient(to bottom,
      rgba(6,8,14,.05) 0%,
      rgba(6,8,14,calc(var(--scrim,.62)*.4)) 30%,
      rgba(6,8,14,calc(var(--scrim,.62)*.85)) 52%,
      rgba(6,8,14,calc(var(--scrim,.62)*.8)) 78%,
      rgba(6,8,14,.45) 100%);
  }
  :root[data-theme="day"] .hero-scrim{
    background:linear-gradient(to bottom,
      rgba(250,247,240,.12) 0%,
      rgba(250,247,240,calc(var(--scrim,.62)*.6)) 30%,
      rgba(250,247,240,calc(var(--scrim,.62)*1.5)) 52%,
      rgba(250,247,240,calc(var(--scrim,.62)*1.35)) 78%,
      rgba(250,247,240,.6) 100%);
  }
}
.hero.has-photo .hero-photo,.hero.has-photo .hero-scrim{display:block}
.hero.has-photo .sky,.hero.has-photo .ridge,.hero.has-photo .water,
.hero.has-photo .city,.hero.has-photo .foreground{opacity:0}

/* the copy sits above centre so it clears you in the photo — you're
   low and left, and the headline was landing across you */
.hero-inner{
  position:relative;z-index:10;height:100%;
  max-width:var(--wrap);margin:0 auto;
  padding:0 24px clamp(70px,17svh,190px);
  display:flex;align-items:center;
  pointer-events:none;
}
.hero-copy{max-width:660px;opacity:var(--heroOpacity,1);pointer-events:auto}

.hero-kicker{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:12px;letter-spacing:.1em;
  color:#E8E4DA;background:rgba(0,0,0,.3);backdrop-filter:blur(10px);
  padding:7px 14px;border-radius:999px;border:1px solid rgba(255,255,255,.14);margin:0 0 20px;
}
:root[data-theme="day"] .hero-kicker{background:rgba(255,255,255,.6);color:#2A2B30;border-color:rgba(0,0,0,.1)}
.wave{color:var(--accent)}

.hero-title{
  font-family:var(--display);
  font-size:clamp(42px,7.4vw,92px);
  line-height:.95;letter-spacing:-.045em;font-weight:800;
  margin:0 0 20px;color:#FBFAF7;text-shadow:0 2px 40px rgba(0,0,0,.4);
}
:root[data-theme="day"] .hero-title{color:#14151A;text-shadow:0 2px 30px rgba(255,255,255,.5)}
.hero-sub{font-size:clamp(15px,1.7vw,19px);color:#D6D2C8;max-width:46ch;margin:0;text-shadow:0 1px 20px rgba(0,0,0,.5)}
:root[data-theme="day"] .hero-sub{color:#3C3E45;text-shadow:none}

.hero-pins{position:absolute;inset:0;z-index:9;pointer-events:none}
.pin{
  position:absolute;pointer-events:auto;
  display:inline-flex;align-items:center;gap:8px;
  padding:7px 13px;border-radius:999px;
  background:rgba(16,16,20,.62);backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.16);
  color:#F3F1ED;font-size:12.5px;font-weight:600;white-space:nowrap;
  transform:translate(-50%,-50%);
  animation:float var(--f) ease-in-out infinite alternate;
  transition:background .25s,border-color .25s;cursor:default;
}
:root[data-theme="day"] .pin{background:rgba(255,255,255,.74);border-color:rgba(0,0,0,.1);color:#14151A}
.pin:hover{border-color:var(--accent)}
.pin .pin-meta{font-family:var(--mono);font-size:10px;color:var(--accent);letter-spacing:.06em}
.pin::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 10px 3px var(--accent-soft)}
@keyframes float{from{transform:translate(-50%,-50%)}to{transform:translate(-50%,calc(-50% - 9px))}}

.hero-badges{position:absolute;right:4%;top:18%;z-index:9;display:flex;flex-direction:column;gap:16px;max-width:230px}
.hbadge{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:14px 16px;box-shadow:var(--shadow);animation:float 5s ease-in-out infinite alternate}
.hbadge:nth-child(2){animation-delay:-2.2s;transform:rotate(-2deg)}
.hbadge b{display:block;font-family:var(--display);font-size:19px;letter-spacing:-.02em;font-weight:700}
.hbadge span{font-size:12.5px;color:var(--muted)}

/* a map pin for you: face, label, and a stem dropping to the subject.
   Anchored at the stem's tip, so left/top point at you, not at the pill. */
.me-spot{
  position:absolute;z-index:11;
  transform:translate(-50%,-100%);
  display:flex;flex-direction:column;align-items:center;
  cursor:pointer;text-decoration:none;
}
.me-pill{
  display:inline-flex;align-items:center;gap:9px;
  padding:6px 16px 6px 6px;border-radius:999px;white-space:nowrap;
  background:rgba(18,18,22,.72);
  backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.2);
  box-shadow:0 14px 28px -12px rgba(0,0,0,.75);
  transition:transform .28s cubic-bezier(.2,.9,.3,1.3),border-color .28s;
}
:root[data-theme="day"] .me-pill{
  background:rgba(255,255,255,.82);
  border-color:rgba(0,0,0,.12);
}
.me-face{
  width:34px;height:34px;flex:0 0 auto;border-radius:50%;
  overflow:hidden;display:grid;place-items:center;
  background:var(--accent);
  box-shadow:0 0 0 2px rgba(255,255,255,.28);
}
.me-face img{width:100%;height:100%;object-fit:cover}
.me-face b{font-family:var(--display);font-size:15px;font-weight:800;color:var(--accent-ink)}
.me-label{
  font-size:15px;font-weight:700;letter-spacing:-.01em;
  color:#fff;
}
:root[data-theme="day"] .me-label{color:#14151A}

/* the stem: a short line down to a dot sitting on you */
.me-stem{
  width:2px;height:34px;margin-top:-1px;
  background:linear-gradient(to bottom,rgba(255,255,255,.55),rgba(255,255,255,.14));
  position:relative;
}
:root[data-theme="day"] .me-stem{
  background:linear-gradient(to bottom,rgba(0,0,0,.4),rgba(0,0,0,.1));
}
.me-stem::after{
  content:"";position:absolute;left:50%;bottom:-5px;
  width:11px;height:11px;margin-left:-5.5px;border-radius:50%;
  background:var(--accent);
  box-shadow:0 0 0 3px rgba(245,185,66,.25);
}

.me-spot:hover .me-pill,.me-spot:focus-visible .me-pill{
  transform:translateY(-4px);
  border-color:var(--accent);
}

.scroll-cue{
  position:absolute;left:50%;bottom:112px;transform:translateX(-50%);z-index:10;
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:#CFCBC1;background:rgba(0,0,0,.3);backdrop-filter:blur(10px);
  padding:9px 18px;border-radius:999px;border:1px solid rgba(255,255,255,.14);
}
:root[data-theme="day"] .scroll-cue{background:rgba(255,255,255,.65);color:#3C3E45;border-color:rgba(0,0,0,.1)}
.cue-ring{width:8px;height:8px;border-radius:50%;background:var(--accent);animation:pulse 1.8s ease-out infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 var(--accent-soft)}70%{box-shadow:0 0 0 10px transparent}100%{box-shadow:0 0 0 0 transparent}}

/* =========================================================
   INTRO
   ========================================================= */
.intro{padding:140px 0 120px}
.intro-body{
  font-family:var(--display);
  font-size:clamp(28px,4.4vw,56px);
  line-height:1.1;letter-spacing:-.04em;font-weight:700;
  max-width:19ch;margin:0;
}
.intro-hand{margin-top:34px}
.intro-word{
  display:inline-block;
  /* Opacity and travel are set by the single scroll loop, not a timer.
     A dim baseline keeps the whole sentence available while it reveals. */
  vertical-align:baseline;
}

/* =========================================================
   JOURNEY — pins on a map, with a camera that flies between them
   Only .jworld's transform animates, so the pan stays on the
   compositor and never repaints the map.
   ========================================================= */
.journey{position:relative;background:var(--sec-bg);overflow:visible}
.journey-head{margin-bottom:26px}
.journey-head .lead{margin-bottom:0}

/* On wide screens the section is made tall by JS and this pins the
   heading and the map together, so scrolling walks the route instead
   of scrolling past it. */
.journey.scrolly{padding-top:0;padding-bottom:0}
.journey.scrolly .journey-pin{
  position:sticky;top:0;height:100svh;
  display:flex;flex-direction:column;justify-content:center;
  padding:76px 0 28px;
}
/* once pinned the heading steps back so the map gets the room */
.journey.scrolly .journey-head{flex:0 0 auto;margin-bottom:12px}
.journey.scrolly .journey-head .h2{font-size:clamp(26px,3.4vw,42px)}
.journey.scrolly .journey-head .lead{font-size:15px}
.journey.scrolly .jmap{min-height:clamp(380px,58svh,560px)}
.journey.scrolly .jmap{flex:1 1 auto;height:auto;min-height:0}
/* the buttons are for phones; on desktop the scroll is the control */
.journey.scrolly .jctl,.journey.scrolly .jstart{display:none}
.jscroll{
  position:absolute;left:50%;bottom:18px;transform:translateX(-50%);
  z-index:7;color:var(--muted);white-space:nowrap;
  opacity:0;transition:opacity .4s;pointer-events:none;
}
.journey.scrolly .jscroll{opacity:1}
.journey.scrolly .jmap.started .jscroll{opacity:0}

/* no frame — the map bleeds to the edges and fades out, so it reads as
   terrain the page is sitting on rather than a picture in a box */
.jmap{
  position:relative;
  width:100%;margin:0;
  height:clamp(460px,64svh,620px);
  overflow:hidden;
  background:transparent;
  touch-action:pan-y;
  cursor:grab;
  mask:linear-gradient(to bottom,transparent,#000 9%,#000 88%,transparent),
       linear-gradient(to right,transparent,#000 5%,#000 95%,transparent);
  mask-composite:intersect;
  -webkit-mask-composite:source-in;
}
.jmap.dragging{cursor:grabbing}

.jworld{
  position:absolute;left:0;top:0;
  width:var(--worldW,1600px);height:var(--worldH,1000px);
  transform-origin:0 0;
  transform:translate3d(var(--camX,0px),var(--camY,0px),0) scale(var(--z,1));
  transition:transform 1.05s cubic-bezier(.33,.9,.28,1);
  will-change:transform;
  backface-visibility:hidden;
}
.jmap.dragging .jworld{transition:none}

/* a supplied map image, stretched to the world box */
.map-img{position:absolute;inset:0;display:none}
.map-img img{width:100%;height:100%;object-fit:cover;display:block}
.jworld.has-map .map-img{display:block;opacity:var(--mapDim,.9)}
.jworld.has-map .map{display:none}
.map-credit{
  position:absolute;right:10px;bottom:8px;z-index:8;
  margin:0;padding:3px 8px;border-radius:5px;
  background:rgba(0,0,0,.45);
  font-family:var(--mono);font-size:9px;letter-spacing:.04em;
  color:rgba(255,255,255,.75);pointer-events:none;
}
:root[data-theme="day"] .map-credit{background:rgba(255,255,255,.6);color:rgba(0,0,0,.6)}

/* the map never changes, so it gets its own layer and is painted once */
.map{
  position:absolute;inset:0;width:100%;height:100%;
  will-change:transform;contain:paint;
}
.routelayer{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}

/* --- a plain road map --- */
.map-land{fill:var(--mp-land)}
.map-parks ellipse{fill:var(--mp-park)}
.map-blocks rect{fill:var(--mp-block)}
.map-water .lake{fill:var(--mp-water);stroke:none}
.map-water .river{fill:none;stroke:var(--mp-water);stroke-width:6;stroke-linecap:round;stroke-linejoin:round}

/* every road is a wide dark casing with a lighter fill on top —
   that pairing is what makes a line read as a road */
.map-roads .casing,.map-roads .fill{fill:none;stroke-linecap:round;stroke-linejoin:round}
.map-roads .casing{stroke:var(--mp-casing)}
.map-roads .fill{stroke:var(--mp-road)}

.map-roads .local.casing{stroke-width:2.6}
.map-roads .local.fill{stroke-width:1.5}
.map-roads .arterial.casing{stroke-width:5.6}
.map-roads .arterial.fill{stroke-width:3.6;stroke:var(--mp-road-2)}
.map-roads .highway.casing{stroke-width:8.4}
.map-roads .highway.fill{stroke-width:5.6;stroke:var(--mp-highway)}

/* Labels are divided by the camera zoom so they stay one size on screen
   however far in the map is, the way names behave on a real map. The
   1.6 is the SVG's own stretch from its viewBox to the world. */
.map-labels .place{
  font-family:var(--font);font-weight:500;
  font-size:calc(6.8px / var(--z,1));
  fill:var(--mp-label);text-anchor:middle;
  paint-order:stroke;stroke:var(--mp-land);
  stroke-width:calc(1.9px / var(--z,1));
  stroke-linejoin:round;
}
/* the city's own name, the way a map prints it largest */
.map-labels .big{
  font-size:calc(15px / var(--z,1));
  font-weight:600;
  fill:var(--mp-label-big);
  letter-spacing:.01em;
  stroke-width:calc(3.2px / var(--z,1));
}
.map-labels .water-label{fill:var(--mp-water-label);stroke:none;font-style:italic}

/* map palette — the familiar dark and light road-map looks */
:root{
  --mp-land:#1E2024;
  --mp-block:#26292E;
  --mp-park:#1E2E26;
  --mp-water:#17263C;
  --mp-casing:#15171A;
  --mp-road:#35383D;
  --mp-road-2:#43474D;
  --mp-highway:#5A5F66;
  --mp-label:#9CA5B3;
  --mp-label-big:#C7CEDA;
  --mp-water-label:#4A7FB5;
}
:root[data-theme="day"]{
  --mp-land:#F1F1F1;
  --mp-block:#E6E6E6;
  --mp-park:#D6ECD4;
  --mp-water:#AEDCF5;
  --mp-casing:#D4D4D4;
  --mp-road:#FFFFFF;
  --mp-road-2:#FFFFFF;
  --mp-highway:#FBD77E;
  --mp-label:#6B6F76;
  --mp-label-big:#3F444B;
  --mp-water-label:#4B8FC0;
}

/* the route, drawn the way a navigation line is: a darker casing with
   a bright core on top, thin enough to sit on the streets */
.route-shadow{
  fill:none;stroke:#0E3E7A;stroke-width:9;
  stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:var(--len,0);stroke-dashoffset:var(--off,0);
  transition:stroke-dashoffset 1s cubic-bezier(.33,.9,.28,1);
}
.route{
  fill:none;stroke:#3B82F6;stroke-width:5.5;
  stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:var(--len,0);stroke-dashoffset:var(--off,0);
  transition:stroke-dashoffset 1s cubic-bezier(.33,.9,.28,1);
}
:root[data-theme="day"] .route-shadow{stroke:#1A56B8}
:root[data-theme="day"] .route{stroke:#4C8DFF}

/* the heading arrow, sitting on the trail */
.jarrow{
  position:absolute;width:44px;height:44px;
  transform:translate(-50%,-50%) rotate(var(--dir,0deg)) scale(calc(1 / var(--z,1)));
  transform-origin:50% 50%;
  opacity:0;pointer-events:none;
  transition:transform 1.05s cubic-bezier(.33,.9,.28,1),opacity .4s;
  will-change:transform;
}
.jarrow.on{opacity:1}
.jarrow .ar-halo{fill:rgba(47,107,216,.25);stroke:rgba(255,255,255,.5);stroke-width:1.5}
.jarrow .ar-head{fill:#2F6BD8;stroke:#fff;stroke-width:2;stroke-linejoin:round}

.jpins{position:absolute;inset:0}
.jpin{
  position:absolute;
  /* it's a <button>, so the UA's grey face and border have to go */
  background:none;border:0;padding:0;font:inherit;color:inherit;
  /* counter-scaled so pins keep one size however far the camera zooms */
  transform:translate(-50%,-100%) scale(calc(1 / var(--z,1)));
  transform-origin:50% 100%;
  transition:transform 1.05s cubic-bezier(.33,.9,.28,1);
  display:flex;align-items:center;gap:0;
  cursor:pointer;
  will-change:transform;
}
.jpin-mark{
  position:relative;width:46px;height:46px;flex:0 0 auto;
  border-radius:50% 50% 50% 6px;
  transform:rotate(-45deg);
  background:var(--pc,#888);
  border:3px solid #fff;
  box-shadow:0 8px 16px -6px rgba(0,0,0,.6);
  display:grid;place-items:center;
  transition:scale .25s cubic-bezier(.2,.9,.3,1.3);
}
.jpin-mark svg,.jpin-mark b{transform:rotate(45deg)}
.jpin-mark svg{width:22px;height:22px}
.jpin-mark b{color:#fff;font-family:var(--display);font-size:15px;font-weight:800}
.jpin-tag{
  margin-left:-6px;
  padding:7px 13px 7px 16px;border-radius:999px;
  background:var(--card);border:1px solid var(--line-2);
  color:var(--ink);font-size:13px;font-weight:700;white-space:nowrap;
  box-shadow:0 8px 16px -8px rgba(0,0,0,.5);
  opacity:0;transform:translateX(-8px);
  transition:opacity .3s,transform .3s;
}
.jpin:hover .jpin-mark,.jpin.on .jpin-mark{scale:1.12}
.jpin:hover .jpin-tag,.jpin.on .jpin-tag{opacity:1;transform:none}
.jpin.on .jpin-mark{border-color:var(--accent)}
.jpin.done .jpin-mark{opacity:.72}

/* Full-bleed city journey. The route is a narrative across Hyderabad. */
.jmap.city-mode{width:100%;max-width:none;margin:0;border:0;border-radius:0;background:var(--sec-bg);mask:none;-webkit-mask:none}
.city-mode::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;background:linear-gradient(to bottom,var(--sec-bg),transparent 15%,transparent 83%,var(--sec-bg)),linear-gradient(to right,var(--sec-bg),transparent 7%,transparent 93%,var(--sec-bg))}
.city-mode .map-img{
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 12%,#000 88%,transparent),linear-gradient(to right,transparent,#000 10%,#000 90%,transparent);
  mask-image:linear-gradient(to bottom,transparent,#000 12%,#000 88%,transparent),linear-gradient(to right,transparent,#000 10%,#000 90%,transparent);
  -webkit-mask-composite:source-in;mask-composite:intersect;
}
.city-mode .map-img img{filter:saturate(.7);opacity:.85}
.city-route-ahead{fill:none;stroke:#5795e8;stroke-width:calc(4px / var(--z,1));stroke-linecap:round;stroke-linejoin:round;opacity:.55}
.city-name{position:absolute;left:49.4%;top:62%;transform:translate(-50%,-50%) scale(calc(1 / var(--z,1)));transform-origin:center;pointer-events:none;font:600 15px var(--font);letter-spacing:.15em;text-transform:uppercase;color:#a6b9c5;text-shadow:0 1px 5px #18242d;white-space:nowrap}
:root[data-theme="day"] .city-name{color:#687682;text-shadow:0 1px 4px #fff}
.city-mode .route-shadow{stroke:#173e73;stroke-width:calc(6px / var(--z,1))}
.city-mode .route{stroke:#5b9eff;stroke-width:calc(4px / var(--z,1))}
:root[data-theme="day"] .city-mode .route-shadow{stroke:#fff}
:root[data-theme="day"] .city-mode .route{stroke:#4285f4}
:root[data-theme="day"] .city-route-ahead{stroke:#4285f4;opacity:.5}
.city-mode .jpin{width:44px;height:54px;display:block;z-index:4;transform:translate(-50%,-100%) scale(calc(1 / var(--z,1)));transform-origin:50% 100%}
.city-mode .jpin-mark{width:38px;height:38px;margin:3px;border-width:2px;box-shadow:0 5px 14px #0005}
.city-mode .jpin-mark b{font:700 12px var(--mono);color:#162131}
.city-mode .jpin-tag{position:absolute;left:50%;bottom:calc(100% + 6px);margin:0;padding:5px 9px;border-radius:7px;font-size:11px;transform:translateX(-50%);opacity:1}
.city-mode .jpin:hover .jpin-tag,.city-mode .jpin.on .jpin-tag{transform:translateX(-50%)}
.city-mode.started .jpin:not(.on) .jpin-tag{opacity:0}
.city-mode.started .jpin:hover .jpin-tag{opacity:1}
.city-mode .jpin.on{z-index:5}
.city-mode .jpin.on .jpin-mark{border-color:#fff;box-shadow:0 0 0 7px #4285f422,0 6px 16px #0005}
.city-mode .jpin.done .jpin-mark{opacity:.85}
.city-mode .jarrow{z-index:5;transition:left 1s cubic-bezier(.33,.9,.28,1),top 1s cubic-bezier(.33,.9,.28,1),transform 1s,opacity .4s}
.city-mode .compass{top:88px;right:30px;width:64px;height:64px}
.city-overview{position:absolute;right:28px;top:170px;z-index:7;min-height:44px;padding:10px 14px;border:1px solid var(--line-2);border-radius:999px;background:var(--card);color:var(--ink);font:12px var(--font);cursor:pointer;display:none}
.city-mode.started .city-overview{display:block}
.city-caption{position:absolute;left:30px;bottom:20px;z-index:5;font:10px var(--mono);color:var(--muted);margin:0}
.city-mode .map-credit{right:30px;bottom:20px;z-index:5}
.city-mode .jdetail{left:40px;bottom:108px;width:min(400px,36%)}
.city-mode .jscroll{bottom:108px;font-size:12px;background:var(--card);padding:8px 14px;border-radius:999px}
.journey.scrolly.city-journey .journey-pin{padding:0}
.journey.scrolly.city-journey{padding-top:96px}
.journey.scrolly.city-journey .journey-head{position:relative;margin-bottom:28px}
.journey.scrolly.city-journey .city-mode{height:100%;flex:1}
@media(max-width:680px),(max-width:980px) and (max-height:500px) and (pointer:coarse){
  .jmap.city-mode{width:100%;margin:0;border-radius:0}
  .city-mode .jdetail{left:16px;right:16px;bottom:84px;width:auto}
  .city-mode .jpin-mark{width:32px;height:32px;margin:6px}
  .city-mode .jpin-tag{font-size:10px}
  .city-mode:not(.started) .jpin:not(:first-child):not(:last-child) .jpin-tag{opacity:0}
  .city-mode .jpin.on .jpin-tag{opacity:1}
  .city-mode .compass{right:18px;top:12px;width:48px;height:48px}
  .city-overview{right:16px;top:70px;font-size:11px;padding:8px 12px}
  .city-caption{left:16px;top:18px;bottom:auto;font-size:9px;max-width:180px;line-height:1.5}
  .city-mode.started .city-caption{display:none}
  .city-mode .map-credit{bottom:0;right:16px;font-size:8px}
}
@media(max-width:980px) and (max-height:500px) and (pointer:coarse){
  .city-mode .jdetail{width:min(360px,48%);right:auto}
}

/* compass rose */
.compass{
  position:absolute;right:18px;top:18px;z-index:5;
  width:76px;height:76px;
  filter:drop-shadow(0 8px 16px rgba(0,0,0,.45));
}
.compass svg{width:100%;height:100%;display:block}
.cp-face{fill:var(--card);stroke:var(--line-2);stroke-width:1.5}
.cp-ring{fill:none;stroke:var(--line);stroke-width:1}
.cp-ticks line{stroke:var(--muted);stroke-width:1}
.cp-ticks line.long{stroke:var(--ink-soft);stroke-width:1.6}
.cp-n{fill:#E4483A}
.cp-s{fill:var(--ink-soft)}
.cp-hub{fill:var(--card);stroke:var(--ink-soft);stroke-width:1.4}
.cp-l{
  position:absolute;font-family:var(--mono);font-size:9px;font-weight:600;
  color:var(--ink-soft);line-height:1;
}
.cp-ln{top:3px;left:50%;transform:translateX(-50%)}
.cp-ls{bottom:3px;left:50%;transform:translateX(-50%)}
.cp-le{right:4px;top:50%;transform:translateY(-50%)}
.cp-lw{left:4px;top:50%;transform:translateY(-50%)}

/* the big Start button, shown only before you set off */
.jstart{
  position:absolute;left:50%;bottom:28px;transform:translateX(-50%);
  z-index:6;font-size:15px;padding:15px 26px;
  transition:opacity .45s,transform .45s;
}
.jmap.started .jstart{opacity:0;transform:translateX(-50%) translateY(14px);pointer-events:none}

/* the detail card */
/* a card, not a panel — the map stays the subject */
.jdetail{
  position:absolute;left:26px;right:auto;bottom:88px;z-index:6;
  width:min(392px,46%);margin:0;
  /* opaque rather than blurred: a backdrop-filter this large is one of
     the most expensive things you can put on a moving panel */
  background:var(--card);
  border:1px solid var(--line-2);border-radius:20px;
  overflow:hidden;
  box-shadow:0 26px 50px -22px rgba(0,0,0,.7);
  opacity:0;transform:translateY(18px);pointer-events:none;
  transition:opacity .5s cubic-bezier(.2,.9,.3,1),transform .5s cubic-bezier(.2,.9,.3,1);
}
.jmap.started .jdetail{opacity:1;transform:none;pointer-events:auto}
.jd-head{
  display:flex;align-items:center;gap:11px;
  padding:11px 14px;
  background:linear-gradient(90deg,color-mix(in srgb,var(--pc,#888) 26%,transparent),transparent 70%);
  border-bottom:1px solid var(--line);
}
.jd-logo{
  width:34px;height:34px;flex:0 0 auto;border-radius:10px;
  background:#fff;display:grid;place-items:center;
}
.jd-logo svg{width:20px;height:20px}
.jd-logo b{font-family:var(--display);font-size:14px;font-weight:800;color:#111}
.jd-id{display:grid;line-height:1.25}
.jd-id b{font-family:var(--display);font-size:14.5px;letter-spacing:-.02em;font-weight:800}
.jd-id span{font-size:11.5px;color:var(--muted)}
.jd-count{margin-left:auto;font-family:var(--mono);font-size:11px;color:var(--muted)}
.jd-body{padding:14px}
.jd-body h3{font-family:var(--display);font-size:18px;line-height:1.12;letter-spacing:-.025em;margin:0 0 7px;font-weight:800}
.jd-text{
  font-size:13px;color:var(--ink-soft);margin:0;line-height:1.5;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;
}
.jdetail.open .jd-text{-webkit-line-clamp:unset;overflow:visible}
.jd-more{
  margin-top:13px;display:inline-flex;align-items:center;gap:7px;
  padding:9px 16px;border-radius:999px;cursor:pointer;
  background:var(--card-2);border:1px solid var(--line-2);color:var(--ink);
  font-family:var(--font);font-size:13px;font-weight:600;
  transition:background .2s,border-color .2s;
}
.jd-more:hover{border-color:var(--accent)}
.jd-more i{font-style:normal;transition:transform .3s}
.jdetail.open .jd-more i{transform:rotate(180deg)}
.jd-text{white-space:pre-line}
.jd-actions{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:13px}
.jd-actions .jd-more{margin-top:0}
.jd-gallery{padding:9px 14px;min-height:44px;border-radius:999px;border:1px solid var(--line-2);background:var(--accent);color:var(--accent-ink);font:600 13px var(--font);cursor:pointer}
.jd-gallery[hidden],.jd-highlights:empty{display:none}
.jd-highlights{display:none;list-style:none;padding:0;margin:14px 0 0;gap:8px;grid-template-columns:repeat(2,minmax(0,1fr))}
.jdetail.open .jd-highlights:not(:empty){display:grid}
.jd-highlights li{padding:10px;border:1px solid var(--line);border-radius:12px;background:var(--card-2);min-width:0}
.jd-highlights b{display:block;font:700 23px var(--display);color:var(--accent)}
.jd-highlights span{font-size:11px;line-height:1.3;color:var(--ink-soft);display:block}
.jdetail{max-height:calc(100% - 170px);overflow:auto;overscroll-behavior:contain}
.jpin[hidden]{display:none}
.journey-gallery{width:min(840px,calc(100% - 32px));max-height:calc(100svh - 48px);padding:0;border:1px solid var(--line-2);border-radius:24px;background:var(--card);color:var(--ink);box-shadow:var(--shadow);overflow:auto;overscroll-behavior:contain}
.journey-gallery::backdrop{background:rgba(5,7,12,.8);backdrop-filter:blur(8px)}
.jg-head{position:sticky;top:0;z-index:1;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:20px 24px;background:var(--card);border-bottom:1px solid var(--line)}
.jg-head h2{font:700 clamp(21px,4vw,30px)/1.1 var(--display);margin:0;overflow-wrap:anywhere}
.jg-close{flex-shrink:0;min-width:44px;min-height:44px;border-radius:50%;border:1px solid var(--line-2);background:var(--card-2);color:var(--ink);font-size:24px;cursor:pointer}
.jg-photos{display:grid;gap:20px;padding:24px}
.jg-photos figure{margin:0}
.jg-photos img{display:block;width:100%;max-height:65svh;object-fit:contain;border-radius:14px;background:var(--bg)}
.jg-photos img[hidden]{display:none}
.jg-photos figcaption{font-size:14px;color:var(--ink-soft);margin-top:10px}
.jg-empty{display:grid;place-content:center;text-align:center;min-height:240px;padding:24px;border:1px dashed var(--line-2);border-radius:16px;background:var(--card-2)}
.jg-empty b{font:700 26px var(--display);margin-bottom:8px}
.jg-empty p{margin:0;color:var(--muted)}

/* prev / count / next */
.jctl{
  position:absolute;left:50%;bottom:20px;transform:translateX(-50%);
  width:max-content;max-width:calc(100% - 20px);
  z-index:7;display:flex;align-items:center;gap:10px;
  padding:7px;border-radius:999px;
  background:color-mix(in srgb,var(--card) 88%,transparent);
  backdrop-filter:blur(14px);
  border:1px solid var(--line-2);
  box-shadow:0 14px 30px -14px rgba(0,0,0,.6);
  opacity:0;pointer-events:none;
  transition:opacity .45s;
}
.jmap.started .jctl{opacity:1;pointer-events:auto}
.jbtn{
  border:0;cursor:pointer;color:var(--ink);
  flex-shrink:0;white-space:nowrap;
  background:var(--card-2);
  font-family:var(--font);font-weight:600;
  transition:background .2s,transform .2s,opacity .2s;
}
.jbtn.round{width:42px;height:42px;border-radius:50%;font-size:16px}
.jbtn.wide{padding:12px 20px;border-radius:999px;font-size:14px;background:var(--accent);color:var(--accent-ink)}
.jbtn:hover{transform:translateY(-1px)}
.jbtn:disabled{opacity:.4;cursor:default;transform:none}
.jcount{font-family:var(--mono);font-size:12.5px;color:var(--muted);min-width:52px;text-align:center}

/* =========================================================
   WORK — cards standing in a cardboard box
   ========================================================= */
/* the bottom padding keeps the tab row clear of the next section's tear */
.work{position:relative;background:var(--sec-bg);--sec-bg:var(--bg);padding:0 0 86px}
/* the heading rides inside the sticky stage, so it stays on screen
   while the box turns underneath it */
.work-head{
  position:absolute;left:0;right:0;top:clamp(42px,7vh,88px);
  text-align:center;margin:0;z-index:4;pointer-events:none;
}
.work-head .h2{margin:6px 0 10px}
.work-head .lead{margin:0 auto;max-width:620px}

/* =========================================================
   WORK — cards standing in a box

   The box is real 3D: a floor, four walls and a hinged lid, each a
   positioned plane inside a preserve-3d parent. Every plane is
   anchored at its BOTTOM EDGE (transform-origin:50% 100%) and swung
   up from there, so a wall's left/top says where its foot sits on the
   floor and the rotation does the rest. app.js owns the numbers.

   Scrolling the track turns the box, swings the lid back and lifts
   the cards out. The stage is sticky inside the track, so the box
   holds still on screen while the scroll drives it.
   ========================================================= */
.box-track{
  position:relative;
  /* the scroll distance the whole sequence is spread over */
  height:300vh;
}
.box-stage{
  position:sticky;top:0;
  height:100svh;
  overflow:hidden;
}
/* the anchor the box hangs from — app.js sets left/top/scale so the
   box stays centred and fits whatever the viewport is */
.box-fit{
  position:absolute;left:50%;top:65%;
  width:0;height:0;
  transform-origin:50% 50%;
  perspective:2400px;perspective-origin:50% 42%;
}
.box3{
  position:absolute;left:0;top:0;width:0;height:0;
  transform-style:preserve-3d;
  will-change:transform;
}
/* every plane in the box shares this: anchored at its foot, free to
   carry children in 3D */
.box3 .f,.box3 .wk{
  position:absolute;
  transform-origin:50% 100%;
  transform-style:preserve-3d;
}

/* ---- the carton itself ---- */
.box-floor{
  position:absolute;left:-330px;top:-130px;
  width:660px;height:260px;
  background:
    repeating-linear-gradient(90deg,rgba(0,0,0,.05) 0 1px,transparent 1px 7px),
    linear-gradient(150deg,#D8B88B,#C09A68 58%,#A87F4F);
  box-shadow:inset 0 0 70px rgba(90,56,22,.45);
}
.box-shadow{
  position:absolute;left:-390px;top:-180px;
  width:780px;height:360px;
  transform:translateZ(-2px);
  background:radial-gradient(60% 60% at 50% 55%,rgba(30,16,4,.62),transparent 70%);
  filter:blur(30px);
}
/* inside faces catch less light than the outside of the carton */
.wall-i{
  background:
    repeating-linear-gradient(90deg,rgba(0,0,0,.05) 0 1px,transparent 1px 7px),
    linear-gradient(#E0C296,#C29C6A);
  box-shadow:inset 0 12px 26px rgba(90,56,22,.3);
}
.wall-o{
  background:linear-gradient(#B98F5C,#9A7245);
  box-shadow:inset 0 -10px 22px rgba(60,34,10,.35);
}
/* the near wall is drawn last and sits in front of the cards' feet,
   which is what makes them read as standing down inside the box */
.wall-front{
  background:
    repeating-linear-gradient(90deg,rgba(0,0,0,.05) 0 1px,transparent 1px 7px),
    linear-gradient(#C8A270,#A87E4C);
  box-shadow:inset 0 10px 24px rgba(60,34,10,.28),0 -8px 20px rgba(0,0,0,.35);
}
.wall-front::after{
  content:attr(data-plate);
  position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);
  font-family:var(--mono);font-size:13px;letter-spacing:.3em;text-transform:uppercase;
  color:rgba(70,42,16,.5);white-space:nowrap;
}
.box-lid{
  background:linear-gradient(160deg,#CDA87A,#AD8453 62%,#8E6B3E);
  box-shadow:inset 0 0 50px rgba(70,42,16,.35);
  transition:transform 1.1s cubic-bezier(.62,0,.2,1);
}
.box-lid::after{
  content:"";position:absolute;inset:14px;border-radius:3px;
  border:1px dashed rgba(70,42,16,.28);
}

/* ---- the cards standing in it ---- */
/* .wk is a plane like any other: app.js stands it up and slides it
   along the box. Only --rise and --tilt change while it animates, so
   the transform string itself never has to be rebuilt. */
.box3 .wk{
  width:var(--cw,234px);height:var(--ch,196px);
  left:calc(var(--cw,234px) / -2);top:calc(var(--ch,196px) * -1);
  margin:0;padding:0;border:0;background:none;
  color:#fff;text-align:left;cursor:pointer;
  box-shadow:0 18px 34px -14px rgba(0,0,0,.7);
  border-radius:9px;
  transition:transform .9s cubic-bezier(.2,.9,.25,1),
             box-shadow .4s,filter .4s;
  will-change:transform;
}
/* Two faces. The swap is done on opacity at the halfway point of the
   turn, where the card is edge-on and nothing can be seen anyway —
   backface-visibility is unreliable inside a <button>, whose anonymous
   content box flattens the 3D context its children live in.
   .wk-bk's own half turn cancels the card's, so its text reads the
   right way round either way. */
.wk-ft,.wk-bk{
  position:absolute;inset:0;border-radius:9px;
  padding:13px 14px;
  display:flex;flex-direction:column;
  transition:clip-path .9s cubic-bezier(.2,.9,.25,1),
             opacity .01s linear .44s;
}
.wk-bk{opacity:0}
.wk.flipped .wk-ft{opacity:0}
.wk.flipped .wk-bk{opacity:1}
.wk-ft{
  justify-content:space-between;
  background:var(--bg,linear-gradient(165deg,#FF9A6B,#F25A38));
}
.wk-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.wk-logo{
  width:26px;height:26px;border-radius:7px;object-fit:cover;
  background:rgba(255,255,255,.22);
}
.wk-tag{
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;
  padding:3px 8px;border-radius:999px;
  background:rgba(0,0,0,.22);
}
.wk-hand{
  display:block;
  font-family:var(--display);font-size:17px;line-height:1.08;
  letter-spacing:-.02em;font-weight:800;margin:0 0 6px;
}
.wk-big{
  display:block;
  font-family:var(--display);font-size:34px;line-height:.95;
  letter-spacing:-.04em;font-weight:800;font-variant-numeric:tabular-nums;
}
.wk-sub{
  display:block;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;opacity:.85;margin:4px 0 0;
}
/* the back of the card — the numbers, shown when it's turned round */
.wk-bk{
  background:linear-gradient(165deg,#15151A,#0E0E12);
  border:1px solid rgba(255,255,255,.16);
  transform:rotateY(180deg);
  justify-content:center;gap:9px;
}
.wb-k{
  display:block;
  font-family:var(--mono);font-size:9px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--glow,var(--accent));margin:0;
}
.wb-n{display:grid;gap:7px}
.wb-n b{
  font-family:var(--display);font-size:21px;letter-spacing:-.03em;
  display:block;line-height:1;color:#fff;
}
.wb-n span{font-size:10.5px;color:rgba(255,255,255,.66);line-height:1.3}
.wb-go{
  display:block;
  font-family:var(--mono);font-size:10px;letter-spacing:.1em;
  color:var(--glow,var(--accent));margin-top:2px;
}

/* hover lifts a card and lights it — never a layout change, so the
   pointer can't slide off and start the hover flickering (see §10 of
   context.md; this has bitten twice) */
.box3 .wk:hover,.box3 .wk:focus-visible{
  box-shadow:0 26px 52px -16px rgba(0,0,0,.85),
             0 0 0 1px var(--glow,#fff),
             0 0 34px -6px var(--glow,#fff);
  filter:brightness(1.07);
  outline:none;
}

/* ---- the hint and the tab row, pinned in the sticky stage ---- */
.box-hint{
  margin:14px 0 0;font-size:19px;color:var(--muted);
  opacity:0;transition:opacity .5s;
}
.box-stage.opened .box-hint{opacity:1}
.box-tabs{
  position:absolute;left:0;right:0;bottom:92px;
  padding:0 24px;pointer-events:none;
}
.tabs{
  display:flex;gap:10px;overflow-x:auto;padding:4px 0;
  scrollbar-width:none;pointer-events:auto;
}
.tabs::-webkit-scrollbar{display:none}
.tab{
  flex:0 0 auto;min-width:190px;
  display:flex;align-items:baseline;gap:11px;
  padding:10px 15px;border-radius:14px;cursor:pointer;
  background:transparent;border:1px solid transparent;
  text-align:left;font-family:var(--font);color:var(--ink);
  transition:transform .25s cubic-bezier(.2,.8,.3,1),border-color .25s,background .25s;
}
.tab:hover,.tab.on{
  transform:translateY(-3px);
  background:var(--card);border-color:var(--tint,var(--accent));
}
.tab .tnum{font-family:var(--mono);font-size:11px;font-weight:600;color:var(--tint,var(--accent))}
.tab .tt{display:grid;line-height:1.3}
.tab .tt b{font-family:var(--display);font-size:15px;letter-spacing:-.02em;font-weight:700}
.tab .tt span{font-size:11.5px;color:var(--muted)}


/* the open card, shown flat in front of the box */
.card-open{
  position:fixed;inset:0;z-index:95;
  display:none;place-items:center;padding:24px;
  background:rgba(8,8,10,.62);backdrop-filter:blur(8px);
}
.card-open.on{display:grid}
.co-panel{
  width:min(560px,100%);max-height:86svh;overflow:auto;
  background:var(--card);border:1px solid var(--line);
  border-radius:26px;padding:30px;
  box-shadow:var(--shadow);
}
.co-panel .client{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);margin:0 0 10px}
.co-panel h3{font-family:var(--display);font-size:clamp(26px,4vw,38px);line-height:1;letter-spacing:-.04em;margin:0 0 10px;font-weight:800}
.co-panel .hook{font-family:var(--display);font-size:18px;color:var(--ink-soft);margin:0 0 10px;font-weight:600}
.co-panel .summary{font-size:15px;color:var(--muted);margin:0 0 22px;line-height:1.55}
.card-metrics{display:flex;gap:26px;margin-bottom:22px;flex-wrap:wrap}
.card-metrics .big{font-family:var(--display);font-size:38px;letter-spacing:-.04em;font-weight:800;line-height:1;color:var(--accent);font-variant-numeric:tabular-nums}
.card-metrics .lbl{font-size:12px;color:var(--muted);margin-top:6px;display:block;line-height:1.4}
.chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:22px}
.chip{font-family:var(--mono);font-size:10.5px;letter-spacing:.05em;padding:5px 10px;border-radius:999px;background:var(--card-2);border:1px solid var(--line);color:var(--ink-soft)}
.co-actions{display:flex;gap:10px;flex-wrap:wrap}

/* =========================================================
   SITES RAIL
   ========================================================= */
.sites-head{display:flex;justify-content:space-between;align-items:flex-end;gap:32px;margin-bottom:44px;flex-wrap:wrap}
.sites-blurb{font-family:var(--display);font-size:clamp(22px,2.9vw,36px);line-height:1.12;letter-spacing:-.035em;max-width:22ch;margin:0;font-weight:700}
.rail-wrap{position:relative;max-width:var(--wrap);margin:0 auto;padding:0 24px}
.rail{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(300px,320px);gap:20px;overflow-x:auto;padding-bottom:18px;scroll-snap-type:x mandatory;scroll-behavior:smooth;scrollbar-width:none}
.rail::-webkit-scrollbar{display:none}
.sitecard{
  scroll-snap-align:start;
  background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;
  transition:transform .18s ease-out,border-color .3s;
  transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(var(--ty,0px));
  transform-style:preserve-3d;
}
.sitecard:hover{border-color:var(--line-2);--ty:-6px}
.sitecard .shot{
  height:180px;position:relative;
  background:radial-gradient(400px 160px at 30% 0%,var(--accent-soft),transparent 70%),linear-gradient(140deg,var(--card-2),var(--bg-2));
  border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:center;
}
.sitecard .shot .dom{font-family:var(--mono);font-size:13px;color:var(--ink-soft)}
.sitecard .tag{
  position:absolute;top:12px;left:12px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  background:var(--accent);color:var(--accent-ink);padding:4px 9px;border-radius:999px;font-weight:600;
}
.sitecard .body{padding:18px 20px}
.sitecard h4{font-family:var(--display);font-size:19px;letter-spacing:-.025em;margin:0 0 4px;font-weight:700}
.sitecard p{font-size:12.5px;color:var(--muted);margin:0}
.rail-nav{display:flex;gap:10px;margin-top:22px;justify-content:flex-end}
.rail-btn{width:42px;height:42px;border-radius:50%;background:var(--card);border:1px solid var(--line);color:var(--ink);cursor:pointer;font-size:15px;transition:transform .2s,background .2s,border-color .2s}
.rail-btn:hover{transform:translateY(-2px);border-color:var(--accent);background:var(--card-2)}

/* =========================================================
   APP
   ========================================================= */
.app-body{font-family:var(--display);font-size:clamp(22px,3.1vw,38px);line-height:1.14;letter-spacing:-.035em;max-width:24ch;margin:0 0 10px;font-weight:700}
.roles{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin-bottom:48px}
.role{background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);padding:16px 18px;transition:transform .25s,border-color .25s}
.role:hover{transform:translateY(-3px);border-color:var(--accent)}
.role b{display:block;font-family:var(--display);font-size:16px;letter-spacing:-.02em;margin-bottom:3px;font-weight:700}
.role span{font-size:12.5px;color:var(--muted)}
.appstats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:20px;margin-bottom:40px}
.astat{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:26px;text-align:center}
.astat b{display:block;font-family:var(--display);font-size:clamp(30px,4.4vw,50px);letter-spacing:-.04em;line-height:1;color:var(--accent);font-weight:800;font-variant-numeric:tabular-nums}
.astat span{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.16em;color:var(--muted);margin-top:10px}
.app-actions{display:flex;gap:12px;flex-wrap:wrap}

/* =========================================================
   STACK — the crate
   ========================================================= */
.crate-stage{position:relative;min-height:420px;display:flex;align-items:center;justify-content:center;margin:20px 0 0}

.crate{
  position:absolute;
  width:260px;height:210px;
  background:none;border:0;padding:0;cursor:pointer;
  transform-style:preserve-3d;
  transition:opacity .5s ease,transform .6s cubic-bezier(.2,.8,.3,1);
  font-family:var(--font);
}
.crate-body{
  position:absolute;inset:40px 0 0;
  background:linear-gradient(160deg,var(--card-2),var(--card));
  border:1px solid var(--line-2);border-radius:10px;
  display:block;overflow:hidden;
  box-shadow:var(--shadow);
}
.crate-slats{
  position:absolute;inset:0;
  background:repeating-linear-gradient(90deg,transparent 0 46px,var(--line) 46px 47px);
  opacity:.8;
}
.crate-stamp{
  position:absolute;left:50%;top:54%;transform:translate(-50%,-50%) rotate(-8deg);
  font-family:var(--mono);font-size:10px;letter-spacing:.2em;
  color:var(--accent);border:2px solid var(--accent);
  padding:6px 12px;border-radius:5px;opacity:.75;white-space:nowrap;
}
.crate-lid{
  position:absolute;left:-4px;right:-4px;top:16px;height:46px;
  background:linear-gradient(160deg,var(--card-2),var(--card));
  border:1px solid var(--line-2);border-radius:8px;
  transform-origin:50% 100%;
  transition:transform .75s cubic-bezier(.6,-0.25,.3,1.3);
  z-index:3;display:block;
}
.crate-tape{
  position:absolute;left:50%;top:-14px;width:54px;height:26px;
  transform:translateX(-50%) rotate(-3deg);
  background:var(--accent-soft);border:1px dashed var(--accent);border-radius:3px;
}
.crate-label{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;align-items:center;gap:1px;white-space:nowrap;
}
.crate-file{font-family:var(--mono);font-size:12px;color:var(--ink)}
.crate-size{font-family:var(--mono);font-size:9px;letter-spacing:.16em;color:var(--muted)}
.crate-cta{
  position:absolute;left:50%;bottom:-46px;transform:translateX(-50%) rotate(-2deg);
  color:var(--muted);font-size:20px;white-space:nowrap;
}
.crate:hover{transform:translateY(-6px)}
.crate:hover .crate-lid{transform:rotateX(-14deg)}

.crate-stage.open .crate{opacity:0;transform:translateY(26px) scale(.86);pointer-events:none}
.crate-stage.open .crate-lid{transform:rotateX(-128deg)}

/* a grid of real logos, the way an app drawer looks */
.toolgrid{
  display:grid;gap:clamp(14px,2.4vw,26px) clamp(10px,2vw,22px);
  grid-template-columns:repeat(auto-fit,minmax(86px,1fr));
  width:100%;min-width:0;
  max-width:760px;margin:0 auto;
  opacity:0;pointer-events:none;
}
.crate-stage.open .toolgrid{opacity:1;pointer-events:auto}
.tool{
  position:relative;
  display:flex;flex-direction:column;align-items:center;gap:9px;
  cursor:default;background:none;border:0;padding:0;
  font-family:var(--font);color:var(--ink);
  opacity:0;transform:translateY(32px) scale(.78);
  transition:opacity .45s cubic-bezier(.2,.8,.3,1),transform .55s cubic-bezier(.2,1.25,.3,1);
  transition-delay:var(--d,0ms);
}
.crate-stage.open .tool{opacity:1;transform:none}
.tool-ic{
  width:clamp(52px,7vw,62px);aspect-ratio:1;border-radius:16px;
  display:grid;place-items:center;
  background:color-mix(in srgb,var(--tc,#888) 15%,var(--card));
  border:1px solid color-mix(in srgb,var(--tc,#888) 30%,transparent);
  transition:transform .28s cubic-bezier(.2,.9,.3,1.3),box-shadow .28s,border-color .28s;
}
.tool-ic svg{width:56%;height:56%;display:block}
.tool-ic b{font-family:var(--display);font-size:19px;font-weight:800;color:var(--tc,var(--ink))}
.tool:hover .tool-ic,.tool:focus-visible .tool-ic{
  transform:translateY(-6px) scale(1.07);
  border-color:var(--tc,var(--accent));
  box-shadow:0 14px 26px -12px color-mix(in srgb,var(--tc,#888) 70%,transparent);
}
.tool-name{font-size:11.5px;font-weight:600;color:var(--muted);text-align:center;transition:color .25s}
.tool:hover .tool-name{color:var(--ink)}
.tool .tip{
  position:absolute;bottom:calc(100% + 8px);left:50%;
  transform:translateX(-50%) translateY(6px);
  background:var(--ink);color:var(--bg);
  font-size:12px;font-weight:500;line-height:1.35;
  width:max-content;max-width:190px;text-align:center;
  padding:8px 12px;border-radius:10px;
  opacity:0;pointer-events:none;
  transition:opacity .22s,transform .22s;z-index:8;
}
.tool .tip b{display:block;font-weight:700;margin-bottom:2px}
.tool:hover .tip,.tool:focus .tip{opacity:1;transform:translateX(-50%) translateY(0)}

/* =========================================================
   PROCESS
   ========================================================= */
/* a line that snakes across, nodes alternating above and below */
.proc-line{
  position:relative;
  max-width:var(--wrap);margin:3vh auto 0;padding:0 24px;
  height:clamp(330px,52vh,460px);
}
.proc-svg{position:absolute;inset:0 24px;width:calc(100% - 48px);height:100%}
.ln-bg{fill:none;stroke:var(--line-2);stroke-width:2;stroke-dasharray:3 9;stroke-linecap:round}
.ln-fg{
  fill:none;stroke:var(--ink);stroke-width:3;
  stroke-linecap:round;stroke-linejoin:round;
  transition:stroke-dashoffset 1.9s cubic-bezier(.35,.9,.3,1);
}
.pnodes{position:absolute;inset:0 24px}
/* the dot sits exactly on the line; the text hangs clear of it —
   downward for nodes under the line, upward for nodes over it */
.pnode{
  position:absolute;width:172px;
  transform:translate(-50%,0);
  padding-top:30px;
  text-align:center;
  opacity:0;
  transition:opacity .55s ease var(--d,0ms);
}
.proc-line.in .pnode{opacity:1}
.pnode.up{transform:translate(-50%,-100%);padding:0 0 30px}

.pnode .dot{
  position:absolute;left:50%;top:0;
  width:17px;height:17px;border-radius:50%;
  transform:translate(-50%,-50%);
  background:var(--c);
  box-shadow:0 0 0 4px var(--sec-bg),0 0 0 5.5px var(--c),0 6px 14px -4px var(--c);
}
.pnode.up .dot{top:100%}

.pnode b{
  display:block;font-family:var(--display);font-size:16px;
  letter-spacing:-.02em;font-weight:700;margin:0;
}
.pnode > span:last-child{display:block;font-size:12.5px;color:var(--muted);margin-top:5px;line-height:1.4}

/* =========================================================
   LIFE — the pinboard
   ========================================================= */
.board-wrap{max-width:var(--wrap);margin:0 auto;padding:0 24px}
.board{
  position:relative;height:640px;border-radius:24px;overflow:hidden;
  background:
    radial-gradient(circle at 20% 25%,rgba(0,0,0,.14) 0 2px,transparent 3px),
    radial-gradient(circle at 70% 60%,rgba(0,0,0,.12) 0 2px,transparent 3px),
    radial-gradient(circle at 45% 80%,rgba(255,255,255,.05) 0 2px,transparent 3px),
    linear-gradient(150deg,var(--cork-2),var(--cork));
  background-size:37px 37px,53px 53px,43px 43px,100% 100%;
  border:10px solid color-mix(in srgb,var(--cork) 60%,#000);
  box-shadow:inset 0 0 90px rgba(0,0,0,.45),var(--shadow);
  touch-action:none;
}
.board-grain{
  position:absolute;inset:0;pointer-events:none;
  background:repeating-linear-gradient(42deg,rgba(0,0,0,.05) 0 2px,transparent 2px 5px);
  mix-blend-mode:multiply;
}
.board-items{position:absolute;inset:0}

.bitem{
  position:absolute;
  transform:rotate(var(--rot,0deg));
  cursor:grab;user-select:none;touch-action:none;
  transition:box-shadow .25s,filter .25s;
  filter:drop-shadow(0 10px 18px rgba(0,0,0,.45));
}
.bitem:active,.bitem.dragging{cursor:grabbing}
.bitem.dragging{filter:drop-shadow(0 22px 34px rgba(0,0,0,.6));z-index:50!important}
.bitem::before{  /* the push pin */
  content:"";position:absolute;left:50%;top:-9px;transform:translateX(-50%);
  width:16px;height:16px;border-radius:50%;
  background:radial-gradient(circle at 35% 30%,#ff8f7a,#d4432c 70%,#9e2d1b);
  box-shadow:0 3px 5px rgba(0,0,0,.5);z-index:4;
}
.bitem .rm{
  position:absolute;top:-10px;right:-10px;
  width:24px;height:24px;border-radius:50%;
  background:var(--ink);color:var(--bg);
  border:0;cursor:pointer;font-size:13px;line-height:1;
  display:grid;place-items:center;
  opacity:0;transform:scale(.6);
  transition:opacity .2s,transform .2s;z-index:6;
}
.bitem:hover .rm{opacity:1;transform:scale(1)}

.bnote{
  width:235px;padding:18px 18px 16px;
  background:linear-gradient(170deg,#FFF6C8,#FFECA6);
  color:#2B2415;border-radius:3px;
}
.bnote h4{font-family:var(--display);font-size:15px;margin:0 0 10px;font-weight:700;letter-spacing:-.01em}
.bnote li{font-size:13px;line-height:1.5;padding-left:14px;position:relative}
.bnote li::before{content:"✦";position:absolute;left:0;color:#B88A1C;font-size:10px}

.bpolaroid{width:190px;padding:11px 11px 0;background:#FBFAF6;border-radius:3px}
.bpolaroid .ph{
  height:150px;border-radius:2px;
  background:repeating-linear-gradient(45deg,#E6E2D8 0 9px,#DCD7CB 9px 18px);
  display:grid;place-items:center;
}
.bpolaroid .ph span{font-family:var(--mono);font-size:9px;letter-spacing:.1em;color:#9A958A}
.bpolaroid .cap{font-family:var(--hand);font-size:19px;color:#3A362C;text-align:center;padding:7px 4px 11px}

.bticket{
  width:290px;padding:16px 18px;border-radius:8px;
  background:linear-gradient(135deg,#FFFDF7,#F3EEE2);color:#23221E;
  position:relative;
}
.bticket::before,.bticket::after{
  content:"";position:absolute;width:20px;height:20px;border-radius:50%;
  background:var(--cork);top:50%;transform:translateY(-50%);
}
.bticket::before{left:-10px}
.bticket::after{right:-10px}
.bticket .air{font-family:var(--display);font-size:14px;font-weight:800;margin-bottom:12px;display:flex;justify-content:space-between}
.bticket .air small{font-family:var(--mono);font-size:8px;letter-spacing:.18em;color:#8A857A;font-weight:400}
.bticket .rt{display:flex;align-items:center;gap:14px;margin-bottom:12px}
.bticket .cd{font-family:var(--display);font-size:28px;font-weight:800;letter-spacing:-.04em;line-height:1}
.bticket .ct{font-size:10px;color:#8A857A}
.bticket .ln{flex:1;height:1px;background:#C9C3B4;position:relative}
.bticket .ln::after{content:"✈";position:absolute;right:-5px;top:50%;transform:translateY(-50%);font-size:13px;color:#C8902E;background:#F7F3E8;padding:0 4px}
.bticket .mt2{display:flex;gap:22px}
.bticket .mt2 span{display:block;font-family:var(--mono);font-size:8px;letter-spacing:.16em;color:#8A857A}
.bticket .mt2 b{font-size:12px}

.btape{
  padding:11px 18px;background:rgba(255,255,255,.9);color:#23221E;
  font-family:var(--hand);font-size:21px;border-radius:2px;white-space:nowrap;
}
.btape::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.06);
}

.board-bar{display:flex;justify-content:space-between;align-items:center;gap:20px;margin-top:20px;flex-wrap:wrap}

/* =========================================================
   THE WALL — sticky notes on a paper wall
   ========================================================= */
.notes{
  position:relative;padding:120px 0;
  --sec-bg:#DDBD8B;
  background:linear-gradient(#DDBD8B,#C99F66);
  color:#13233A;
}
:root[data-theme="day"] .notes{--sec-bg:#E8CFA0;background:linear-gradient(#E8CFA0,#D5B37C)}
.notes .kicker{color:rgba(19,35,58,.55)}
.notes .h2{color:#13233A}
.notes .lead{color:rgba(19,35,58,.68)}
.wall-actions{display:flex;gap:12px;justify-content:center;margin-bottom:10px}
.notes .btn.primary{background:#13233A;color:#F7EFE0;border-color:transparent}

.nw-rows{display:grid;gap:0;margin-top:6vh}
.nw-row{
  overflow:hidden;padding:30px 0 56px;margin-bottom:-20px;
  mask:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
}
.nw-track{display:flex;gap:24px;width:max-content;animation:nwscroll var(--dur,70s) linear infinite}
.nw-row.rev .nw-track{animation-direction:reverse}
.nw-row:hover .nw-track,.nw-row:focus-within .nw-track{animation-play-state:paused}
@keyframes nwscroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}

.nw-card{
  position:relative;flex:0 0 auto;
  width:290px;min-height:170px;box-sizing:border-box;
  padding:26px 20px 18px;
  background:var(--nc,#FFE98A);color:#13233A;
  border:0;text-align:left;font-family:var(--font);
  border-radius:4px 4px 18px 4px;
  transform:rotate(var(--r,0deg));
  box-shadow:0 18px 28px -18px rgba(60,30,0,.5),0 2px 5px rgba(60,30,0,.18);
  transition:transform .3s cubic-bezier(.2,.8,.3,1),box-shadow .3s;
  display:flex;flex-direction:column;justify-content:space-between;gap:16px;
}
.nw-card:hover{transform:rotate(0deg) translateY(-6px) scale(1.02);box-shadow:0 26px 36px -18px rgba(60,30,0,.55)}
/* the strip of tape holding it up */
.nw-card::before{
  content:"";position:absolute;left:50%;top:-11px;
  width:70px;height:22px;margin-left:-35px;
  background:rgba(255,255,255,.6);
  transform:rotate(-3deg);
  box-shadow:0 1px 2px rgba(0,0,0,.06);
}
.nw-card p{margin:0;font-size:14.5px;line-height:1.5}
.nw-card .who{display:flex;align-items:center;gap:10px}
.nw-card .av{
  width:30px;height:30px;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;
  background:rgba(19,35,58,.14);color:#13233A;
  font-family:var(--display);font-size:13px;font-weight:800;
}
.nw-card .who b{display:block;font-size:13px;font-weight:700}
.nw-card .who span{display:block;font-size:11px;color:rgba(19,35,58,.6)}
/* nothing on the wall yet */
.notes.empty .nw-rows{display:flex;justify-content:center}
.notes.empty .nw-row{overflow:visible;mask:none;padding:30px 0 20px}
.notes.empty .nw-track{animation:none;width:auto;gap:20px;align-items:flex-start}
.nw-empty{
  flex:0 0 auto;max-width:320px;padding:4px 10px 0;
  text-align:left;color:#13233A;
}
.nw-empty h3{font-family:var(--display);font-size:24px;letter-spacing:-.025em;margin:0 0 6px;font-weight:800}
.nw-empty p{margin:0;font-size:14.5px;color:rgba(19,35,58,.68)}

.nw-card.nw-ghost{
  background:rgba(255,255,255,.4);
  border:2px dashed rgba(19,35,58,.3);
  cursor:pointer;align-items:flex-start;justify-content:center;
}
.nw-card.nw-ghost span{font-weight:700;font-size:13.5px;text-decoration:underline}

/* =========================================================
   CONTACT — the keyboard
   ========================================================= */
.hello{padding:130px 0 190px;position:relative;overflow:hidden;isolation:isolate}
.hello .wrap{position:relative;z-index:3}

/* blueprint grid */
.hello-grid{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    linear-gradient(var(--line) 1px,transparent 1px) 0 0/58px 58px,
    linear-gradient(90deg,var(--line) 1px,transparent 1px) 0 0/58px 58px;
  mask:radial-gradient(ellipse 80% 70% at 50% 45%,#000 30%,transparent 78%);
}
/* starry night over it */
.hello-stars{position:absolute;inset:0;z-index:1;pointer-events:none}
.hello-stars i{
  position:absolute;border-radius:50%;background:#fff;
  animation:twinkle var(--dur) ease-in-out infinite alternate;
}
:root[data-theme="day"] .hello-stars{opacity:.22}
.hello-glow{
  position:absolute;left:50%;top:38%;z-index:2;
  width:min(900px,120%);aspect-ratio:2/1;transform:translate(-50%,-50%);
  pointer-events:none;
  background:radial-gradient(ellipse at center,color-mix(in srgb,var(--accent) 16%,transparent),transparent 68%);
}
.hello .h2{max-width:16ch;margin-left:auto;margin-right:auto}
.keys-mat{
  margin:52px auto 60px;max-width:860px;
  padding:30px 24px 34px;border-radius:26px;
  background:var(--card);border:1px solid var(--line);
  box-shadow:var(--shadow);
}
.keys-hint{
  display:flex;align-items:center;justify-content:center;gap:10px;flex-wrap:wrap;
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);margin:0 0 28px;
}
.kbd-row{display:inline-flex;gap:5px}
.kbd{
  display:inline-grid;place-items:center;
  min-width:20px;padding:3px 6px;border-radius:5px;
  background:var(--card-2);border:1px solid var(--line-2);
  border-bottom-width:2px;
  font-family:var(--mono);font-size:10px;color:var(--ink-soft);
}

.keys{display:flex;justify-content:center;gap:clamp(12px,3vw,30px);flex-wrap:wrap}
/* the column is exactly as wide as its keycap, so the handwritten note
   underneath can't push the row into wrapping */
.kw{display:flex;flex-direction:column;align-items:center;gap:10px;width:clamp(78px,11vw,112px)}
.key{
  position:relative;display:block;
  width:100%;aspect-ratio:1;
  border-radius:16px;
  background:var(--kd,#999);
  padding-bottom:7px;
  transition:transform .13s cubic-bezier(.2,.8,.3,1),padding-bottom .13s;
  cursor:pointer;
}
.key .cap{
  display:grid;place-items:center;gap:6px;
  width:100%;height:100%;border-radius:14px;
  background:var(--kc,#bbb);
  box-shadow:inset 0 2px 0 rgba(255,255,255,.3),inset 0 -2px 0 rgba(0,0,0,.14);
  color:#fff;
}
.key i{font-family:var(--display);font-style:normal;font-size:18px;font-weight:800;line-height:1}
.key svg{width:26px;height:26px;display:block}
.key:hover{transform:translateY(-3px)}
.key:active,.key.down{transform:translateY(4px);padding-bottom:1px}
.key-label{font-size:12.5px;font-weight:600;color:var(--ink-soft)}
/* allowed to spill a little past its column without affecting layout,
   but not so far that neighbouring notes run into each other */
.knote{font-family:var(--hand);font-size:17px;color:var(--muted);margin:0;text-align:center;width:112%;margin-inline:-6%;line-height:1.25}

.colophon{text-align:center;font-family:var(--mono);font-size:11px;letter-spacing:.1em;color:var(--muted);margin:0}

/* =========================================================
   DOCK
   ========================================================= */
.dock{
  position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:60;
  display:flex;align-items:center;gap:8px;padding:7px;border-radius:999px;
  background:rgba(18,18,22,.72);backdrop-filter:blur(20px) saturate(140%);
  border:1px solid rgba(255,255,255,.12);
  box-shadow:0 18px 50px -18px rgba(0,0,0,.7);
  max-width:calc(100vw - 32px);
}
:root[data-theme="day"] .dock{background:rgba(255,255,255,.8);border-color:rgba(0,0,0,.09);box-shadow:0 18px 50px -22px rgba(20,21,26,.28)}
.dock-inner{display:flex;gap:2px;overflow-x:auto;scrollbar-width:none}
.dock-inner::-webkit-scrollbar{display:none}
.dock a{padding:9px 16px;border-radius:999px;font-size:13.5px;font-weight:600;white-space:nowrap;color:#D8D4CB;transition:background .2s,color .2s}
:root[data-theme="day"] .dock a{color:#3C3E45}
.dock a:hover,.dock a.on{background:rgba(255,255,255,.1);color:#fff}
:root[data-theme="day"] .dock a:hover,:root[data-theme="day"] .dock a.on{background:rgba(0,0,0,.06);color:#14151A}
.dock-cta{background:var(--accent)!important;color:var(--accent-ink)!important;padding:9px 18px!important}

/* =========================================================
   MOTION
   ========================================================= */
[data-reveal]{opacity:0;transform:translateY(26px);transition:opacity .7s cubic-bezier(.2,.8,.3,1),transform .7s cubic-bezier(.2,.8,.3,1)}
[data-reveal].in{opacity:1;transform:none}

.progress{
  position:fixed;top:0;left:0;height:2px;width:0;z-index:70;
  background:linear-gradient(90deg,var(--accent),color-mix(in srgb,var(--accent) 50%,#fff));
  box-shadow:0 0 14px var(--accent-soft);transition:width .08s linear;
}

.line{display:block;overflow:hidden;padding-bottom:.12em;margin-bottom:-.12em}
.line .w{
  display:inline-block;
  transform:translateY(110%) rotate(2deg);opacity:0;
  transition:transform .85s cubic-bezier(.16,1,.3,1),opacity .6s ease;
  transition-delay:var(--d,0ms);will-change:transform;
}
.split.in .line .w{transform:none;opacity:1}
.split .line mark.hl,.split .line s.strike{opacity:0;transition:opacity .5s ease var(--d,0ms)}
.split.in .line mark.hl,.split.in .line s.strike{opacity:1}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width:980px){
  .hero-badges{display:none}
  .box-track{height:260vh}
  .keys{gap:14px}
}

@media (max-width:680px), (max-width:980px) and (max-height:500px) and (pointer:coarse){
  body{font-size:16px}
  .section{padding:84px 0}
  .wrap,.deck-wrap,.rail-wrap,.board-wrap{padding:0 16px}
  .topbar{
    padding:calc(12px + env(safe-area-inset-top,0px)) max(12px,env(safe-area-inset-right,0px)) 12px max(12px,env(safe-area-inset-left,0px));
  }
  .topbar-right{display:flex;align-items:center;gap:6px}
  .topbar-pill{font-size:11px;gap:6px;min-height:40px;padding:7px 10px}
  /* the phone crop is portrait, so it wants the full height back */
  .hero{height:100svh;min-height:560px}
  .hero-inner{padding:0 16px;align-items:flex-end;padding-bottom:190px}
  .hero-copy{max-width:100%}
  .pin{font-size:11px;padding:6px 10px}
  .hero-pins{bottom:auto;height:46%}
  .scroll-cue{bottom:calc(96px + env(safe-area-inset-bottom,0px));font-size:10px;white-space:nowrap}
  .intro-body{max-width:100%}

  /* journey — buttons, not scroll, on a phone */
  .jscroll{display:none}
  .jmap{width:calc(100% - 32px);margin-inline:auto;height:clamp(440px,76svh,620px);border-radius:20px}
  .jdetail{left:10px;right:10px;bottom:84px;width:auto;max-height:calc(100% - 170px);overflow:auto;border-radius:16px}
  .jd-id{min-width:0}
  .jd-id b,.jd-id span{overflow-wrap:anywhere}
  .jd-count{flex-shrink:0}
  .jd-body{padding:14px}
  .jd-text{font-size:13.5px;-webkit-line-clamp:3}
  .jctl{bottom:14px;gap:8px}
  .jbtn.round{width:44px;height:44px}
  .jbtn.wide{min-height:44px;padding:10px 15px;font-size:13px}
  .jd-more{min-height:44px}
  .compass{width:48px;height:48px;right:12px;top:12px}
  .jpin-tag{font-size:12px;padding:6px 11px 6px 14px}

  /* Keep the same opening sequence on phones, with a shorter scroll
     track and full-size touch controls separate from the 3D cards. */
  .box-track{height:240svh}
  .box-fit{top:60%}
  .work-head{top:calc(74px + env(safe-area-inset-top,0px));padding:0 16px}
  .work-head .h2{font-size:30px;margin:6px 0 8px}
  .work-head .lead{font-size:13px;max-width:27ch}
  .box-hint{opacity:1;font-size:15px;margin-top:10px}
  .box-tabs{bottom:calc(84px + env(safe-area-inset-bottom,0px));padding:0 16px}
  .box-tabs .tabs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;overflow:visible}
  .box-tabs .tab{min-width:0;min-height:60px;padding:8px 6px;gap:4px;align-items:center;background:var(--card);border-color:var(--line)}
  .box-tabs .tab .tnum{font-size:9px}
  .box-tabs .tab .tt b{font-size:11px;overflow-wrap:anywhere}
  .box-tabs .tab .tt span{display:none}

  /* the process line goes vertical */
  .proc-line{height:auto;padding:0 16px}
  .proc-svg{display:none}
  .pnodes{position:static;display:grid;gap:26px}
  .pnode,.pnode.up{
    position:static;width:auto;transform:none;opacity:1;padding:0;
    text-align:left;display:grid;grid-template-columns:auto 1fr;
    gap:0 14px;align-items:start;
  }
  .pnode .dot,.pnode.up .dot{position:static;grid-row:span 2;transform:none;margin:4px 0 0}
  .pnode > span:last-child{margin:2px 0 0}

  .crate-stage{min-height:360px}
  .toolgrid{grid-template-columns:repeat(3,minmax(0,1fr));gap:24px 12px}
  .tool{min-width:0}
  .tool-name{overflow-wrap:anywhere}
  /* Edge-column tooltips open inward instead of widening the document. */
  .tool:nth-child(3n+1) .tip{left:0;transform:translateY(6px)}
  .tool:nth-child(3n) .tip{left:auto;right:0;transform:translateY(6px)}
  .tool:nth-child(3n+1):hover .tip,.tool:nth-child(3n+1):focus .tip,
  .tool:nth-child(3n):hover .tip,.tool:nth-child(3n):focus .tip{transform:translateY(0)}
  /* Phones get readable cards and natural vertical scrolling. Desktop
     positions remain saved and are used again on a wide screen. */
  .board{height:auto;padding:30px 18px;touch-action:pan-y}
  .board-items{position:relative;display:grid;justify-items:center;gap:36px}
  .bitem{
    position:relative;left:auto!important;top:auto!important;
    width:min(100%,290px);cursor:auto;touch-action:pan-y;
  }
  .bnote,.bticket{width:100%}
  .bpolaroid{width:min(190px,100%);margin-inline:auto}
  .btape{white-space:normal;text-align:center;overflow-wrap:anywhere}
  .bitem .rm{opacity:1;transform:none;width:36px;height:36px;top:-18px;right:-12px}
  .board-bar .btn{min-height:44px}
  .steps li{grid-template-columns:44px 1fr;gap:14px;row-gap:4px;padding:20px 4px}
  .steps li p{grid-column:2}
  .nw-card{width:240px;min-height:150px;padding:24px 16px 14px}
  .notes{padding:84px 0}
  .notes.empty .nw-rows{display:block;padding:0 16px;margin-top:32px}
  .notes.empty .nw-track{width:100%;flex-direction:column;align-items:center;gap:28px}
  .notes.empty .nw-row.rev{display:none}
  .nw-empty{text-align:center;max-width:100%}
  .hello{padding:90px 0 150px}
  .keys-mat{padding:22px 14px 26px}
  .keys{gap:10px}
  .key{width:clamp(58px,17vw,80px);border-radius:13px}
  .key .cap{border-radius:11px}
  .key i{font-size:15px}
  .key svg{width:20px;height:20px}
  .key-label{font-size:11px}
  .knote{display:none}
  .colophon{overflow-wrap:anywhere}
  .sites-head{flex-direction:column;align-items:flex-start}
  .rail{grid-auto-columns:min(300px,100%)}
  .dock{bottom:calc(14px + env(safe-area-inset-bottom,0px));padding:6px}
  .dock a{padding:8px 11px;font-size:12.5px}
  .dock-cta{display:none}
  .card-open{padding:16px}
  .co-panel{padding:24px;max-height:calc(100svh - 32px - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px))}
  .co-actions .btn{min-height:44px;white-space:normal}
}

@media (max-width:360px){
  .hero-title{font-size:34px}
  .dock a{font-size:11.5px;padding:10px 8px}
}

/* Short portrait phones still need space between the photo pin, copy,
   scroll cue and dock. Do not make the image taller than the screen. */
@media (max-width:680px) and (max-height:740px){
  .hero-inner{padding-bottom:calc(114px + env(safe-area-inset-bottom,0px))}
  .hero-title{font-size:32px;margin-bottom:12px}
  .hero-kicker{font-size:10px;padding:5px 10px;margin-bottom:10px}
  .hero-sub{font-size:13px;line-height:1.45}
  .scroll-cue{bottom:calc(76px + env(safe-area-inset-bottom,0px));font-size:9px;padding:7px 12px}
}

@media (orientation:landscape) and (max-width:980px) and (max-height:500px) and (pointer:coarse){
  .hero{height:100svh;min-height:100svh}
  .hero-inner{align-items:flex-start;justify-content:flex-end;padding:76px 24px 80px}
  .hero-copy{max-width:50%}
  .hero-title{font-size:32px;margin-bottom:12px}
  .hero-kicker{margin-bottom:12px;font-size:10px}
  .hero-sub{font-size:13px;line-height:1.45}
  .scroll-cue{bottom:76px;left:auto;right:24px;transform:none;font-size:9px;padding:6px 12px}
  .jmap{height:440px}
  .jdetail{width:min(360px,48%);right:auto}
  .toolgrid{max-width:520px}
  .work-head{left:max(16px,env(safe-area-inset-left,0px));right:auto;top:70px;width:38%;padding:0;text-align:left}
  .work-head .kicker,.work-head .lead,.box-hint{display:none}
  .work-head .h2{font-size:24px;margin:0}
  .box-fit{left:72%;top:60%}
  .box-tabs{left:max(16px,env(safe-area-inset-left,0px));right:auto;top:108px;bottom:auto;width:38%;padding:0}
  .box-tabs .tabs{grid-template-columns:1fr;gap:4px}
  .box-tabs .tab{min-height:42px;padding:8px 10px;gap:10px}
  .box-tabs .tab .tt b{font-size:12px}
}

@media (orientation:landscape) and (max-width:680px) and (max-height:500px) and (pointer:coarse){
  .hero-copy{max-width:55%}
  .hero-title{font-size:30px}
  .hero-kicker{margin-bottom:8px}
  .hero-sub{font-size:12px}
}

@media (orientation:landscape) and (max-height:360px) and (pointer:coarse){
  .scroll-cue{display:none}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  html{scroll-behavior:auto}
  [data-reveal]{opacity:1!important;transform:none!important}
  .line .w{opacity:1!important;transform:none!important}
  .line{overflow:visible}
  .hero-photo img{animation:none;transform:none}
  /* the crate is decorative: show the tools outright */
  .crate{display:none}
  .tools,.crate-stage.open .tools{opacity:1!important;pointer-events:auto!important}
  .tool{opacity:1!important;transform:none!important}
  .crate-stage{min-height:0}
  /* The box opens on scroll here too, by choice. A box opening and
     cards coming out of it IS the section, not decoration, so it
     keeps a real (shorter) swing instead of snapping open.
     NOTE: never put `transform:none` on .wk — the card's transform is
     what stands it up inside the box, so clearing it drops the card
     flat on the floor. Hover changes only shadow and filter. */
  .box-lid{transition-duration:.6s!important}
  .box3 .wk{
    transition-property:transform,box-shadow,filter!important;
    transition-duration:.5s!important;
  }
  .wk-ft,.wk-bk{
    transition-property:clip-path,opacity!important;
    transition-duration:.5s,.01s!important;
    transition-delay:0s,.24s!important;
  }
  .box-hint{transition-duration:.3s!important}
  .pnode{opacity:1!important}
  .ln-fg{stroke-dashoffset:0!important}
  /* The journey is scroll-driven here too, by choice, so the camera
     keeps a short glide. Snapping between seven stops on the way down
     is harder to follow than easing between them. */
  .jworld,.jpin,.jarrow{
    transition-property:transform!important;
    transition-duration:.52s!important;
  }
  .route{
    transition-property:stroke-dashoffset!important;
    transition-duration:.52s!important;
  }
  .jdetail{transition-duration:.3s!important}
  .jctl{transition-duration:.3s!important}
  .toolgrid,.crate-stage.open .toolgrid{opacity:1!important;pointer-events:auto!important}
  .tool{opacity:1!important;transform:none!important}
  /* the stars stay — they're the background, not the animation.
     The global rule above already stops them twinkling. */
  .hello-stars i{animation:none;opacity:.5!important}
  .nw-track{animation:none;flex-wrap:wrap;width:auto;justify-content:center}
  .nw-row{mask:none;overflow:visible}
}
