/* The approved hero, "Tom fixes the sign" (hero-walk/approved/, 30 Oct 2026), unchanged apart from paths.
   Its class names (.hero .stage .tom .bubble .skip .btn …) are global, so the rest of the site avoids them. */

:root{
  --bg:#FBFAF7; --ink:#18171A; --ink-2:#3B393D; --gold:#C9A46A; --accent:#8A6634; --rule:#E2DFD8;
  --night:#121110; --night-text:#CFC9BE; --glow:#E9C98C;
  --grot:"Space Grotesk",system-ui,sans-serif; --serif:"Bodoni Moda",Didot,"Bodoni 72",Georgia,serif;
  color-scheme:light;

  /* Wordmark width; everything else is derived from it. */
  --ww:min(76vw, 1000px);

  /* Wordmark SVG geometry (viewBox 0 2.5 613.4 131.5): top-left of the T crossbar is (20.70, 25.0). */
  --w-aspect:0.21438;          /* 131.5 / 613.4 */
  --t-x:0.03375;               /* 20.70 / 613.4 */
  --t-y:0.1711;                /* (25.0 - 2.5) / 131.5 */

  /* Clip is 21:9 (1920x824). Measured on tom-walk-end.png: top-outer point of the shoulder on our right. */
  --v-aspect:0.42917;          /* 824 / 1920 */
  --sh-x:0.12240;          /* 235 / 1920 */
  --sh-y:0.47816;          /* 394 / 824 */

  /* Clip width relative to the wordmark; keeps Tom ~408px tall at a 1000px wordmark, as in v2/v3. */
  --tom:1.918;

  --vw:calc(var(--ww) * var(--tom));
  --vh:calc(var(--vw) * var(--v-aspect));
  --wh:calc(var(--ww) * var(--w-aspect));
  --tom-left:calc(var(--ww) * var(--t-x) - var(--vw) * var(--sh-x));
  --tom-top:calc(var(--wh) * var(--t-y) - var(--vh) * var(--sh-y));
}

*{box-sizing:border-box}
html,body{margin:0}
body{background:var(--bg);color:var(--ink);font-family:var(--grot);-webkit-font-smoothing:antialiased}

.hero{
  position:relative;isolation:isolate;
  min-height:100svh;display:grid;justify-items:center;align-content:center;overflow:clip;
  padding:calc(var(--ww) * 0.2) 16px calc(var(--ww) * 0.08);
  background:var(--bg);
}
/* Daylight layer: a full-bleed sheet whose opacity is the page's "light level". */
.hero::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--bg);opacity:1;pointer-events:none}
.stage{position:relative;width:var(--ww)}

/* ---- Wordmark: three stacked copies of one symbol. Only their opacity ever animates. ---- */
.wordmark{position:relative;z-index:1;display:block;width:100%;aspect-ratio:613.4 / 131.5}
.wordmark svg{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:visible}
/* Unlit: a faint outline of the letters, like a neon tube with the power off. */
.wm-unlit{--a:transparent;--b:transparent;--c:transparent;--s:rgba(251,250,247,.16);opacity:0}
.wm-glow{--a:var(--glow);--b:var(--glow);--c:var(--glow);filter:blur(calc(var(--ww) * 0.011));opacity:.28}
.wm-lit{--a:var(--ink);--b:var(--gold);--c:var(--accent)}
/* Faulty sign: the tubes in their night colours. "Tommy" (with its second m) flickers weakly; "Talk" is off until the plug. */
.wm-fault{--a:#F3E9D6;--b:#D9B276;--c:#B98A4C;opacity:0;filter:drop-shadow(0 0 calc(var(--ww) * .006) rgba(233,201,140,.7))}
.f-tommy{--fault:fault-tommy}
.f-m2{--fault:fault-m2}
.f-talk{--fault:fault-talk}
/* The T on its own layer, pivoting on the foot of its stem (34, 100 in the viewBox), so it can be bumped. */
.wm-t{position:absolute;inset:0;transform-origin:5.5% 74.1%}

.tom{
  position:absolute;z-index:2;left:var(--tom-left);top:var(--tom-top);
  width:var(--vw);height:var(--vh);pointer-events:none;
  /* Soft right edge: where the box ends inside a very wide screen, he fades in rather than popping in. */
  -webkit-mask-image:linear-gradient(to left, transparent 0, #000 4%);
          mask-image:linear-gradient(to left, transparent 0, #000 4%);
}
.tom video,.tom img{position:absolute;inset:0;width:100%;height:100%;display:block}
.tom video{opacity:0}

/* Speech bubble: sits above the wordmark, tail pointing down-left to his face. */
.bubble{
  position:absolute;z-index:3;left:calc(var(--ww) * 0.06);bottom:calc(100% + var(--ww) * 0.012);
  margin:0;padding:.7em 1.05em;max-width:18em;
  font:500 clamp(15px, calc(var(--ww) * 0.024), 22px)/1.3 var(--grot);
  background:#fff;color:var(--ink);border:1.5px solid var(--ink);border-radius:18px;
}
.bubble::after{
  content:"";position:absolute;left:-8px;bottom:12px;width:14px;height:14px;
  background:#fff;border-left:1.5px solid var(--ink);border-bottom:1.5px solid var(--ink);
  transform:rotate(45deg);border-bottom-left-radius:3px;
}

/* Headline and buttons: readable from the very first frame, in soft light text while the shop is dark. */
.lede{position:relative;z-index:3;width:min(100%, 40rem);margin-top:calc(var(--ww) * 0.2);text-align:center}
.lede h1{margin:0 0 .9em;font:500 clamp(20px, calc(var(--ww) * 0.032), 30px)/1.25 var(--grot);letter-spacing:-.01em;color:var(--ink);text-wrap:balance}
.ctas{display:flex;flex-wrap:wrap;justify-content:center;gap:12px}
.btn{
  display:inline-block;padding:.85em 1.5em;border-radius:999px;border:1.5px solid var(--ink);
  background:var(--ink);color:var(--bg);text-decoration:none;
  font:600 clamp(15px, calc(var(--ww) * 0.018), 18px)/1 var(--grot);letter-spacing:.01em;
  transition:background-color .2s ease, color .2s ease, border-color .2s ease;
}
.btn:hover{background:var(--accent);border-color:var(--accent)}
.btn-ghost{background:transparent;color:var(--ink)}
.btn-ghost:hover{background:transparent;color:var(--accent);border-color:var(--accent)}
.btn:focus-visible{outline:3px solid var(--gold);outline-offset:3px}

.skip{
  position:fixed;right:16px;bottom:16px;z-index:5;
  font:500 13px/1 var(--grot);color:var(--ink-2);background:var(--bg);
  border:1px solid var(--rule);border-radius:999px;padding:.6em 1em;cursor:pointer;
  transition:opacity .2s ease;
}
.skip:focus-visible{outline:3px solid var(--gold);outline-offset:2px}
.skip[hidden]{display:none}


/* ---- v6 story. Every animation's delay is its time on the clip (--t0 lines the CSS clock up with the video). ---- */
.cable,.pool,.warm,.wash,.talk-top{display:none}
.is-playing .tom img{opacity:0}
.is-playing .tom video{opacity:1}
.is-playing .bubble{opacity:0;transform:translateY(8px);visibility:hidden}
.is-settled .bubble{
  opacity:1;visibility:visible;transform:none;
  transition:opacity .45s cubic-bezier(.2,.7,.2,1), transform .45s cubic-bezier(.2,.7,.2,1), visibility 0s;
}

/* Dark shop: only while the clip plays. Every other path shows the lit page. */
.is-playing{background:var(--night)}
.is-playing::before{opacity:0}
.is-playing .wm-lit,.is-playing .wm-glow{opacity:0}
.is-playing .wm-unlit{opacity:1}
.is-playing .tom video{filter:brightness(.3)}
/* New wording: the headline, and a smaller line under it. */
.lede h1{margin-bottom:.4em}
.lede .sub{margin:0 auto 1.5em;max-width:34em;font:400 clamp(15px, calc(var(--ww) * .018), 18px)/1.5 var(--grot);color:var(--ink-2);text-wrap:balance}
/* While the shop is dark the words are soft light text with a faint dark halo; the halo keeps them clear of the
   page as it comes up to cream, until they swap to their day colours (with a cream halo) at mid-tone. */
.is-playing .lede h1{color:var(--night-text);text-shadow:var(--halo-night)}
.is-playing .lede .sub{color:var(--night-text);text-shadow:var(--halo-night)}
/* The main button stays a dark pill throughout (only its outline changes), so its label never loses contrast. */
.is-playing .btn{background:var(--ink);border-color:var(--night-text);color:var(--bg)}
.is-playing .btn-ghost{background:transparent;border-color:var(--night-text);color:var(--night-text);text-shadow:var(--halo-night)}
.hero{--halo-night:0 0 .3em rgba(18,17,16,.75), 0 0 .9em rgba(18,17,16,.5);--halo-day:0 0 .3em rgba(251,250,247,.8), 0 0 .9em rgba(251,250,247,.5)}
.is-playing ~ .skip{background:var(--night);color:var(--night-text);border-color:#34312D}
.is-playing :is(.cable,.pool,.warm,.wash,.talk-top){display:block}
.is-playing:not(.is-settled) :is(.wm-lit,.wm-glow,.wm-unlit,.wm-fault,.pool,.cable,.wash){will-change:opacity}
.is-playing:not(.is-settled) :is(.warm,.wm-t){will-change:transform,opacity}

/* The cable (drawn in clip px, under Tom). Its shape is an SVG animation scrubbed to the video's time. */
.cable{position:absolute;z-index:1;left:var(--tom-left);top:var(--tom-top);width:var(--vw);height:var(--vh);pointer-events:none;overflow:visible;opacity:0}
/* Kept quiet on purpose: a thin matte line just above the page colour, noticed only at the plug's spark. */
.cable path{fill:none;stroke:#2A2621;stroke-width:2;stroke-linecap:round}
.cable .plug{fill:#332E28}
.cable .spark{fill:#F1D9A8}
/* Warm pool of light on the "Talk" side once it is lit */
.pool{position:absolute;z-index:-1;pointer-events:none;opacity:0;
  left:calc(var(--ww) * .32);top:calc(var(--wh) * -1.6);width:calc(var(--ww) * 1.05);height:calc(var(--wh) * 4.6);
  background:radial-gradient(closest-side, rgba(233,201,140,.2), rgba(233,201,140,.08) 55%, rgba(233,201,140,0))}
/* Warm light seeping out from the whole wordmark when the sign comes on: a wide soft ellipse that swells a
   little and fades (transform and opacity only). It carries the page through the in-between stages of the
   cream daylight fade, so the page warms up rather than going grey. */
.warm{position:absolute;z-index:-1;pointer-events:none;opacity:0;
  left:calc(var(--ww) * -.45);top:calc(var(--wh) * -2.2);width:calc(var(--ww) * 1.9);height:calc(var(--wh) * 5.4);
  background:radial-gradient(closest-side, rgba(240,214,163,.55), rgba(233,201,140,.32) 45%, rgba(233,201,140,.12) 75%, rgba(233,201,140,0));
  transform:scale(.8)}
/* A full-page warm tint during the fade, so the halfway point is a warm taupe everywhere, never a grey edge. */
.wash{position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:0;background:rgba(201,164,106,.3)}
/* "Talk", once lit, stays in front of Tom while he walks across it. */
.talk-top{position:absolute;z-index:3;left:0;top:0;width:100%;aspect-ratio:613.4 / 131.5;pointer-events:none}
.talk-top svg{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:visible}

/* Flicker budget: "Tommy" never goes above a third of full strength while it is faulty, and blinks at most
   twice in each 1.6 s loop (well under 3 a second). "Talk" eases on; nothing flashes. */
.is-running :is(.f-tommy,.f-m2){animation:tommy-weak 1.6s linear var(--t0) infinite, tube-on .4s cubic-bezier(.3,.6,.3,1) calc(var(--t0) + 16.050s) forwards, tube-out .7s ease calc(var(--t0) + 17.050s) forwards}
.is-running .f-talk{animation:talk-on .9s cubic-bezier(.25,.6,.3,1) calc(var(--t0) + 7.602s) both, tube-out .7s ease calc(var(--t0) + 17.050s) forwards}
.is-running .pool{animation:fade-in 1.2s cubic-bezier(.3,.6,.3,1) calc(var(--t0) + 7.662s) both, fade-out 1s ease calc(var(--t0) + 16.700s) forwards}
.is-running .cable{animation:fade-in .4s ease var(--t0) both, fade-out .8s ease calc(var(--t0) + 16.600s) forwards}
/* Tom: dim in the dark, warmer once "Talk" is lit, cooler again as he walks away from it, then full daylight. */
.is-running .tom video{animation:tom-warm 1s ease calc(var(--t0) + 7.662s) both, tom-leave 5.708s ease-in-out calc(var(--t0) + 8.042s) forwards, tom-day 1.2s cubic-bezier(.45,0,.25,1) calc(var(--t0) + 16.450s) forwards}
/* Fix two, in order: the T jolts on shoulder contact; "Tommy" brightens fully with its glow (0.4 s); then warm
   light seeps out from the whole wordmark while the page eases up to cream (1.2 s). No disc, no flash. */
.is-running .wm-t{animation:t-jolt .25s cubic-bezier(.25,.7,.35,1) calc(var(--t0) + 16.000s) both}
.is-running .wm-glow{animation:glow-rise .4s cubic-bezier(.3,.6,.3,1) calc(var(--t0) + 16.050s) both, glow-settle 1.2s ease calc(var(--t0) + 16.900s) forwards}
.is-running .warm{animation:warm-seep 1.9s cubic-bezier(.4,0,.3,1) calc(var(--t0) + 16.400s) both}
.is-running .wash{animation:wash 1.8s cubic-bezier(.4,0,.4,1) calc(var(--t0) + 16.450s) both}
.is-running::before{animation:fade-in 1.2s cubic-bezier(.45,0,.3,1) calc(var(--t0) + 16.550s) both}
.is-running .wm-unlit{animation:fade-out .5s ease calc(var(--t0) + 16.450s) forwards}
.is-running .wm-lit{animation:fade-in .9s ease calc(var(--t0) + 16.750s) both}
.is-running .lede h1{animation:day-h1 .01s step-start calc(var(--t0) + 16.900s) both}
/* The smaller line takes the headline's colours through the fade, then eases to its own grey once the page is cream. */
.is-running .lede .sub{animation:day-h1 .01s step-start calc(var(--t0) + 16.900s) both, sub-settle .6s ease calc(var(--t0) + 17.800s) forwards}
.is-running .btn{animation:day-btn .8s ease calc(var(--t0) + 16.600s) both}
.is-running .btn-ghost{animation:day-ghost .01s step-start calc(var(--t0) + 16.900s) both}
.is-running ~ .skip{animation:day-skip .01s step-start calc(var(--t0) + 16.900s) both}

@keyframes tommy-weak{
  0%{opacity:.2} 18%{opacity:.2} 21%{opacity:.32} 25%{opacity:.16} 30%{opacity:.24}
  62%{opacity:.22} 65%{opacity:.3} 70%{opacity:.18} 100%{opacity:.2}
}
@keyframes tube-on{from{opacity:.2} to{opacity:1}}
@keyframes tube-out{from{opacity:1} to{opacity:0}}
@keyframes talk-on{0%{opacity:0} 18%{opacity:.5} 30%{opacity:.42} 100%{opacity:1}}
@keyframes fade-in{from{opacity:0} to{opacity:1}}
@keyframes fade-out{to{opacity:0}}
@keyframes tom-warm{from{filter:brightness(.3) sepia(0)} to{filter:brightness(.62) sepia(.16)}}
@keyframes tom-leave{from{filter:brightness(.62) sepia(.16)} to{filter:brightness(.42) sepia(.06)}}
@keyframes tom-day{from{filter:brightness(.42) sepia(.06)} 40%{filter:brightness(.62) sepia(.14)} to{filter:brightness(1) sepia(0)}}
@keyframes t-jolt{
  0%{transform:none}
  22%{transform:translateX(calc(var(--ww) * .004)) rotate(1.6deg)}
  55%{transform:translateX(calc(var(--ww) * -.0012)) rotate(-.5deg)}
  80%{transform:translateX(calc(var(--ww) * .0004)) rotate(.15deg)}
  100%{transform:none}
}
@keyframes wash{0%{opacity:0} 40%{opacity:1} 100%{opacity:0}}
@keyframes glow-rise{from{opacity:0} to{opacity:.85}}
@keyframes glow-settle{from{opacity:.85} to{opacity:.28}}
@keyframes warm-seep{0%{opacity:0;transform:scale(.8)} 45%{opacity:1} 100%{opacity:0;transform:scale(1.15)}}
@keyframes day-h1{from{color:var(--night-text);text-shadow:var(--halo-night)} to{color:var(--ink);text-shadow:var(--halo-day)}}
@keyframes sub-settle{from{color:var(--ink);text-shadow:var(--halo-day)} to{color:var(--ink-2);text-shadow:var(--halo-day)}}
@keyframes day-btn{from{border-color:var(--night-text)} to{border-color:var(--ink)}}
@keyframes day-ghost{
  from{border-color:var(--night-text);color:var(--night-text);text-shadow:var(--halo-night)}
  to{border-color:var(--ink);color:var(--ink);text-shadow:var(--halo-day)}
}
@keyframes day-skip{
  from{background:var(--night);color:var(--night-text);border-color:#34312D}
  to{background:var(--bg);color:var(--ink-2);border-color:var(--rule)}
}

/* ---- Phone (under 700 px): the same story on the phone cut's clock. ---- */
@media (max-width:699px){
/* Flicker budget: "Tommy" never goes above a third of full strength while it is faulty, and blinks at most
   twice in each 1.6 s loop (well under 3 a second). "Talk" eases on; nothing flashes. */
.is-running :is(.f-tommy,.f-m2){animation:tommy-weak 1.6s linear var(--t0) infinite, tube-on .4s cubic-bezier(.3,.6,.3,1) calc(var(--t0) + 11.883s) forwards, tube-out .7s ease calc(var(--t0) + 12.883s) forwards}
.is-running .f-talk{animation:talk-on .9s cubic-bezier(.25,.6,.3,1) calc(var(--t0) + 5.560s) both, tube-out .7s ease calc(var(--t0) + 12.883s) forwards}
.is-running .pool{animation:fade-in 1.2s cubic-bezier(.3,.6,.3,1) calc(var(--t0) + 5.620s) both, fade-out 1s ease calc(var(--t0) + 12.533s) forwards}
.is-running .cable{animation:fade-in .4s ease var(--t0) both, fade-out .8s ease calc(var(--t0) + 12.433s) forwards}
/* Tom: dim in the dark, warmer once "Talk" is lit, cooler again as he walks away from it, then full daylight. */
.is-running .tom video{animation:tom-warm 1s ease calc(var(--t0) + 5.620s) both, tom-leave 3.583s ease-in-out calc(var(--t0) + 6.000s) forwards, tom-day 1.2s cubic-bezier(.45,0,.25,1) calc(var(--t0) + 12.283s) forwards}
/* Fix two, in order: the T jolts on shoulder contact; "Tommy" brightens fully with its glow (0.4 s); then warm
   light seeps out from the whole wordmark while the page eases up to cream (1.2 s). No disc, no flash. */
.is-running .wm-t{animation:t-jolt .25s cubic-bezier(.25,.7,.35,1) calc(var(--t0) + 11.833s) both}
.is-running .wm-glow{animation:glow-rise .4s cubic-bezier(.3,.6,.3,1) calc(var(--t0) + 11.883s) both, glow-settle 1.2s ease calc(var(--t0) + 12.733s) forwards}
.is-running .warm{animation:warm-seep 1.9s cubic-bezier(.4,0,.3,1) calc(var(--t0) + 12.233s) both}
.is-running .wash{animation:wash 1.8s cubic-bezier(.4,0,.4,1) calc(var(--t0) + 12.283s) both}
.is-running::before{animation:fade-in 1.2s cubic-bezier(.45,0,.3,1) calc(var(--t0) + 12.383s) both}
.is-running .wm-unlit{animation:fade-out .5s ease calc(var(--t0) + 12.283s) forwards}
.is-running .wm-lit{animation:fade-in .9s ease calc(var(--t0) + 12.583s) both}
.is-running .lede h1{animation:day-h1 .01s step-start calc(var(--t0) + 12.733s) both}
/* The smaller line takes the headline's colours through the fade, then eases to its own grey once the page is cream. */
.is-running .lede .sub{animation:day-h1 .01s step-start calc(var(--t0) + 12.733s) both, sub-settle .6s ease calc(var(--t0) + 13.633s) forwards}
.is-running .btn{animation:day-btn .8s ease calc(var(--t0) + 12.433s) both}
.is-running .btn-ghost{animation:day-ghost .01s step-start calc(var(--t0) + 12.733s) both}
.is-running ~ .skip{animation:day-skip .01s step-start calc(var(--t0) + 12.733s) both}
}

/* ?t=N review: hold every animation on the frame for that moment. */
.is-frozen,.is-frozen *,.is-frozen::before,.is-frozen ~ .skip{animation-play-state:paused !important}

/* ---- Phone (under 700 px): the lit end state, stacked wordmark, and the walk-on on request ---- */
.pstage,.watch{display:none}
@media (max-width:699px){
  :root{--ww:min(74vw, 400px)}
  .hero{padding:24px 16px 32px}
  .stage,.hero > .pool{display:none}
  .pstage{
    display:block;position:relative;width:100vw;--u:calc(100vw / 780);height:calc(var(--u) * 448);
    --ww:calc(var(--u) * 736.08);--wh:calc(var(--ww) * var(--w-aspect));
  }
  .pw{position:absolute;inset:0;z-index:1}
  .pl1,.pl2{position:absolute}
  .pl1{left:calc(var(--u) * 138.16);top:calc(var(--u) * 92);width:calc(var(--u) * 432);height:calc(var(--u) * 144)}
  .pl2{left:calc(var(--u) * 190.4);top:calc(var(--u) * 231.4);width:calc(var(--u) * 315.6);height:calc(var(--u) * 129.6)}
  .pl1 svg,.pl2 svg,.pstage .talk-top svg{position:absolute;inset:0;width:100%;height:100%;display:block;overflow:hidden}
  .pl1 .wm-t{transform-origin:12.14% 70.83%}
  .pstage .tom{left:0;top:0;width:100%;height:100%;-webkit-mask-image:none;mask-image:none}
  .pstage .cable{left:0;top:0;width:100%;height:100%}
  .pstage .cable path{stroke-width:3}
  .pstage .talk-top{left:calc(var(--u) * 190.4);top:calc(var(--u) * 231.4);width:calc(var(--u) * 315.6);height:calc(var(--u) * 129.6);aspect-ratio:auto}
  .pstage .pool{left:calc(var(--u) * 20);top:calc(var(--u) * 80);width:calc(var(--u) * 640);height:calc(var(--u) * 440)}
  .pstage .warm{left:calc(var(--u) * -160);top:calc(var(--u) * -160);width:calc(var(--u) * 1100);height:calc(var(--u) * 760)}
  /* Bubble: just right of his face, tail pointing at it, clear of the T */
  .pstage .bubble{left:calc(var(--u) * 150);bottom:calc(100% - var(--u) * 84);font-size:15px}
  .watch{
    display:inline-flex;align-items:center;gap:.55em;margin-top:18px;
    padding:.8em 1.3em;border-radius:999px;border:1.5px solid var(--ink);background:var(--bg);color:var(--ink);
    font:600 16px/1 var(--grot);letter-spacing:.01em;cursor:pointer;
    transition:background-color .2s ease, color .2s ease;
  }
  .watch svg{width:.8em;height:.8em;fill:currentColor}
  .watch:hover{background:var(--ink);color:var(--bg)}
  .watch:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
  .watch[hidden]{display:none}
  /* While the clip plays the button keeps its space (so nothing shifts), but can't be seen or tabbed to */
  .is-playing:not(.is-settled) .watch{visibility:hidden}
  .lede{margin-top:20px}
}

/* ---- Reduced motion: no clip, no darkness, no flicker; lit page, still and bubble (Tier 3 fade only) ---- */
@media (prefers-reduced-motion:reduce){
  .tom video{display:none}
  .hero *,.hero::before{animation:none !important}
  .lamp,.wm-fault{display:none}
  .bubble{transition:opacity .15s ease !important}
}
