/* Tommy Talk website. Plain CSS, no framework. The home page also loads /hero/hero.css (the approved hero),
   whose class names are global, so nothing here reuses .hero .stage .tom .bubble .skip .btn .pool .warm .wash .watch. */
@font-face{font-family:"Space Grotesk";font-style:normal;font-weight:300 700;font-display:swap;src:url(/fonts/space-grotesk-var.woff2) format("woff2")}
@font-face{font-family:"Bodoni Moda";font-style:normal;font-weight:400 900;font-display:swap;src:url(/fonts/bodoni-moda-var.woff2) format("woff2")}
@font-face{font-family:"Bodoni Moda";font-style:italic;font-weight:400 700;font-display:swap;src:url(/fonts/bodoni-moda-italic-var.woff2) format("woff2")}

:root{
  --bg:#FBFAF7; --bg-2:#F3EFE6; --card:#FFFEFB; --ink:#18171A; --ink-2:#2E2C30; --muted:#4A4642;
  --gold:#C9A46A; --accent:#8A6634; --rule:#E2DFD8;
  --night:#121110; --on-ink:#F4F1EA; --on-ink-2:#CFC9BE;
  --grot:"Space Grotesk",system-ui,sans-serif; --serif:"Bodoni Moda",Didot,"Bodoni 72",Georgia,serif;
  --head-h:72px; --radius:20px;
  /* Headings (Tom's pick, 31 Oct): upright Bodoni Moda for h1 and the big section headings; the body sans in bold for
     every smaller heading. The italic Bodoni is kept for the wordmark only. Figures are always the bold sans. */
  --hd-font:var(--serif); --hd-weight:650; --hd-ls:-.01em;
  --hs-font:var(--grot); --hs-weight:700; --hs-ls:-.015em;
  color-scheme:light;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-padding-top:16px}
html,body{margin:0}
body{background:var(--bg);color:var(--ink);font:400 1.0625rem/1.6 var(--grot);-webkit-font-smoothing:antialiased;overflow-x:clip}
@media (min-width:768px){body{font-size:1.125rem}}
img{max-width:100%;height:auto;display:block}
a{color:var(--accent);text-underline-offset:.2em;text-decoration-thickness:1px}
a:hover{color:var(--ink)}
:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:4px}
p{margin:0 0 1em}
ul,ol{margin:0;padding:0}
h1,h2,h3{margin:0;font-weight:500}

.wrap{width:100%;max-width:76rem;margin-inline:auto;padding-inline:16px}
@media (min-width:768px){.wrap{padding-inline:32px}}

.skip-link{position:absolute;left:16px;top:-100px;z-index:20;background:var(--ink);color:var(--bg);padding:.7em 1.1em;border-radius:999px;text-decoration:none;font-weight:600}
.skip-link:focus{top:12px}
.visually-hidden{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---------- Header ---------- */
.site-head{position:relative;isolation:isolate;z-index:10;background:var(--bg);border-bottom:1px solid var(--rule)}
.head-row{min-height:var(--head-h);display:flex;align-items:center;justify-content:space-between;gap:24px}
.brand{display:block;padding:6px 0;flex:none}
.brand img{width:130px;height:auto}
.site-nav ul{list-style:none;display:flex;flex-wrap:wrap;gap:4px 22px}
.site-nav a{display:inline-block;padding:10px 0;color:var(--ink);text-decoration:none;font:500 .9375rem/1.2 var(--grot)}
.site-nav a:hover{color:var(--accent)}
.site-nav a[aria-current="page"]{text-decoration:underline;text-decoration-color:var(--gold);text-decoration-thickness:2px;text-underline-offset:.45em}
.menu-btn{font:600 .9375rem/1 var(--grot);color:var(--ink);background:transparent;border:1.5px solid currentColor;border-radius:999px;padding:.6em 1.1em;cursor:pointer}
.menu-btn[hidden]{display:none}
@media (min-width:1024px){.menu-btn{display:none!important}}

/* Phones and tablets: the links fold behind "Menu" (only with JS; without it they simply wrap). */
@media (max-width:1023px){
  .js .menu-btn{display:inline-block}
  .js .site-nav{display:none;position:absolute;left:0;right:0;top:100%;background:var(--bg);border-bottom:1px solid var(--rule);box-shadow:0 18px 30px -24px rgba(24,23,26,.35)}
  .js .site-nav.is-open{display:block}
  .js .site-nav ul{flex-direction:column;gap:0;padding:8px 16px 16px}
  .js .site-nav li + li{border-top:1px solid var(--rule)}
  .js .site-nav a{display:block;padding:14px 0;font-size:1.0625rem}
  .head-row{flex-wrap:wrap}
  html:not(.js) .site-nav{width:100%;padding-bottom:10px}
}
@media (min-width:768px) and (max-width:1023px){.js .site-nav ul{padding-inline:32px}}

/* Home: the header rides along with the hero's walk-on, dark while the shop is dark, lit with the page. */
.page-home .brand{visibility:hidden}
.page-home .site-head{border-bottom-color:transparent;background:transparent}
.page-home .site-head::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--bg)}
.page-home .hero{min-height:calc(100svh - var(--head-h))}
.page-home:has(.hero.is-playing) .site-head{background:var(--night)}
.page-home:has(.hero.is-playing) .site-head::before{opacity:0}
.page-home:has(.hero.is-playing) .site-head :is(.site-nav a,.menu-btn){color:var(--night-text,#CFC9BE)}
.page-home:has(.hero.is-running) .site-head::before{animation:fade-in 1.2s cubic-bezier(.45,0,.3,1) calc(var(--t0) + 16.550s) both}
.page-home:has(.hero.is-running) .site-head :is(.site-nav a,.menu-btn){animation:head-day .01s step-start calc(var(--t0) + 16.900s) both}
@media (max-width:699px){
  .page-home:has(.hero.is-running) .site-head::before{animation:fade-in 1.2s cubic-bezier(.45,0,.3,1) calc(var(--t0) + 12.383s) both}
  .page-home:has(.hero.is-running) .site-head :is(.site-nav a,.menu-btn){animation:head-day .01s step-start calc(var(--t0) + 12.733s) both}
}
.page-home:has(.hero.is-frozen) .site-head *,.page-home:has(.hero.is-frozen) .site-head::before{animation-play-state:paused!important}
@keyframes head-day{from{color:var(--night-text,#CFC9BE)} to{color:var(--ink)}}

/* ---------- Type ---------- */
.eyebrow{display:block;margin:0 0 14px;font:600 .8125rem/1.3 var(--grot);letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.display{font:var(--hd-weight) clamp(2.375rem, 1.6rem + 3.3vw, 4.5rem)/1.05 var(--hd-font);letter-spacing:var(--hd-ls);text-wrap:balance}
.h2{font:var(--hd-weight) clamp(1.875rem, 1.45rem + 2vw, 3rem)/1.1 var(--hd-font);letter-spacing:var(--hd-ls);text-wrap:balance;margin-bottom:.45em}
.h3{font:var(--hs-weight) clamp(1.25rem, 1.15rem + .5vw, 1.5rem)/1.25 var(--hs-font);letter-spacing:var(--hs-ls);margin-bottom:.4em}
.lead{font-size:clamp(1.125rem, 1.05rem + .35vw, 1.3125rem);line-height:1.55;color:var(--ink-2);max-width:34em;text-wrap:pretty}
.muted{color:var(--muted)}
.small{font-size:.9375rem}
.tm{font:normal 400 .5em/1 var(--grot);vertical-align:.9em;margin-left:.05em;letter-spacing:0}

/* ---------- Sections ---------- */
.section{padding-block:clamp(64px, 3rem + 5vw, 128px)}
.section--tight{padding-block:clamp(48px, 2rem + 3vw, 80px)}
.section-head{max-width:46rem;margin-bottom:clamp(32px, 2rem + 1.5vw, 56px)}
/* A single column of running text, kept to a readable line length. */
.measure{max-width:60ch}
.band{background:var(--ink);color:var(--on-ink)}
.band .lead,.band .muted{color:var(--on-ink-2)}
.band .eyebrow{color:var(--gold)}
.band a{color:var(--gold)}
.band a:hover{color:var(--on-ink)}
.band :focus-visible{outline-color:var(--gold)}
.soft{background:var(--bg-2)}

/* ---------- Buttons ---------- */
.button{display:inline-flex;align-items:center;gap:.5em;padding:.9em 1.5em;border-radius:999px;border:1.5px solid var(--ink);background:var(--ink);color:var(--bg);text-decoration:none;font:600 1rem/1 var(--grot);letter-spacing:.01em;cursor:pointer;transition:background-color .2s ease,color .2s ease,border-color .2s ease}
.button:hover{background:var(--accent);border-color:var(--accent);color:var(--bg)}
.button--ghost{background:transparent;color:var(--ink)}
.button--ghost:hover{background:transparent;color:var(--accent);border-color:var(--accent)}
.band .button{background:var(--gold);border-color:var(--gold);color:var(--ink)}
.band .button:hover{background:var(--on-ink);border-color:var(--on-ink);color:var(--ink)}
.band .button--ghost{background:transparent;color:var(--on-ink);border-color:var(--on-ink-2)}
.band .button--ghost:hover{color:var(--gold);border-color:var(--gold);background:transparent}
.actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:28px}
.arrow::after{content:"→";font-family:var(--grot)}

/* ---------- Page intro: words on one side, a character saying something on the other ---------- */
.intro{padding-block:clamp(40px, 2rem + 4vw, 96px) clamp(48px, 2rem + 4vw, 104px);overflow:clip}
.intro-grid{display:grid;gap:40px;align-items:center}
@media (min-width:900px){.intro-grid{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:56px}}
.intro .lead{margin-top:22px}

/* A character with a speech bubble. The bubble matches the hero's: white, ink outline, a tail towards the face. */
.speaker{position:relative;display:grid;justify-items:center;max-width:420px;margin-inline:auto;width:100%}
.speaker__art{position:relative;width:min(78%, 330px);aspect-ratio:390/517;isolation:isolate}
.speaker__art img{width:100%;height:100%;object-fit:contain;object-position:bottom}
.speaker__art .hand{position:absolute;inset:0}
.say{position:relative;margin:0 0 18px;padding:.8em 1.1em;max-width:20em;background:#fff;color:var(--ink);border:1.5px solid var(--ink);border-radius:18px;font:500 1.0625rem/1.4 var(--grot);text-wrap:pretty}
.say::after{content:"";position:absolute;left:42%;bottom:-8px;width:14px;height:14px;background:#fff;border-right:1.5px solid var(--ink);border-bottom:1.5px solid var(--ink);transform:rotate(45deg);border-bottom-right-radius:3px}
.say cite{display:block;margin-top:.35em;font:600 .8125rem/1.3 var(--grot);font-style:normal;color:var(--accent);letter-spacing:.02em}

/* The gold closing quote, from the wordmark: the site's one ornament. */
.quote-mark{font:italic 600 1em/1 var(--serif);color:var(--gold)}
.big-quote{display:block;font:italic 600 clamp(5rem, 3rem + 7vw, 9rem)/.6 var(--serif);color:var(--gold);height:.45em;margin-bottom:.15em}

/* ---------- Product cards ---------- */
.cards{display:grid;gap:20px}
@media (min-width:768px) and (max-width:1023px){.cards{grid-template-columns:1fr 1fr}.cards > :last-child{grid-column:1 / -1}}
@media (min-width:1024px){.cards{grid-template-columns:repeat(3, minmax(0,1fr));gap:24px}}
.card{display:flex;flex-direction:column;background:var(--card);border:1px solid var(--rule);border-radius:var(--radius);overflow:hidden}
.card__art{position:relative;height:220px;border-bottom:1px solid var(--rule);display:flex;align-items:flex-end;justify-content:center;overflow:hidden}
.card__art img{height:100%;width:auto;object-fit:contain}
.card__art--sign{align-items:center;padding:20px}
.card__art--sign img{height:100%;width:auto;border-radius:6px;box-shadow:0 10px 24px -14px rgba(24,23,26,.45);transform:rotate(-2deg)}
.card__body{display:flex;flex-direction:column;flex:1;padding:26px 24px 24px}
.card__body > p{color:var(--ink-2)}
.points{list-style:none;margin:4px 0 22px;display:grid;gap:10px}
.points li{position:relative;padding-left:1.4em}
.points li::before{content:"";position:absolute;left:0;top:.68em;width:.75em;height:2px;background:var(--gold)}
.card__foot{margin-top:auto;padding-top:18px;border-top:1px solid var(--rule);display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:8px 16px}
.card__price{font-weight:700;font-variant-numeric:tabular-nums lining-nums}
.card__link{font-weight:600;text-decoration:none}
.card__link:hover{text-decoration:underline}

/* ---------- Numbered steps ---------- */
.steps{list-style:none;counter-reset:step;display:grid;gap:28px}
@media (min-width:900px){.steps{grid-template-columns:repeat(3, minmax(0,1fr));gap:40px}}
.steps li{counter-increment:step;position:relative;padding-top:8px;border-top:1px solid var(--rule)}
.band .steps li{border-top-color:#3A373D}
.steps li::before{content:counter(step);display:block;margin:6px 0 10px;font:700 3rem/1 var(--grot);font-variant-numeric:tabular-nums lining-nums;color:var(--accent)}
.band .steps li::before{color:var(--gold)}
.steps h3{font:600 1.1875rem/1.3 var(--grot);margin-bottom:.4em}
.steps p{margin:0;color:var(--ink-2)}
.band .steps p{color:var(--on-ink-2)}

/* ---------- Simple lists ---------- */
.ticks{list-style:none;display:grid;gap:14px}
.ticks li{position:relative;padding-left:2em}
.ticks li::before{content:"";position:absolute;left:0;top:.2em;width:1.2em;height:1.2em;border-radius:50%;background:var(--gold) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.3 5 8.6l4.6-5' fill='none' stroke='%2318171A' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/70% no-repeat}
.ticks strong{display:block;font-weight:600}
.ticks--two{gap:18px 40px}
@media (min-width:768px){.ticks--two{grid-template-columns:1fr 1fr}}
.chips{list-style:none;display:flex;flex-wrap:wrap;gap:10px}
.chips li{padding:.55em 1em;border:1.5px solid var(--ink);border-radius:999px;font-weight:500;background:var(--card)}

/* ---------- Two-column feature rows ---------- */
.split{display:grid;gap:40px;align-items:center}
@media (min-width:900px){.split{grid-template-columns:1fr 1fr;gap:64px}.split--flip > :first-child{order:2}}

/* ---------- Prices ---------- */
.price{display:grid;align-content:start;gap:4px;padding:28px 0;border-top:1px solid var(--rule)}
.price:last-child{border-bottom:1px solid var(--rule)}
.band .price{border-color:#3A373D}
.price__figure{font:700 clamp(2.125rem, 1.75rem + 1.5vw, 3rem)/1.05 var(--grot);letter-spacing:-.02em;font-variant-numeric:tabular-nums lining-nums}
.price__what{font-weight:600}
.price__note{color:var(--muted);margin:0}
.band .price__note{color:var(--on-ink-2)}
.price-grid{display:grid;gap:0 48px}
@media (min-width:900px){.price-grid{grid-template-columns:repeat(2, minmax(0,1fr))}}
.product-price{display:grid;gap:24px;padding-block:48px;border-top:1px solid var(--rule)}
@media (min-width:900px){.product-price{grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:64px}}
.product-price:first-of-type{border-top:0;padding-top:0}
.product-price ul{list-style:none;display:grid;gap:0}
.product-price li{display:flex;flex-wrap:wrap;justify-content:space-between;gap:4px 24px;padding:16px 0;border-bottom:1px solid var(--rule)}
.product-price li:first-child{border-top:1px solid var(--rule)}
.product-price .amount{font:700 1.375rem/1.2 var(--grot);font-variant-numeric:tabular-nums lining-nums;white-space:nowrap}

/* ---------- Placeholders for Tom's photos (listed in site/README.md) ---------- */
.ph{display:grid;place-items:center;aspect-ratio:4/3;padding:20px;border:2px dashed var(--accent);border-radius:var(--radius);
  background:repeating-linear-gradient(-45deg, var(--bg-2) 0 14px, #EEE9DE 14px 28px);
  color:var(--ink-2);font:500 .9375rem/1.45 ui-monospace,"SF Mono",Menlo,monospace;text-align:center}
.ph--wide{aspect-ratio:16/9}

/* ---------- Demo cards ---------- */
.demos{display:grid;gap:20px}
@media (min-width:768px){.demos{grid-template-columns:repeat(2, minmax(0,1fr))}}
@media (min-width:1200px){.demos--four{grid-template-columns:repeat(4, minmax(0,1fr))}.demos--three{grid-template-columns:repeat(3, minmax(0,1fr))}}
.demo{position:relative;display:flex;flex-direction:column;border-radius:var(--radius);background:var(--card);border:1px solid var(--rule);overflow:hidden}
.band .demo{background:#211F24;border-color:#3A373D}
.demo__art{height:200px;display:flex;align-items:flex-end;justify-content:center;border-bottom:1px solid var(--rule)}
.band .demo__art{border-bottom-color:#3A373D}
.demo__art img{height:100%;width:auto}
.demo__body{display:flex;flex-direction:column;flex:1;padding:22px 22px 24px}
.demo__body .h3{font-size:1.375rem}
.demo__body p{color:var(--ink-2)}
.band .demo__body p{color:var(--on-ink-2)}
.demo__go{margin-top:auto;font-weight:600;text-decoration:none}
.demo__go::before{content:"";position:absolute;inset:0;border-radius:inherit}
.demo:has(.demo__go:hover){border-color:var(--gold)}
.demo:has(.demo__go:focus-visible){outline:3px solid var(--accent);outline-offset:3px}
.band .demo:has(.demo__go:focus-visible){outline-color:var(--gold)}
.demo__go:focus-visible{outline:none}
.demo--empty{border:2px dashed var(--gold);background:transparent}
.demo--empty .demo__art{background:transparent}
.empty-frame{width:150px;height:180px;margin-bottom:10px;border:2px dashed var(--accent);border-radius:75px 75px 12px 12px;display:grid;place-items:center;color:var(--accent);font:var(--hs-weight) 1.05rem/1.2 var(--hs-font);text-align:center;padding:12px}
.band .empty-frame{border-color:var(--gold);color:var(--gold)}

/* ---------- Window sign ---------- */
.sign-frame{max-width:440px;margin-inline:auto}
.sign-frame img{width:100%;border-radius:8px;box-shadow:0 30px 50px -30px rgba(24,23,26,.55), 0 0 0 1px var(--rule)}
.sign-frame figcaption{margin-top:16px;color:var(--muted);font-size:.9375rem;text-align:center}

/* ---------- Phone mock-up ---------- */
.phone{position:relative;width:min(100%, 320px);margin-inline:auto;padding:12px;border-radius:46px;background:#0E0D0F;box-shadow:0 40px 60px -36px rgba(24,23,26,.6), inset 0 0 0 1.5px #3A373D}
.phone img{width:100%;border-radius:34px}
.phone figcaption{position:absolute;left:0;right:0;top:calc(100% + 18px);text-align:center;color:var(--muted);font-size:.9375rem}

/* ---------- Trail map with tappable QR codes ---------- */
.map{position:relative;margin:0;border-radius:12px;overflow:hidden;box-shadow:0 30px 60px -40px rgba(24,23,26,.55), 0 0 0 1px var(--rule);background:#F1ECDF}
.map img{width:100%}
.qr-hit{position:absolute;display:block;border-radius:6px}
.qr-hit:hover{box-shadow:0 0 0 3px var(--gold)}
.qr-hit:focus-visible{outline:3px solid var(--ink);outline-offset:2px;box-shadow:0 0 0 6px var(--gold)}
.stop-list{list-style:none;display:grid;gap:0 32px;margin-top:28px;counter-reset:none}
@media (min-width:768px){.stop-list{grid-template-columns:repeat(2, minmax(0,1fr))}}
.stop-list li{display:flex;align-items:center;gap:16px;border-top:1px solid var(--rule)}
.stop-list li > a{flex:1;min-width:0}
.stop-qr{display:none}
@media (min-width:1024px){.stop-qr{display:block;flex:none;width:104px;padding:6px 0}.stop-qr svg{display:block;width:100%;height:auto}}
.stop-list a{display:flex;gap:14px;align-items:baseline;padding:14px 0;color:var(--ink);text-decoration:none}
.stop-list a:hover .stop-name{color:var(--accent);text-decoration:underline}
.stop-num{flex:none;display:inline-grid;place-items:center;width:1.9em;height:1.9em;border-radius:50%;background:#B5432C;color:#fff;font:700 .875rem/1 var(--grot)}
.stop-num--story{background:transparent;color:var(--ink);border:2px solid currentColor}
.stop-name{font-weight:600}
.stop-go{margin-left:auto;color:var(--accent);font-size:.875rem;font-weight:600;text-align:right}

/* "Demo coming soon" (Keynsham switched off) */
.soon{display:grid;gap:28px;align-items:center;padding:clamp(24px, 4vw, 48px);border:1px solid var(--rule);border-radius:var(--radius);background:var(--card)}
@media (min-width:768px){.soon{grid-template-columns:auto 1fr}}
.soon img{width:180px;aspect-ratio:390/517;object-fit:contain;object-position:bottom}

/* ---------- Contact ---------- */
.contact{display:grid;gap:40px;align-items:center}
@media (min-width:900px){.contact{grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr)}}
.email-big{display:inline-block;margin-top:8px;font:700 clamp(1.5rem, 1.1rem + 2vw, 2.5rem)/1.2 var(--grot);letter-spacing:-.015em;color:inherit;text-decoration:underline;text-decoration-color:var(--gold);text-decoration-thickness:2px;text-underline-offset:.18em;overflow-wrap:anywhere}
.email-big:hover{color:var(--accent)}

/* ---------- Prose (privacy) ---------- */
.prose{max-width:42rem}
.prose h2{font:600 1.1875rem/1.3 var(--grot);margin:2.25rem 0 .6rem;padding-top:1.25rem;border-top:1px solid var(--rule)}
.prose ul{padding-left:1.2rem;margin-bottom:1em}
.prose li{margin-bottom:.6em}

/* ---------- Footer ---------- */
.site-foot{background:var(--ink);color:var(--on-ink-2);padding-top:clamp(48px, 6vw, 80px)}
.site-foot a{color:var(--on-ink);text-decoration:none}
.site-foot a:hover{color:var(--gold);text-decoration:underline}
.site-foot :focus-visible{outline-color:var(--gold)}
.foot-grid{display:grid;gap:36px}
@media (min-width:768px){.foot-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.foot-brand img{width:150px;margin-bottom:18px}
.foot-brand p{max-width:26em}
.site-foot nav ul{list-style:none;display:grid;gap:4px 32px}
@media (min-width:480px){.site-foot nav ul{grid-template-columns:1fr 1fr}}
.site-foot nav a{display:inline-block;padding:6px 0}
.foot-legal{margin-top:40px;padding-block:22px 28px;border-top:1px solid #34312D;font-size:.875rem}
.foot-legal p{margin:0}

/* ---------- Gentle reveal as sections arrive (opacity and transform only; off for reduced motion) ---------- */
@media (prefers-reduced-motion:no-preference){
  .js .reveal{opacity:0;transform:translateY(18px);transition:opacity .6s cubic-bezier(.2,.7,.2,1), transform .6s cubic-bezier(.2,.7,.2,1)}
  .js .reveal.is-in{opacity:1;transform:none}
}

/* ---------- On Tour extras ---------- */
.portrait{width:150px;margin-top:36px}
.photo-row{display:grid;gap:16px}
@media (min-width:768px){.photo-row{grid-template-columns:repeat(3, minmax(0,1fr))}}
/* "It can be anyone": the speech hand-off. Sizes are in container units (cqw), so the scene scales as one picture.
   Phones (narrow): Tom and the bishop side by side, bubbles above their heads, the empty frame stacked underneath.
   Wider than 600px: all three in a row. Everything is placed where the scene ends; the animation only adds
   transforms and opacity on the way there. */
.handoff{position:relative;container-type:inline-size;max-width:1100px;margin-inline:auto}
.handoff__stage{position:relative;height:88cqw;--h:52cqw;--from:23cqw}
.actor{position:absolute;bottom:0;display:flex;flex-direction:column;align-items:center}
.actor--tom{left:-1.2cqw;width:calc(var(--h) * 560 / 517)}
.actor--heah{left:54.9cqw;width:calc(var(--h) * 390 / 517)}
.actor__art{position:relative;width:100%;height:var(--h)}
.actor__art img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;object-position:bottom}
.actor__a{opacity:0}
.actor .say{flex:none;width:max-content;max-width:44cqw;margin:0 0 2.6cqw;padding:.65em .9em;font-size:14px;line-height:1.35}
/* Tails point down at the mouths: Tom's head is at the middle of his column, the bishop's just left of it. */
.actor--tom .say{margin-right:4cqw}
.actor--tom .say::after{left:calc(50% + 2cqw - 7px)}
.actor--heah .say::after{left:calc(50% - 1.6cqw - 7px)}
.next{display:grid;justify-items:center;margin-top:5cqw}
.next__frame{width:36cqw;aspect-ratio:390/500;display:grid;place-items:center;padding:12px;border:2px dashed var(--accent);border-radius:999px 999px 16px 16px;color:var(--accent);font:var(--hs-weight) clamp(1rem, 4.6cqw, 1.75rem)/1.15 var(--hs-font);text-align:center}
.next__cap{margin:12px 0 0;font-weight:500;color:var(--ink-2);text-align:center}
.replay{display:block;margin:24px auto 0;position:relative;font:600 .875rem/1 var(--grot);color:var(--ink);background:var(--bg);border:1.5px solid var(--ink);border-radius:999px;padding:.55em 1em;cursor:pointer}
.replay:hover{background:var(--ink);color:var(--bg)}
.replay[hidden]{display:none}
@container (min-width:600px){
  .handoff__stage{height:49cqw;--h:34cqw;--from:30cqw}
  .actor--tom{left:1.6cqw}
  .actor--heah{left:38.2cqw}
  .actor .say{max-width:29cqw;font-size:clamp(15px, 1.65cqw, 18px);margin-bottom:1.4cqw}
  .actor--tom .say{margin-right:0}
  .actor--tom .say::after{left:calc(50% - 7px)}
  .actor--heah .say::after{left:calc(50% - 1cqw - 7px)}
  /* The empty frame stands in the line-up: the same height as Tom and the bishop, on the same baseline. */
  .handoff__stage{margin-bottom:4.6em}   /* room for the caption under the frame (a container can't pad itself) */
  .next{position:absolute;left:68cqw;top:calc(49cqw - var(--h, 34cqw));width:26cqw;margin:0;--h:34cqw}
  .next__frame{width:22cqw;height:34cqw;aspect-ratio:auto;font-size:clamp(1rem, 2.1cqw, 1.6rem)}
}

.demo__art .demo__sign{height:86%;align-self:center;border-radius:4px}
.about-art{display:flex;justify-content:center}
.about-art img{width:min(70%, 300px)}
@media (min-width:900px){.about-art img{width:min(80%, 340px)}}
.band .phone figcaption{color:var(--on-ink-2)}

/* ---- The hand-off scene playing (only with motion allowed; site.js adds the classes). ----
   One clock: each delay is calc(var(--hf-t0) + its time), so ?handoff=N can freeze any moment for review.
   0 s Tom talks in the middle · 1.6-2.4 s he steps aside · 2.35-2.6 s explain to thumbs up ·
   2.3-3.0 s the bishop rises in · 3.0-3.35 s his answer · 4.3-4.8 s "Your guide here". Transform and opacity only. */
.handoff{--hf-t0:0s}
.is-armed:not(.is-play) .actor--tom{transform:translateX(var(--from))}
.is-armed:not(.is-play) .actor__a{opacity:1}
.is-armed:not(.is-play) .actor__b,
.is-armed:not(.is-play) .actor--heah .actor__art,
.is-armed:not(.is-play) .actor--heah .say,
.is-armed:not(.is-play) .next{opacity:0}
.is-play .actor--tom{animation:hf-step .8s cubic-bezier(.45,0,.2,1) calc(var(--hf-t0) + 1.6s) both}
.is-play .actor__a{animation:hf-out .25s ease calc(var(--hf-t0) + 2.35s) both}
.is-play .actor__b{animation:hf-in .25s ease calc(var(--hf-t0) + 2.35s) both}
.is-play .actor--heah .actor__art{animation:hf-rise .7s cubic-bezier(.2,.7,.2,1) calc(var(--hf-t0) + 2.3s) both}
.is-play .actor--heah .say{transform-origin:40% 100%;animation:hf-say .35s cubic-bezier(.2,.7,.2,1) calc(var(--hf-t0) + 3s) both}
.is-play .next{animation:hf-next .5s ease calc(var(--hf-t0) + 4.3s) both}
.is-play:not(.is-done) :is(.actor--tom,.actor__a,.actor__b,.actor--heah .actor__art,.actor--heah .say,.next){will-change:transform,opacity}
.is-frozen,.is-frozen *{animation-play-state:paused!important}
@keyframes hf-step{from{transform:translateX(var(--from))} to{transform:none}}
@keyframes hf-out{from{opacity:1} to{opacity:0}}
@keyframes hf-in{from{opacity:0} to{opacity:1}}
@keyframes hf-rise{from{opacity:0;transform:translateY(12%)} to{opacity:1;transform:none}}
@keyframes hf-say{from{opacity:0;transform:translateY(6px) scale(.96)} to{opacity:1;transform:none}}
@keyframes hf-next{from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:none}}
/* Reduced motion: the end frame, still. (site.js never arms the scene then; this is the belt to its braces.) */
@media (prefers-reduced-motion:reduce){.handoff *{animation:none!important}.handoff .actor__a{opacity:0!important}}

/* ---------- Waist-up blazer Tom (560 x 517 frames) in a speaker ---------- */
.speaker__art--wide{width:min(100%, 420px);aspect-ratio:560/517}

/* ---------- "What is Tommy Talk?" ---------- */
.whatis-grid{display:grid;gap:32px;align-items:end}
@media (min-width:900px){.whatis-grid{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:56px}}
.whatis-points{list-style:none;display:grid;gap:12px;margin-top:8px}
.whatis-points li{position:relative;padding-left:1.4em;color:var(--ink-2)}
.whatis-points li::before{content:"";position:absolute;left:0;top:.72em;width:.75em;height:2px;background:var(--accent)}

/* ---------- Example conversations (real HTML) ----------
   Laid out where the conversation ends; playing only adds opacity and transforms on the way there (site.js). */
.mock{margin:0;container-type:inline-size}
.mock figcaption{margin-top:12px;color:var(--muted);font-size:.9375rem}
.chat{background:#fff;border:1.5px solid var(--ink);border-radius:22px;overflow:hidden;box-shadow:0 30px 50px -36px rgba(24,23,26,.5)}
.chat__head{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--rule);font-weight:700}
.chat__head img{width:40px;height:40px;border-radius:50%;background:var(--bg-2);object-fit:cover}
.chat__head small{display:block;font-weight:500;font-size:.8125rem;color:var(--muted)}
.chat__log{list-style:none;display:grid;gap:10px;padding:18px 16px 20px}
.msg{display:flex}
.msg--you{justify-content:flex-end}
.msg__text{display:block;max-width:82%;padding:.6em .9em;border-radius:18px;font-size:1rem;line-height:1.45}
.msg--you .msg__text{background:var(--ink);color:var(--bg);border-bottom-right-radius:6px}
.msg--tom{position:relative}
.msg--tom .msg__text{background:var(--bg-2);color:var(--ink);border-bottom-left-radius:6px}
.dots{position:absolute;left:0;top:0;display:flex;gap:5px;padding:.85em 1em;border-radius:18px;border-bottom-left-radius:6px;background:var(--bg-2);opacity:0}
.dots i{width:7px;height:7px;border-radius:50%;background:var(--muted)}

/* A (made-up) website with the companion open in its corner. Narrow: the chat fills the frame under the address bar. */
.mock--site{max-width:640px;margin-inline:auto;width:100%}
.mock__bar{display:flex;align-items:center;gap:6px;padding:10px 14px;background:#ECE8DF;border:1.5px solid var(--ink);border-bottom:0;border-radius:16px 16px 0 0}
.mock__bar i{width:10px;height:10px;border-radius:50%;background:#C9C3B6}
.mock__bar span{margin-left:10px;padding:3px 12px;border-radius:999px;background:#fff;font-size:.8125rem;color:var(--muted)}
.mock__body{position:relative;padding:14px;background:var(--card);border:1.5px solid var(--ink);border-radius:0 0 16px 16px}
.mock__page{display:none}
.mock__launch{display:none}
.chat--corner{box-shadow:none}
@container (min-width:520px){
  .mock__body{height:min(620px, 100cqw);padding:0;overflow:hidden}
  .mock__page{display:grid;gap:14px;align-content:start;padding:26px 28px;width:58%}
  .mock__logo{font:700 1.125rem/1 var(--hs-font);margin-bottom:14px}
  .mock__line{height:12px;border-radius:6px;background:#E9E4DA}
  .mock__line--big{height:26px;width:90%;background:#DCD5C7}
  .mock__line--short{width:60%}
  .mock__tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:10px}
  .mock__tiles i{aspect-ratio:1;border-radius:10px;background:#EFEAE0}
  .chat--corner{position:absolute;right:16px;top:16px;bottom:84px;width:min(64%, 380px);display:flex;flex-direction:column;box-shadow:0 24px 40px -24px rgba(24,23,26,.45)}
  .chat--corner .chat__log{flex:1;min-height:0;align-content:end;overflow:hidden}
  .chat--corner .msg__text{font-size:.9375rem}
  .mock__launch{display:block;position:absolute;right:16px;bottom:16px;width:56px;height:56px;border-radius:50%;border:2px solid var(--ink);overflow:hidden;background:var(--bg-2)}
  .mock__launch img{width:100%;height:100%;object-fit:cover}
}

/* Playing (motion allowed only): each message arrives at its own --at; Tom's are preceded by typing dots. */
.mock{--c-t0:0s}
.is-armed:not(.is-play) .msg__text{opacity:0}
.is-play .msg__text{animation:msg-in .35s cubic-bezier(.2,.7,.2,1) calc(var(--c-t0) + var(--at)) both}
.is-play .msg--you .msg__text{transform-origin:100% 100%}
.is-play .msg--tom .msg__text{transform-origin:0 100%}
.is-play .dots{animation:dots-show .9s linear calc(var(--c-t0) + var(--at) - .9s) both}
.is-play .dots i{animation:dot-hop .6s ease-in-out calc(var(--c-t0) + var(--at) - .9s) 2 both}
.is-play .dots i:nth-child(2){animation-delay:calc(var(--c-t0) + var(--at) - .8s)}
.is-play .dots i:nth-child(3){animation-delay:calc(var(--c-t0) + var(--at) - .7s)}
.is-play:not(.is-done) :is(.msg__text,.dots){will-change:transform,opacity}
@keyframes msg-in{from{opacity:0;transform:translateY(8px) scale(.97)} to{opacity:1;transform:none}}
@keyframes dots-show{0%{opacity:0} 12%{opacity:1} 90%{opacity:1} 100%{opacity:0}}
@keyframes dot-hop{0%,100%{transform:none} 40%{transform:translateY(-4px)}}
.mock .replay{margin-top:16px}
@media (prefers-reduced-motion:reduce){.mock *{animation:none!important}.mock .dots{opacity:0!important}}

/* ---------- Try it now ---------- */
.try{display:grid;gap:40px;align-items:center}
@media (min-width:900px){.try{grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:64px}}
.try-steps{list-style:none;counter-reset:try;display:grid;gap:22px;margin-top:8px}
.try-steps > li{counter-increment:try;position:relative;padding-left:3.1rem;color:var(--ink-2)}
.try-steps > li::before{content:counter(try);position:absolute;left:0;top:-.1em;display:grid;place-items:center;width:2.1rem;height:2.1rem;border-radius:50%;background:var(--ink);color:var(--bg);font:700 1rem/1 var(--grot);font-variant-numeric:tabular-nums}
.try-steps strong{display:block;color:var(--ink);font-weight:700;margin-bottom:2px}
.ask-row{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px}
.ask{font:600 1rem/1.2 var(--grot);color:var(--ink);background:var(--card);border:1.5px solid var(--ink);border-radius:999px;padding:.65em 1.05em;cursor:pointer;text-align:left;transition:background-color .2s ease,color .2s ease}
.ask:hover{background:var(--ink);color:var(--bg)}
.try-sign{display:block;width:150px;margin-top:14px}
.try-sign img{border-radius:6px;box-shadow:0 14px 28px -18px rgba(24,23,26,.5), 0 0 0 1px var(--rule)}
@media (min-width:1024px){.try-sign{width:190px}}
.try-note:empty{display:none}
.try-note{margin-top:20px;padding:12px 16px;border-left:3px solid var(--accent);background:var(--card);color:var(--ink)}

/* The hero's "Sorted. Ask me anything." opens the chat: a button that keeps the approved bubble's look. */
button.bubble{cursor:pointer;text-align:left}
button.bubble:hover{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.2em}
.more-demos{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:20px 40px;padding-block:28px;border-block:1px solid var(--rule)}
.more-demos p{margin:0}
/* "What is it?" at the top of each product page: a small label, then the plain answer. */
.what-it-is{margin:22px 0 18px;padding-left:18px;border-left:3px solid var(--accent)}
.what-it-is__h{font:700 .9375rem/1.3 var(--grot);letter-spacing:.02em;color:var(--accent);margin-bottom:6px}
.what-it-is .lead{margin:0}
.try-steps--plain{margin-top:20px}
@media (max-width:899px){.try > .speaker{order:2}}

/* A phone, for the Shop Window Guide and On Tour examples: the page the QR code opens, drawn in HTML. */
.mock--phone{max-width:340px;margin-inline:auto;width:100%}
.mock--phone figcaption{text-align:center}
.handset{padding:12px;border-radius:46px;background:#0E0D0F;box-shadow:0 40px 60px -36px rgba(24,23,26,.6), inset 0 0 0 1.5px #3A373D}
.handset__screen{display:flex;flex-direction:column;min-height:520px;border-radius:34px;background:var(--bg);overflow:hidden}
.street-head{display:flex;align-items:center;gap:12px;padding:30px 18px 14px;background:var(--card);border-bottom:1px solid var(--rule)}
.street-head img{width:44px;height:44px;border-radius:50%;background:var(--bg-2);object-fit:cover}
.street-head b{display:block;font-weight:700}
.street-head small{display:flex;align-items:center;gap:6px;font-size:.8125rem;color:var(--muted)}
.street-head--tour small{color:var(--accent);font-weight:700;letter-spacing:.02em}
.dot-closed{width:8px;height:8px;border-radius:50%;background:#B5432C}
.mock--phone .chat__log{flex:1;align-content:start;padding:16px 14px}
.mock--phone .msg__text{font-size:.9375rem}
.msg--btn{justify-content:center;margin-top:6px}
.msg--btn .msg__text{background:var(--ink);color:var(--bg);border-radius:999px;font-weight:700;padding:.65em 1.4em}
.demo__do{font-size:.9375rem}
.demo__do strong{font-weight:700;color:var(--ink)}
.band .demo__do strong{color:var(--on-ink)}
.speaker--inline{margin:28px 0 0;max-width:340px;justify-items:start}
@media (max-width:899px){.speaker--inline{display:none}}

/* ---------- The Keynsham poster, large: each side on its own dark band, like the poster on a wall ---------- */
.poster-band{background:var(--night);color:var(--on-ink);padding-block:clamp(40px, 2rem + 3vw, 88px)}
.poster-wrap{max-width:calc(1600px + 32px);margin-inline:auto;padding-inline:16px}
.poster-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px 24px;margin-bottom:20px}
.poster-head .h3{margin:0;color:var(--on-ink)}
.poster-band .button{background:var(--gold);border-color:var(--gold);color:var(--ink)}
.poster-band .button:hover{background:var(--on-ink);border-color:var(--on-ink);color:var(--ink)}
.poster-band :focus-visible{outline-color:var(--gold)}
.poster-band .map{box-shadow:0 40px 80px -40px rgba(0,0,0,.8)}
.poster-cap{margin:16px 0 0;color:var(--on-ink-2);font-size:.9375rem}
.poster-band .qr-hit:focus-visible{outline-color:var(--on-ink)}
.list-title{font:700 1.0625rem/1.3 var(--grot);margin:0 0 4px}
.poster-band .eyebrow{color:var(--gold)}
.poster-band .lead{color:var(--on-ink-2)}
.trail-band__grid{display:grid;gap:32px;align-items:center}
@media (min-width:900px){.trail-band__grid{grid-template-columns:minmax(0,.75fr) minmax(0,1.25fr);gap:56px}}
.trail-band__map{display:block;border-radius:10px;overflow:hidden;box-shadow:0 40px 80px -40px rgba(0,0,0,.8)}
.trail-band__map:hover{box-shadow:0 0 0 3px var(--gold), 0 40px 80px -40px rgba(0,0,0,.8)}
.trail-band__map:focus-visible{outline:3px solid var(--gold);outline-offset:4px}

/* "View full size": the poster in a full-screen viewer with zoom and pan (site.js). Transform only. */
.zoom{position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;margin:0;padding:0;border:0;background:#0B0A0A;color:var(--on-ink);overscroll-behavior:contain}
.zoom::backdrop{background:#0B0A0A}
.zoom__view{position:absolute;inset:76px 0 84px;overflow:hidden;touch-action:none;cursor:grab}
@media (max-width:599px){.zoom__view{inset:72px 0 80px}}
.zoom__view.is-dragging{cursor:grabbing}
.zoom__view:focus-visible{outline:3px solid var(--gold);outline-offset:-3px}
.zoom__img{position:absolute;left:0;top:0;max-width:none;transform-origin:0 0;user-select:none;-webkit-user-drag:none}
.zoom__bar{position:absolute;z-index:2;left:50%;bottom:max(18px, env(safe-area-inset-bottom));transform:translateX(-50%);display:flex;gap:6px;padding:6px;border-radius:999px;background:rgba(18,17,16,.92);box-shadow:0 10px 30px rgba(0,0,0,.5)}
.zoom__bar button{min-width:44px;height:44px;padding:0 14px;border:0;border-radius:999px;background:transparent;color:var(--on-ink);font:700 1rem/1 var(--grot);cursor:pointer}
.zoom__bar button:hover{background:#2A282E}
.zoom__bar button:focus-visible{outline:3px solid var(--gold);outline-offset:0}
.zoom__close{position:absolute;z-index:2;right:16px;top:max(16px, env(safe-area-inset-top));height:44px;padding:0 18px;border:0;border-radius:999px;background:var(--gold);color:var(--ink);font:700 1rem/1 var(--grot);cursor:pointer}
.zoom__close:focus-visible{outline:3px solid var(--on-ink);outline-offset:3px}
.zoom__help{position:absolute;z-index:2;left:16px;top:max(22px, env(safe-area-inset-top));margin:0;font-size:.875rem;color:var(--on-ink-2)}
@media (max-width:599px){.zoom__help{display:none}}
/* Full-length Tom (tom-full-*), e.g. pointing to the chat button in "Try it now". */
.speaker__art--tall{width:min(62%, 250px);aspect-ratio:582/1200}
@media (min-width:900px){.speaker__art--tall{width:min(70%, 290px)}}

/* ---------- One Tom on screen ----------
   While the chat is open, the page's own characters and their speech bubbles fade out, so the only Tom on
   screen is the one talking. Opacity only (then hidden, so nothing behind can be clicked); kept under reduced motion. */
:is(.speaker,.card__art:not(.card__art--sign),.demo__art:has(img[src*="/characters/"]),.about-art,.handoff__stage,.next,.soon > img,.hero .tom,.hero .bubble){transition:opacity .25s ease,visibility 0s linear 0s}
body:has(> .cw[data-open="true"]) :is(.speaker,.card__art:not(.card__art--sign),.demo__art:has(img[src*="/characters/"]),.about-art,.handoff__stage,.next,.soon > img,.hero .tom,.hero .bubble){opacity:0;visibility:hidden;transition:opacity .25s ease,visibility 0s linear .25s}
/* Phones and tablets (below 1024px, where the chat's Tom stands on top of the panel): the open chat sits on a
   page-coloured veil, so its Tom never stands over the wordmark or the page text. */
@media (max-width:1023px){
  body::after{content:"";position:fixed;inset:0;z-index:2147482990;background:var(--bg);opacity:0;visibility:hidden;pointer-events:none;transition:opacity .25s ease,visibility 0s linear .25s}
  body:has(> .cw[data-open="true"])::after{opacity:1;visibility:visible;transition:opacity .25s ease}
}

/* ---------- Demos: "Want one for your place?" ---------- */
.demo--cta{border:2px solid var(--gold);background:var(--card)}
.band .demo--cta{background:var(--night)}
.demo--cta .h3{font:var(--hd-weight) clamp(1.6rem, 2.4vw, 2rem)/1.1 var(--hd-font);letter-spacing:var(--hd-ls)}
.demo--cta .demo__body{justify-content:center;gap:4px;padding:28px}
.demo__cta{align-self:flex-start;margin-top:14px;min-height:48px}
.demo--cta .demo__do a{position:relative;z-index:1}

/* Phones and tablets: every control is at least 44px tall to tap (card links also cover their whole card). */
@media (max-width:767px){
  .menu-btn,.replay,.ask,button#skip{min-height:44px}
  .card__link,.demo__go{display:inline-flex;align-items:center;min-height:44px}
}
/* The home hero's "Skip" button steps aside while the chat is open, too. */
body:has(> .cw[data-open="true"]) button#skip{opacity:0;visibility:hidden}

/* ---------- Shop Window Guide: the two ways to have one ---------- */
.sw-prices{margin:18px 0 0}
.sw-prices strong{font:var(--hs-weight) 1.25rem/1.3 var(--hs-font);letter-spacing:var(--hs-ls);margin-bottom:4px;font-variant-numeric:tabular-nums}
.band .sw-prices li{color:var(--on-ink-2)}
.band .sw-prices strong{color:var(--on-ink)}
.sw-popup{margin-top:18px}
.band .sw-popup{color:var(--on-ink-2)}
.band .sw-popup a{color:var(--gold)}
.band .sw-popup a:hover{color:var(--on-ink)}

/* ---------- The round chat button never covers content ----------
   It's fixed in the bottom-right corner (68px, 20px from the edges). From 768px the page content stops short of
   it: the right-hand padding grows just enough, and only when the content would otherwise reach the corner. */
@media (min-width:768px){
  :is(main, .site-foot) .wrap{padding-right:max(16px, calc(6.5rem - max(0px, (100vw - 76rem) / 2)))}
}
/* Phones: a 56px button (still over the 44px minimum) tucked 12px into the corner, and room under the footer so
   the end of every page scrolls fully clear of it. */
@media (max-width:767px){
  body .cw:not([data-open="true"]){right:12px;bottom:calc(12px + env(safe-area-inset-bottom,0px))}
  body .cw-launch{width:3.5rem;height:3.5rem}
  .site-foot{padding-bottom:calc(5rem + env(safe-area-inset-bottom,0px))}
}
/* The home hero's "Skip" button moves to the bottom-left corner, so it never shares a corner with the chat button. */
button#skip{right:auto;left:16px}
