/* ═══════════════════════════════════════════════════════════════════════
   Lindy customer case study — shared stylesheet
   Tokens are lifted verbatim from the homepage :root, so these pages drop
   into the existing site with no palette reconciliation.
   ═══════════════════════════════════════════════════════════════════════ */
:root{
  --bg:#FCFBF8; --navy:#0F3547; --blue:#2A66FF; --gold:#F5AD18;
  --border:#EFEDE8; --border-light:#E7E5DE;
  --text:#0F1E28; --text-mid:rgba(15,30,40,.80); --text-dim:rgba(15,30,40,.62);
  --paper:#F4EFE7;
  /* Photo mat: the homepage amber family. NOT the coral from Glean's card,
     which has no basis in Lindy's palette. */
  --mat:linear-gradient(135deg,#F7B844,#FBD87A 46%,#FDF8EC);
  --ease:cubic-bezier(.22,1,.36,1);
  /* ONE container convention for the whole page — every top-level block is
     .wrap, so left/right content edges line up from hero to footer. */
  --shell:1200px; --gutter:clamp(20px,5vw,64px);
}
.wrap{max-width:var(--shell); margin:0 auto; padding-left:var(--gutter); padding-right:var(--gutter)}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0; background:var(--bg); color:var(--text); font-family:'Manrope',sans-serif;
  letter-spacing:-.01em; -webkit-font-smoothing:antialiased; overflow-x:hidden}
img{max-width:100%; display:block}
button{font:inherit; cursor:pointer; border:0; background:none; color:inherit}
a{color:inherit}

/* Visible keyboard focus. The tabs and rail links are real buttons/anchors so
   they were already reachable, but with no focus ring a keyboard user cannot
   see where they are — sherpa-pages' quality gate requires visible focus.
   :focus-visible keeps mouse clicks free of rings. */
.csx :focus-visible{outline:2px solid var(--blue); outline-offset:3px; border-radius:6px}
.csx .ba-tabs button:focus-visible,
.csx .walk-nav button:focus-visible{outline-offset:2px}
.csx .endcta a:focus-visible{outline-color:var(--gold)}   /* light ring on navy */

/* product screenshots — a soft frame so a white-bg PNG doesn't bleed into cream */
.shot{border-radius:14px; overflow:hidden; border:1px solid var(--border-light);
  background:#fff; box-shadow:0 12px 34px rgba(15,53,71,.09)}
.shot img{width:100%; height:auto}
.shot--tall img{max-height:440px; object-fit:cover; object-position:top}
.shotcap{margin:9px 0 0; font-size:11.5px; color:var(--text-dim); font-weight:500; text-align:right}

/* ═══════════ BRAND PANEL ═══════════
   The hero visual for a study with no honest product scene. Some stories have
   no on-era screenshot: every support/helpdesk image we hold is a workflow
   builder canvas, which contradicts the current product. A customer's own
   wordmark on their own brand colour beats both a misleading screenshot and a
   stock photo. Set --panel per page; the logo is INLINE svg, not <img>, so it
   can be recoloured to sit on the panel. */
.logopanel{border-radius:14px; display:grid; place-items:center; min-height:300px;
  padding:clamp(32px,5vw,60px); background:var(--panel,var(--navy))}
.logopanel svg,.logopanel img{width:min(76%,400px); height:auto}
/* A square glyph at 400px wide dwarfs a wordmark at the same width.
   Cap square-ish marks by height instead. */
.logopanel img[width="317"]{width:auto; max-height:190px}
.logopanel--invert svg path{fill:#fff}
/* Raster wordmarks can't be recoloured per-path. A black-on-transparent
   PNG inverts cleanly to white; alpha is preserved. */
.logopanel--invert img{filter:invert(1)}
/* Light variant: coloured wordmarks, and rasters with a white background
   baked in (Tiddle's), must not be recoloured or inverted. Matches the
   .shot frame so it sits consistently beside product scenes. */
.logopanel--light{background:#fff; border:1px solid var(--border-light);
  box-shadow:0 12px 34px rgba(15,53,71,.09)}

/* ═══════════ FULL-WIDTH SCENE ═══════════
   A dense product screenshot in the hero's side column renders at ~0.31x — a
   1760px Slack scene squeezed into 543px, putting its own type under 5px. Given
   its own full-width block it renders around 0.7x and becomes readable. Use
   this for any scene too detailed for the side-by-side slot; keep the
   side-by-side one for simple scenes. */
/* Capped and centred, not edge to edge. Full content width renders this
   scene at 0.68x but makes it dominate the page; ~900px keeps its type
   readable without the screenshot outweighing the story. */
.scene{padding:8px 0 0}
.scene .shot{max-width:900px; margin:0 auto}
.scene .shot img{width:100%; height:auto; max-height:none}
.scene .shotcap{max-width:900px; margin-left:auto; margin-right:auto}

/* the matted portrait — gradient pad peeking out at the corners, not a border */
.mat{padding:10px; border-radius:16px; background:var(--mat); display:inline-block}
.mat img{border-radius:8px; display:block}

.reveal{opacity:0; transform:translateY(22px); transition:opacity .7s var(--ease), transform .7s var(--ease)}
.reveal.in{opacity:1; transform:none}
.reveal[data-d="1"]{transition-delay:.08s}
.reveal[data-d="2"]{transition-delay:.16s}
.reveal[data-d="3"]{transition-delay:.24s}

.prog{position:fixed; top:0; left:0; height:3px; z-index:300;
  background:linear-gradient(90deg,var(--gold),var(--blue)); width:0; transition:width .1s linear}

/* ═══════════ HERO ═══════════
   `.hero` is the ONE class name that collides with lindy.ai's global CSS, which
   sets `.hero { height:110vh; display:flex; align-items:flex-start }`. On a
   1035px-tall window that forced the hero to 1139px and left ~500px of dead
   cream under the content — the "why is there so much white space" report.
   It never showed locally, because locally there is no site chrome.
   The `.csx` scope beats the site's bare `.hero`, and the resets below undo
   what leaks through. Keep `class="csx"` on <body>. */
.csx .hero,
.hero{
  background:var(--bg); position:relative; overflow:hidden; padding:152px 0 104px;
  height:auto; min-height:0; display:block;
  width:auto; justify-content:normal; align-items:normal;
}
.hero::before{content:''; position:absolute; left:-10%; top:-34%; width:66%; aspect-ratio:1;
  border-radius:50%; background:radial-gradient(circle,rgba(245,173,24,.13),transparent 66%)}
.hero::after{content:''; position:absolute; right:-14%; top:-20%; width:56%; aspect-ratio:1;
  border-radius:50%; background:radial-gradient(circle,rgba(42,102,255,.07),transparent 68%)}
.hero-in{position:relative; z-index:1; display:grid;
  grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr); gap:clamp(28px,5vw,64px); align-items:center}
.brandline{display:flex; align-items:center; gap:14px; margin-bottom:28px; flex-wrap:wrap}
.brandline img{height:26px; width:auto}
.brandline a{display:block; transition:opacity .18s ease}
.brandline a:hover{opacity:.72}
.brandline span{font-size:11.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--text-dim); padding-left:14px; border-left:1px solid var(--border-light)}
/* Light 300 is deliberate, not an oversight — it's the Glean-derived editorial
   look these pages were designed around. Note it does NOT match lindy.ai's own
   display type, which sets every other h1 (/case-studies, the "Ready when you
   are." CTA) at Manrope 700 / ~71px. Bumping to 600 / 62px was tried on
   2026-09-07 and rejected: it reads closer to the site but pushes Percepture's
   quote from 5 lines to 6 and grows the hero ~100px. Keep 300 unless that
   tradeoff is revisited on purpose. */
.hero h1{margin:0; font-size:clamp(31px,4.1vw,52px); line-height:1.07; letter-spacing:-.03em;
  font-weight:300; color:var(--navy); text-wrap:balance}
.hero h1 em{font-style:normal; font-weight:400;
  background:linear-gradient(180deg,#F7B844,#C68809);
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent}
/* A study may open on a customer quote instead of an editorial line, which needs
   an attribution sitting directly under the h1. Deliberately matched to
   `.quote cite` — same job, so it should read the same. Additive: only Percepture
   uses this today, and pages without it are unaffected. */
.hero-attrib{margin:26px 0 0; font-size:14.5px; line-height:1.55; color:var(--text-dim);
  font-weight:500}
.hero-attrib b{display:block; color:var(--text); font-weight:600}
/* `.hero` prefix is load bearing — do not "simplify" it away. A rule in the site's
   shared CSS sits between `.hero-attrib a` (0,1,1) and `.quote cite a` (0,2,1) and
   re-underlines the link, which is why the mid-page quote renders clean and this
   did not. Matching `.quote cite a`'s specificity is the fix. */
.hero .hero-attrib a{color:var(--blue); text-decoration:none; font-weight:600}
.hero .hero-attrib a:hover{text-decoration:underline}
.hero-sub{margin:22px 0 0; font-size:16.5px; line-height:1.6; color:var(--text-mid); max-width:46ch}
/* When an attribution intervenes, the descriptive paragraph needs more air or the
   two blocks read as one run-on caption. */
.hero-attrib + .hero-sub{margin-top:26px}
.hero-cta{display:flex; flex-wrap:wrap; gap:11px; align-items:center; margin-top:32px}
.btn{display:inline-flex; align-items:center; gap:8px; padding:14px 28px; border-radius:12px;
  font-size:15px; font-weight:600; text-decoration:none;
  transition:transform .18s var(--ease), background .18s ease, border-color .18s ease}
.btn-p{background:var(--blue); color:#fff}
.btn-p:hover{background:#1a52e0; transform:translateY(-2px)}
.btn-s{border:1px solid var(--border-light); color:var(--navy); background:#FCFBF8}
.btn-s:hover{border-color:#CFD6DB; transform:translateY(-2px)}

/* ═══════════ STATS ═══════════ */
.stats{position:relative; z-index:5}
.stats-in{display:grid; grid-template-columns:repeat(3,1fr); gap:1px;
  background:var(--border-light); border:1px solid var(--border-light);
  border-radius:18px; overflow:hidden; box-shadow:0 16px 48px rgba(15,53,71,.10)}
.stat{background:#FCFBF8; padding:30px 28px; transition:background .2s ease}
.stat:hover{background:#fff}
.stat b{display:block; font-size:clamp(31px,3.5vw,44px); line-height:1; font-weight:400;
  letter-spacing:-.035em; color:var(--navy); white-space:nowrap; font-variant-numeric:tabular-nums}
/* data-suf rides at full size ("K","%","x"); <u> is the demoted unit ("/mo","min") */
.stat b u{text-decoration:none; font-size:.44em; font-weight:600; color:var(--text-dim); margin-left:.14em}
.stat span{display:block; margin-top:11px; font-size:13.5px; line-height:1.45;
  color:var(--text-dim); font-weight:500; max-width:24ch}
.stats-note{margin:14px 0 0; font-size:12.5px; color:var(--text-dim); font-weight:500; text-align:center}

/* ═══════════ SHELL + RAIL ═══════════ */
.shell{display:grid; grid-template-columns:170px minmax(0,1fr); gap:clamp(28px,5vw,76px); align-items:start}
.rail{position:sticky; top:76px; padding-top:80px}
.rail-h{font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.1em;
  color:var(--text-dim); margin:0 0 14px}
.rail a{display:block; padding:8px 0 8px 16px; position:relative; font-size:14px; font-weight:500;
  color:var(--text-dim); text-decoration:none; transition:color .16s ease}
.rail a::before{content:''; position:absolute; left:0; top:50%; transform:translateY(-50%);
  width:5px; height:5px; border-radius:50%; background:var(--border-light); transition:all .18s var(--ease)}
.rail a:hover{color:var(--text)}
.rail a.on{color:var(--navy); font-weight:700}
.rail a.on::before{background:var(--gold); transform:translateY(-50%) scale(1.6)}
.body{min-width:0; padding:104px 0 60px}

/* ═══════════ SECTIONS ═══════════ */
.sec{padding:74px 0; border-top:1px solid var(--border-light)}
.sec:first-child{border-top:0; padding-top:0}
.sec-h{margin:0 0 10px; font-size:clamp(27px,3.3vw,38px); line-height:1.1;
  letter-spacing:-.03em; font-weight:300; color:var(--navy)}
.thesis{margin:0 0 22px; font-size:14.5px; font-weight:700; line-height:1.5; color:var(--text)}
.sec p{margin:0 0 17px; font-size:16px; line-height:1.7; color:var(--text-mid); max-width:62ch}
.sec p:last-child{margin-bottom:0}
.handoff{margin:24px 0 0 !important; font-size:16.5px; font-weight:700; color:var(--navy)}

/* ═══════════ AT A GLANCE ═══════════
   Explicit 6-col grid, not auto-fit — auto-fit orphans the last card and
   stacks its chips vertically in a narrow box. */
.glance{display:grid; grid-template-columns:repeat(6,1fr); gap:14px; margin-top:26px}
.glance > *{grid-column:span 2}
.glance > .g-wide{grid-column:span 3}
.gcard{border:1px solid var(--border-light); border-radius:15px; padding:18px; background:#FCFBF8;
  transition:transform .2s var(--ease), box-shadow .2s var(--ease)}
.gcard:hover{transform:translateY(-3px); box-shadow:0 10px 28px rgba(15,53,71,.09)}
.gcard h4{margin:0 0 11px; font-size:10.5px; font-weight:700; text-transform:uppercase;
  letter-spacing:.09em; color:var(--text-dim)}
.gcard .v{font-size:15.5px; font-weight:600; color:var(--navy); line-height:1.4}
.chips{display:flex; flex-wrap:wrap; gap:6px; margin-top:2px}
.chips i{font-style:normal; font-size:12.5px; font-weight:600; color:var(--navy);
  background:#F1EFEA; border-radius:7px; padding:4px 9px}

/* ═══════════ BEFORE / AFTER ═══════════ */
.ba-tabs{display:inline-flex; gap:4px; padding:4px; background:#F1EFEA; border-radius:999px; margin-bottom:24px}
.ba-tabs button{padding:9px 20px; border-radius:999px; font-size:14px; font-weight:600;
  color:var(--text-dim); transition:all .2s var(--ease)}
.ba-tabs button.on{background:var(--navy); color:#FCFBF8}
.ba-panel{display:none}
.ba-panel.on{display:grid; grid-template-columns:1fr minmax(0,.82fr); gap:32px;
  align-items:center; animation:fade .45s var(--ease)}
/* A panel with only one child was still laying out two columns, so its prose
   wrapped narrow against an empty half. Collapse to one column automatically
   rather than needing a modifier class per page. */
.ba-panel.on:has(> :only-child){grid-template-columns:1fr}
@keyframes fade{from{opacity:0; transform:translateY(10px)}to{opacity:1; transform:none}}
.painlist{margin:18px 0 0; padding:0; list-style:none}
.painlist li{display:flex; gap:11px; align-items:flex-start; padding:9px 0;
  font-size:15.5px; line-height:1.5; color:var(--text-mid)}
.painlist i{flex:none; width:19px; height:19px; border-radius:50%; display:grid; place-items:center;
  margin-top:2px; font-style:normal; font-size:11px; font-weight:800}
.painlist .bad i{background:rgba(214,69,69,.12); color:#C0392B}
.painlist .good i{background:rgba(30,150,90,.13); color:#1E8A55}

/* the "N things → 1 assistant" tally, for before/after states with no screenshot */
.tally{border:1px solid var(--border-light); border-radius:16px; background:#FCFBF8; padding:22px}
.tally h5{margin:0 0 15px; font-size:10.5px; font-weight:700; text-transform:uppercase;
  letter-spacing:.09em; color:var(--text-dim)}
.tally-rows{display:grid; gap:8px}
.trow{display:flex; align-items:center; gap:11px; padding:12px 14px; border-radius:10px;
  border:1px solid var(--border-light); background:#fff;
  font-size:14.5px; font-weight:600; color:var(--navy)}
.trow em{margin-left:auto; font-style:normal; font-size:12px; font-weight:600; color:#C0392B}
.trow img{width:22px; height:22px; border-radius:5px}
.trow--one{border-color:rgba(245,173,24,.5); background:linear-gradient(120deg,#FFF9EE,#FDF8EC)}
.trow--one em{color:#1E8A55}
/* Scoped to .tally (0,2,0) so it outranks `.sec p` (0,1,1) above — as a bare
   `.tally-foot` its margin-top never applied, which is why the row sat flush
   against the last tally row. */
.tally .tally-foot{margin:24px 0 0; font-size:13px; font-weight:600; color:var(--text-dim)}

/* ═══════════ HEADLINE STATE ═══════════
   For the single claim a page is really making. Reads as a statement rather
   than a card — used where the "after" state is the whole point of the study. */
.bigstate{margin:0; padding:clamp(26px,3.4vw,40px); border-radius:20px;
  background:var(--paper); display:grid; gap:16px; align-content:center}
.bigstate b{display:block; font-weight:300; line-height:1.08; letter-spacing:-.03em;
  color:var(--navy); font-size:clamp(27px,3.4vw,40px)}
.bigstate p{margin:0; font-size:15px; line-height:1.55; color:var(--text-mid); max-width:52ch}
.bigstate .chips i{background:#fff; border:1px solid var(--border-light)}

/* ═══════════ WALKTHROUGH ═══════════ */
.walk-nav{display:flex; flex-wrap:wrap; gap:9px; margin-bottom:26px}
.walk-nav button{display:flex; align-items:center; gap:9px; padding:11px 17px 11px 12px;
  border:1px solid var(--border-light); border-radius:12px; background:#FCFBF8;
  font-size:14px; font-weight:600; color:var(--text-dim); transition:all .2s var(--ease)}
.walk-nav button em{font-style:normal; font-size:11px; font-weight:800; color:#B9BFC4;
  font-variant-numeric:tabular-nums}
.walk-nav button:hover{border-color:#CFD6DB; color:var(--text)}
.walk-nav button.on{background:var(--navy); border-color:var(--navy); color:#FCFBF8}
.walk-nav button.on em{color:var(--gold)}
.walk-panel{display:none}
.walk-panel.on{display:block; animation:fade .5s var(--ease)}
.walk-grid{display:grid; grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr); gap:32px; align-items:center}
.walk-panel h3{margin:0 0 13px; font-size:21px; font-weight:400; letter-spacing:-.02em; color:var(--navy)}
.walk-panel p{font-size:15.5px; margin-bottom:0}
/* Scoped to .walk-panel (0,2,0) so it outranks `.sec p` (0,1,1) above. As a
   bare `.walk-quote` the margin-top never applied and the quote sat flush
   against the paragraph — same trap as `.tally-foot`. */
.walk-panel .walk-quote{margin:28px 0 0; padding:14px 17px; border-left:2px solid var(--gold);
  background:rgba(245,173,24,.06); border-radius:0 10px 10px 0;
  font-size:14.5px; line-height:1.55; color:var(--text); font-weight:500}

/* ═══════════ RESULTS ═══════════ */
.results{margin:24px 0 0; padding:0; list-style:none; display:grid; gap:11px}
.results li{display:flex; gap:14px; align-items:flex-start; padding:17px 19px;
  border:1px solid var(--border-light); border-radius:13px; background:#FCFBF8;
  transition:transform .2s var(--ease), box-shadow .2s var(--ease)}
.results li:hover{transform:translateX(3px); box-shadow:0 8px 22px rgba(15,53,71,.07)}
.results b{flex:none; min-width:112px; font-size:19px; font-weight:600; color:var(--navy);
  letter-spacing:-.02em; line-height:1.25}
.results span{font-size:15px; line-height:1.55; color:var(--text-mid)}

/* ═══════════ QUOTE ═══════════
   Customer headshots are ~400x400, so the portrait gets a modest fixed
   column rather than a percentage of the card. Size to the asset. */
.quote{margin:52px 0 0; background:var(--paper); border-radius:22px;
  display:grid; grid-template-columns:1fr auto; gap:clamp(24px,4vw,44px);
  padding:clamp(26px,3.4vw,42px); align-items:center}
.quote blockquote{margin:0}
.quote q{quotes:none; display:block; font-size:clamp(17px,1.75vw,20.5px); line-height:1.5;
  letter-spacing:-.018em; color:var(--text)}
.quote cite{display:block; margin-top:30px; font-style:normal; font-size:14.5px;
  line-height:1.55; color:var(--text-dim); font-weight:500}
.quote cite b{display:block; color:var(--text); font-weight:600}
.quote cite a{color:var(--blue); text-decoration:none; font-weight:600}
.quote cite a:hover{text-decoration:underline}
.quote cite .then{display:block; margin-top:5px; font-size:13px; color:var(--text-dim)}
.quote .mat img{width:196px; height:196px; object-fit:cover}

/* a short quote pulled inline, no portrait */
.pullquote{margin:34px 0 0; padding:22px 26px; border-radius:16px; background:var(--paper)}
.pullquote q{quotes:none; display:block; font-size:17px; line-height:1.55; color:var(--text)}
.pullquote cite{display:block; margin-top:13px; font-style:normal; font-size:13.5px;
  color:var(--text-dim); font-weight:600}
/* .pullquote carries no bottom margin and .ba-tabs no top margin, so a quote
   placed directly above the tabs left them touching its edge. Scoped to the
   adjacency so Ankor's pullquote, which ends a section, is untouched. */
.pullquote + .ba-tabs{margin-top:28px}
/* Byline variant: a face beside the attribution, for a pull quote that opens a
   section. The avatar is decorative — the cite already carries the name, so
   alt="" keeps a screen reader from announcing it twice. */
.pullquote--byline .by{display:flex; align-items:center; gap:13px; margin-top:16px}
.pullquote--byline .by img{width:46px; height:46px; border-radius:50%; object-fit:cover;
  flex:none; border:2px solid #fff; box-shadow:0 2px 8px rgba(15,53,71,.12)}
.pullquote--byline cite{margin-top:0}


/* Full-bleed glance card, for a list that reads better across than stacked. */
.glance > .g-full{grid-column:span 6}
.g-full .chips i{font-size:13.5px; padding:6px 12px}

/* ═══════════ STACK ═══════════ */
.stack{display:grid; grid-template-columns:repeat(auto-fill,minmax(78px,1fr)); gap:11px; margin-top:24px}
.stack figure{margin:0; border:1px solid var(--border-light); border-radius:13px; background:#fff;
  aspect-ratio:1; display:grid; place-items:center; padding:17px;
  transition:transform .2s var(--ease), box-shadow .2s var(--ease)}
.stack figure:hover{transform:translateY(-4px); box-shadow:0 10px 22px rgba(15,53,71,.12)}
.stack img{width:100%; height:auto; max-height:34px; object-fit:contain}

/* ═══════════ FUTURE + END CTA ═══════════ */
.future{border-radius:20px; padding:clamp(24px,3vw,36px); border:1px solid var(--border-light);
  background:linear-gradient(150deg,rgba(245,173,24,.11),rgba(42,102,255,.07) 62%,rgba(15,53,71,.045))}
.future-note{margin:18px 0 0 !important; padding-top:16px;
  border-top:1px solid rgba(15,53,71,.10);
  font-size:14.5px !important; color:var(--text-dim) !important}
.future-note strong{color:var(--navy)}
.future h3{margin:0 0 13px; font-size:19px; font-weight:700; letter-spacing:-.02em; color:var(--navy)}
.endcta{margin:34px 0 0; padding:56px clamp(24px,4vw,46px); border-radius:22px;
  background:var(--navy); color:#FCFBF8; text-align:center; position:relative; overflow:hidden}
.endcta::after{content:''; position:absolute; left:50%; bottom:-60%; transform:translateX(-50%);
  width:70%; aspect-ratio:1; border-radius:50%;
  background:radial-gradient(circle,rgba(245,173,24,.18),transparent 66%)}
.endcta h2{margin:0 0 11px; font-size:clamp(25px,2.9vw,33px); font-weight:300;
  letter-spacing:-.03em; position:relative; z-index:1}
.endcta p{margin:0 0 25px; font-size:15.5px; color:rgba(252,251,248,.72); position:relative; z-index:1}
.endcta .row{display:flex; gap:11px; justify-content:center; flex-wrap:wrap; position:relative; z-index:1}
.endcta .btn{position:relative; z-index:1}
.endcta .btn-s{border-color:rgba(252,251,248,.32); color:#FCFBF8; background:transparent}
.endcta .btn-s:hover{background:rgba(252,251,248,.1)}

/* ═══════════ RESPONSIVE ═══════════ */
@media (max-width:980px){
  .hero-in{grid-template-columns:1fr; gap:34px}
  .shell{grid-template-columns:1fr; gap:0}
  .rail{display:none}
  .body{padding-top:52px}
  .ba-panel.on,.walk-grid{grid-template-columns:1fr; gap:24px}
  .quote{grid-template-columns:1fr; gap:24px}
  .quote .mat{justify-self:start}
  .shotcap{text-align:left}
}
@media (max-width:640px){
  .stats-in{grid-template-columns:1fr}
  .stat{padding:22px}
  .hero{padding:104px 0 40px}
  .sec{padding:52px 0}
  .glance{grid-template-columns:1fr}
  /* `.g-full` MUST be listed here. It is `grid-column:span 6` at 0,2,0, so the
     `.glance > *` reset at 0,1,0 does not reach it — and a span-6 item inside a
     1fr grid GENERATES five implicit columns rather than being clamped. That blew
     the row to 615px inside a 335px viewport, and `page_wrap` is `overflow-x:clip`
     (not `hidden`), so the overshooting cards could not be scrolled to at all.
     Only Percepture uses `.g-full`, which is why this hid on one page. */
  .glance > *,.glance > .g-wide,.glance > .g-full{grid-column:auto}
  .results li{flex-direction:column; gap:6px}
  .results b{min-width:0}
  .quote .mat img{width:152px; height:152px}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{transition:none !important; animation:none !important}
  .reveal{opacity:1 !important; transform:none !important}
}
