/* Thereish home page: the scroll story (task 062). Loaded after site.css, home page only.

   Three layers:
   1. Static (this first part): every stop's words beside a flat picture of its screen,
      the route drawn in full. Shown without JavaScript and with reduced motion.
   2. Live (the media query below): one 3D phone on a sticky stage travels the route.
      CSS scroll-driven animations do the fades where the browser has them.
   3. /js/story.js moves the phone, the route and the kilometre counter. */

.story-page {
  --phone-shell: #1E2A3D;
  --card-glass: color-mix(in srgb, var(--bg) 90%, transparent);
  --foot-h: 64px;
}
.lvh-probe { position: fixed; left: 0; top: 0; width: 0; height: 100vh; height: 100lvh; visibility: hidden; pointer-events: none; }

/* Header and menu */
.bar {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 10px calc(clamp(12px, 3vw, 32px) + 60px) 10px clamp(16px, 4vw, 40px);
  min-height: 52px;
}
.bar .brand svg { width: 24px; height: 24px; }
.bar .wordmark { font-size: 1.4rem; }
.bar-nav ul { display: flex; gap: 18px; list-style: none; margin: 0; padding: 0; font-size: 0.9375rem; }
.bar-nav a { color: var(--text-2); text-decoration: none; font-weight: 500; }
.bar-nav a:hover { color: var(--link); text-decoration: underline; }
@media (max-width: 560px) { .bar-nav { display: none; } }

.menu { position: fixed; z-index: 60; top: calc(4px + env(safe-area-inset-top, 0px)); right: clamp(12px, 3vw, 32px); }
.menu summary {
  list-style: none; width: 44px; height: 44px; border-radius: 50%; cursor: pointer;
  display: grid; place-content: center; gap: 5px;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  box-shadow: 0 0 0 1px var(--line);
}
.menu summary::-webkit-details-marker { display: none; }
.menu summary span { display: block; width: 16px; height: 2px; border-radius: 2px; background: var(--text); }
.menu summary:focus-visible { border-radius: 50%; }
.menu nav {
  position: absolute; right: 0; top: 52px; min-width: 190px; padding: 8px;
  background: var(--bg); border-radius: 16px;
  box-shadow: 0 0 0 1px var(--line), 0 12px 30px rgba(15, 27, 46, 0.18);
}
.menu ul { list-style: none; margin: 0; padding: 0; }
.menu a { display: block; padding: 10px 14px; border-radius: 10px; color: var(--text); text-decoration: none; font-weight: 500; }
.menu a:hover { background: var(--card); }
/* One set of links at a time (task 096): wide, the header's links show, so the round
   menu is for narrow widths only. The live layer below brings it back over the hero,
   where the header is hidden. */
@media (min-width: 561px) { .menu { display: none; } }

/* ---------- 1. Static layer ---------- */
.stage, .trail, .km { display: none; }

.story { position: relative; width: min(100% - 2.5rem, var(--page)); margin-inline: auto; }
.stop { position: relative; display: grid; gap: 1.5rem 3rem; align-items: center; padding: 2.75rem 0 2.75rem 3.5rem; }
/* The route: a dotted line down the page, with every ring filled. */
.stop::before { content: ""; position: absolute; left: 1.05rem; top: 0; bottom: 0; border-left: 4px dotted var(--dot); }
.s-hero::before { top: auto; height: 3.5rem; }
.final::before { bottom: auto; height: 3.6rem; }
.marker {
  position: absolute; left: 0; top: 2.6rem; margin: 0; display: flex; align-items: center; gap: 0.6rem;
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
}
.marker svg { width: 2.4rem; height: 2.4rem; background: var(--bg); border-radius: 50%; }
.marker span { display: none; }
.s-hero .marker { top: auto; bottom: 2.4rem; }
.s-hero .marker span { display: inline; }
.s-hero { padding-block: 2.5rem 7rem; }

.hero-mark {
  display: flex; align-items: center; gap: 0.25em; margin: 0 0 0.35em;
  font-size: clamp(2.5rem, 8vw, 5rem); line-height: 1; letter-spacing: -0.025em;
}
.hero-mark svg { width: 0.9em; height: 0.9em; }
.hero-mark .wordmark { font-size: 1em; letter-spacing: inherit; }
.s-hero h1 { font-size: clamp(1.9rem, 4vw, 4.1rem); line-height: 1.05; letter-spacing: -0.02em; margin: 0; }
.s-hero .sub { margin: 18px 0 0; color: var(--text-2); max-width: 36ch; font-size: clamp(1rem, 1.4vw, 1.375rem); }
.s-hero .hint { display: none; }

.kicker { margin: 0; font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent-text); }
.copy h2 { font-size: clamp(1.75rem, 4.2vw, 4.25rem); line-height: 1.04; letter-spacing: -0.02em; margin: 0.35em 0 0.4em; }
.copy p { color: var(--text-2); margin: 0 0 0.9em; max-width: 38ch; font-size: clamp(1rem, 1.25vw, 1.25rem); }
.copy .kicker { color: var(--accent-text); font-size: 0.8125rem; }
.copy .fine { font-size: 0.875rem; color: var(--text-3); }
.km em, .splash small { font-family: var(--font-display); font-style: italic; font-weight: 600; }

.flat { margin: 0; justify-self: start; }
.flat img {
  width: min(250px, 62vw); height: auto; border-radius: 34px;
  border: 7px solid var(--phone-shell); background: var(--card);
}
@media (min-width: 52rem) {
  .stop { grid-template-columns: minmax(0, 1fr) auto; }
  .stop.r { grid-template-columns: auto minmax(0, 1fr); }
  .stop.r .flat { order: -1; }
  .flat { justify-self: center; }
}

.store { margin-top: 6px; }
.store p { margin: 0; }
.store .store-soon { font-size: 0.8125rem; color: var(--text-3); }
.store[data-live="yes"] .store-soon, .store[data-live="no"] .store-badge { display: none; }
.links { display: flex; flex-wrap: wrap; gap: 16px; margin: 20px 0 0; padding: 0; list-style: none; font-size: 0.9375rem; }

.foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px;
  padding: 0 clamp(16px, 6vw, 96px); min-height: var(--foot-h);
  border-top: 1px solid var(--line); color: var(--text-3); font-size: 0.8125rem;
}
.foot p { margin: 0; }
.foot a { color: inherit; }

/* ---------- 2. Live layer ---------- */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  .story-page { overflow-x: hidden; overflow-x: clip; }

  .bar {
    position: sticky; top: env(safe-area-inset-top, 0px); z-index: 40;
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
    opacity: 0; visibility: hidden; transition: opacity 0.25s linear, visibility 0.25s linear;
  }
  .bar.on, .bar:focus-within { opacity: 1; visibility: visible; }

  /* Wide, the round menu stands in for the header while the header is hidden (the
     hero), and goes as the header comes back: the bar's class, or the same scroll
     timeline (below). */
  @media (min-width: 561px) {
    .menu { display: block; transition: opacity 0.25s linear, visibility 0.25s linear; }
    .bar.on ~ .menu, .bar:focus-within ~ .menu { opacity: 0; visibility: hidden; }
  }

  .story { width: auto; margin: 0; }
  .stop::before, .marker, .flat { display: none; }

  /* The stage: one fixed screen that holds the phone while the day scrolls past.
     Fixed, not sticky: in Firefox a sticky box's scroll offset gets into the 3D view,
     and the phone stretches more the further down the page you are. */
  .stage {
    display: block; position: fixed; left: 0; right: 0; top: 0; z-index: 2;
    height: 100vh; height: 100svh;
    overflow: hidden; pointer-events: none;
  }
  /* The lens: the 3D view. */
  .lens {
    position: absolute; inset: 0; display: grid; place-items: center; padding-top: 52px;
    perspective: 2400px; perspective-origin: 50% 50%;
  }
  /* Laid out --k times its resting size (the largest zoom) and scaled down by story.js,
     so the screen is sharp when the phone zooms in. */
  /* --w makes the screen (the phone less 0.018 × --h of frame each side) exactly the
     captures' shape, 1000 × 2174, so object-fit: cover crops nothing. */
  .phone {
    --k: 1.75;
    --h: calc(min(64vh, 620px) * var(--k)); --h: calc(min(64svh, 620px) * var(--k));
    --w: calc(var(--h) * 0.4794); --r: calc(var(--h) * 0.098); --t: calc(var(--h) * 0.048 + 2px * var(--k));
    flex: none;
    position: relative; height: var(--h); width: var(--w);
    transform-style: preserve-3d; will-change: transform;
    opacity: 0; transition: opacity 0.3s linear;
  }
  .stage.ready .phone { opacity: 1; }
  .face { position: absolute; inset: 0; border-radius: var(--r); }
  .face, .face * { -webkit-backface-visibility: hidden; backface-visibility: hidden; }
  /* The edge: flat strips facing outwards all the way round (built in story.js), so the
     phone is solid from any angle. No blend modes, filters or backdrop-filter in here:
     they flatten the 3D in Safari. */
  .edge { position: absolute; left: 50%; top: 50%; width: 0; height: 0; transform-style: preserve-3d; }
  .wall { position: absolute; left: 0; top: 0; -webkit-backface-visibility: visible; backface-visibility: visible; }
  .wall.side-button { border-radius: 3px; }
  .front {
    transform: translateZ(calc(var(--t) / 2)); padding: calc(var(--h) * 0.006);
    background: linear-gradient(145deg, #B9C1CC, #5E6878 45%, #9AA3B1);
  }
  .bezel {
    position: absolute; inset: calc(var(--h) * 0.006); padding: calc(var(--h) * 0.012);
    border-radius: calc(var(--r) - var(--h) * 0.006); background: #05080D;
  }
  .screen {
    position: relative; width: 100%; height: 100%; overflow: hidden;
    border-radius: calc(var(--r) - var(--h) * 0.018); background: var(--bg);
  }
  .screen::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    background: linear-gradient(115deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0) 32%);
  }
  .screens { position: absolute; inset: 0; }
  .screens picture, .screens .splash { position: absolute; inset: 0; opacity: 0; transition: opacity 0.2s linear; }
  .screens .is-on { opacity: 1; }
  .screens img { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; }
  .splash {
    display: grid; place-items: center; align-content: center; gap: calc(var(--h) * 0.03);
    background: var(--bg); color: var(--text);
  }
  .splash svg { width: 62%; }
  .splash b { font-family: var(--font-display); font-weight: 600; font-size: calc(var(--h) * 0.07); letter-spacing: -0.01em; position: relative; }
  .splash b .wm-i { position: relative; }
  .splash b .wm-i::after {
    content: ""; position: absolute; width: 0.16em; height: 0.16em; border-radius: 50%;
    background: var(--dot); left: 0.12em; top: 0.2em;
  }
  .splash small { font-size: calc(var(--h) * 0.03); color: var(--dot); }
  .island {
    position: absolute; z-index: 3; top: calc(var(--h) * 0.022); left: 50%; transform: translateX(-50%);
    width: 31%; height: calc(var(--h) * 0.036); background: #000; border-radius: 99px;
  }
  .back {
    transform: rotateY(180deg) translateZ(calc(var(--t) / 2)); display: grid; place-items: center;
    background: linear-gradient(150deg, #56637A, #2A3448 55%, #3B475D);
    box-shadow: inset 0 0 0 calc(var(--h) * 0.006) #8C97A8;
  }
  .back-mark { width: 30%; }
  .back-mark circle:first-child { stroke: #F4F6F5; }
  .back-mark circle:last-child { fill: #4CC393; }
  .cam {
    position: absolute; top: 3.5%; left: 6%; width: 40%; aspect-ratio: 1; border-radius: 26%;
    background: rgba(255, 255, 255, 0.07); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);
  }
  .cam i {
    position: absolute; width: 40%; aspect-ratio: 1; border-radius: 50%;
    background: radial-gradient(circle at 40% 35%, #2B3A55, #05080D 60%); box-shadow: 0 0 0 calc(var(--h) * 0.005) #3A465C;
  }
  .cam i:nth-child(1) { top: 7%; left: 7%; }
  .cam i:nth-child(2) { bottom: 7%; left: 7%; }
  .cam i:nth-child(3) { top: 31%; right: 7%; width: 28%; }

  /* The stops */
  .stop {
    z-index: 3; display: flex; align-items: center; min-height: 150vh;
    /* The words sit centred in the outer part of their half, clear of the ring and its
       name in the middle column (172px either side of centre). */
    padding: 0 max(16px, (50vw - 672px) / 2);
  }
  /* The words keep clear of the ring and its name in the middle column. */
  .stop .copy { width: min(500px, 100%, 50vw - 188px); min-width: 0; }
  .stop.l { justify-content: flex-start; }
  .stop.r { justify-content: flex-end; }
  .s-hero { min-height: 100vh; min-height: 100svh; padding: 0 clamp(16px, 6vw, 96px); }
  .hero-inner { max-width: min(780px, 46vw); will-change: transform, opacity; }
  .hero-mark { font-size: clamp(40px, 8vw, 136px); gap: 14px; margin: 0; }
  .s-hero h1 { margin-top: 0.5em; }
  .s-hero .hint {
    display: block; margin: 26px 0 0; font-size: 0.8125rem; color: var(--text-3);
    letter-spacing: 0.1em; text-transform: uppercase;
  }
  /* The last screen is exactly one screen tall, so scrolling stops with Home beside the
     phone. The footer sits inside it. */
  .final { min-height: 100vh; min-height: 100svh; padding-bottom: var(--foot-h); }
  .foot { position: relative; z-index: 3; margin-top: calc(-1 * var(--foot-h)); height: var(--foot-h); }

  /* The route */
  .trail { display: block; position: absolute; left: 0; top: 0; width: 100%; z-index: 2; pointer-events: none; --R: 22px; }
  .trail svg, .done-track svg { position: absolute; left: 0; top: 0; overflow: visible; max-width: none; }
  .trail .ahead { stroke: var(--text-3); opacity: 0.45; }
  /* story.js sets the height and the dot's top: the line the "you" dot rides. */
  .done-window { position: absolute; left: 0; right: 0; top: 0; height: 50%; overflow: hidden; }
  .done-track { position: absolute; left: 0; top: 0; width: 100%; will-change: transform; }
  .done-track .done { stroke: var(--dot); }
  .site { position: absolute; width: 0; height: 0; }
  .site .ring {
    position: absolute; left: calc(var(--R) * -1.155); top: calc(var(--R) * -1.155);
    width: calc(var(--R) * 2.31); height: calc(var(--R) * 2.31); border-radius: 50%;
    border: calc(var(--R) * 0.31) solid var(--text); background: var(--bg);
  }
  .site .dot {
    position: absolute; left: calc(var(--R) * -0.06); top: calc(var(--R) * -0.66);
    width: calc(var(--R) * 0.72); height: calc(var(--R) * 0.72); border-radius: 50%;
    background: var(--dot); transform: scale(0); transition: transform 0.35s cubic-bezier(0.3, 1.6, 0.5, 1);
  }
  .site.arrived .dot { transform: scale(1); }
  .site .label {
    position: absolute; top: 0; transform: translateY(-50%); white-space: nowrap;
    font-size: 0.9375rem; font-weight: 600; line-height: 1; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--text);
  }
  .site .label.two { line-height: 1.25; }
  .site.lab-right .label { left: calc(var(--R) + 14px); }
  .site.lab-left .label { right: calc(var(--R) + 14px); text-align: right; }
  .you {
    position: absolute; left: 0; top: 50%; width: 18px; height: 18px; margin: -9px 0 0 -9px;
    border-radius: 50%; background: var(--dot); opacity: 0; will-change: transform, opacity;
  }
  .km {
    display: block; position: fixed; z-index: 45; margin: 0;
    right: clamp(16px, 3vw, 32px); top: calc(62px + env(safe-area-inset-top, 0px));
    padding: 7px 13px; border-radius: 999px; background: var(--text); color: var(--bg);
    font-weight: 600; font-size: clamp(0.8125rem, 1.1vw, 1rem); font-variant-numeric: tabular-nums;
    opacity: 0; visibility: hidden; transition: opacity 0.25s linear, visibility 0.25s linear;
  }
  .km.on { opacity: 1; visibility: visible; }
  .km em { color: var(--dot); }

  /* Where the browser has no scroll-driven animations, story.js eases the words in. */
  .js-words .stop:not(.s-hero) .copy { opacity: 0; transform: translateY(28px); transition: opacity 0.5s ease, transform 0.5s ease; }
  .js-words .stop:not(.s-hero) .copy.in { opacity: 1; transform: none; }

  /* Phone widths: the phone to one side, the ring and its name on the other, the words
     in a frosted card at the bottom. */
  @media (max-width: 900px) {
    .phone { --k: 1.55; --h: calc(min(36vh, 340px) * var(--k)); --h: calc(min(36svh, 340px) * var(--k)); }
    .stop { align-items: flex-end; justify-content: center; padding: 0 16px 6vh; }
    .stop.l, .stop.r { justify-content: center; }
    .stop .copy {
      width: min(500px, 100%);
      background: var(--card-glass); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
      padding: 16px 18px 8px; border-radius: 22px; box-shadow: 0 0 0 1px var(--line);
    }
    .copy h2 { font-size: 1.75rem; }
    .copy p { font-size: 1rem; }
    .s-hero { align-items: flex-start; padding: 9vh 16px 0; }
    .hero-inner { max-width: none; }
    .final { padding-bottom: calc(var(--foot-h) + 12px); }
    .trail { --R: 15px; }
    .site .label { font-size: 0.75rem; }
    .site.lab-right .label { left: calc(var(--R) + 11px); }
    .site.lab-left .label { right: calc(var(--R) + 11px); }
    .you { width: 14px; height: 14px; margin: -7px 0 0 -7px; }
  }

  /* Scroll-driven animations do the fades on their own where the browser has them. */
  @supports (animation-timeline: scroll()) {
    .bar, .km { animation: st-appear linear both; animation-timeline: scroll(root); animation-range: 43vh 53vh; transition: none; }
    .bar:focus-within { animation: none; }
    @media (min-width: 561px) {
      .menu { animation: st-disappear linear both; animation-timeline: scroll(root); animation-range: 43vh 53vh; transition: none; }
      .bar:focus-within ~ .menu { animation: none; }
    }
    @media (min-width: 561px) and (max-width: 900px) { .menu { animation-range: 52vh 62vh; } }
    .hero-inner { animation: st-hero linear both; animation-timeline: scroll(root); animation-range: 0px 75vh; }
    .stop:not(.s-hero) .copy { animation: st-words linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
    .trail:not(.by-script) .site:not(.start) .dot { animation: st-pop linear both; animation-timeline: view(); animation-range: cover 43% cover 50%; transition: none; }
    @media (max-width: 900px) {
      .bar, .km { animation-range: 52vh 62vh; }
      .hero-inner { animation-range: 0px 90vh; }
    }
  }
}
@keyframes st-appear { from { opacity: 0; visibility: hidden; } to { opacity: 1; visibility: visible; } }
@keyframes st-disappear { from { opacity: 1; visibility: visible; } to { opacity: 0; visibility: hidden; } }
@keyframes st-hero { to { opacity: 0; transform: translateY(-40px); } }
@keyframes st-words { from { opacity: 0; transform: translateY(28px); } }
@keyframes st-pop { 0% { transform: scale(0); } 70% { transform: scale(1.25); } 100% { transform: scale(1); } }
