/* ==========================================================================
   NEXYL — styles.css
   Tokens first: edit these to retheme the whole site.
   ========================================================================== */

/* ==========================================================================
   TYPEFACE — Inter Display, self-hosted
   ONE family for the entire site. There is no serif and no mono any more:
     italic accents  ->  font-weight:500 + font-style:italic
     micro-labels    ->  font-weight:500 + uppercase + var(--track-label)
   Do NOT reintroduce Hanken Grotesk, Instrument Serif or Fragment Mono, and
   do not add a Google Fonts <link> — the site loads no external fonts.
   The .woff2 files are subset to Latin (~20KB each, 125KB total). The full
   .ttf sources sit beside them in assets/fonts/ if a wider character range
   is ever needed; see the Progress Log for the exact subset command.
   ========================================================================== */
@font-face{font-family:'Inter Display';src:url('fonts/InterDisplay-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Inter Display';src:url('fonts/InterDisplay-Medium.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Inter Display';src:url('fonts/InterDisplay-Italic.woff2') format('woff2');font-weight:400;font-style:italic;font-display:swap}
@font-face{font-family:'Inter Display';src:url('fonts/InterDisplay-MediumItalic.woff2') format('woff2');font-weight:500;font-style:italic;font-display:swap}
@font-face{font-family:'Inter Display';src:url('fonts/InterDisplay-SemiBold.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'Inter Display';src:url('fonts/InterDisplay-Bold.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'Inter Display';src:url('fonts/InterDisplay-ExtraBold.woff2') format('woff2');font-weight:800;font-style:normal;font-display:swap}

:root{
  --bg:#EFEEEC; /* live-site canvas: light neutral grey (was warm cream #FAF8F4) */
  --ink:#191713;
  --ink-soft:#615C52; /* was --body; renamed — --body is now the type size */
  --word-muted:#C6BFB2;
  --card:#FFFFFF;
  --line:rgba(25,23,19,.10);
  --dark:#141210;
  --cream:#FAF8F4;

  --orange:#F5511E;
  --blue:#0A97FF;
  --green:#37C26B;
  --pink:#FF4DAB;
  --yellow:#FFCF2B;

  /* one family, one token — see the TYPEFACE block above */
  --sans:'Inter Display',system-ui,-apple-system,sans-serif;
  /* tracking for uppercase micro-labels (was Fragment Mono's job) */
  --track-label:.14em;

  /* ------------------------------------------------------------------
     TYPE SCALE — measured off the live Framer site (nexyl.framer.website)
     at 1440px AND 375px, not invented. Every text element on every page
     maps to exactly one of these. Never hand-set a font-size again.

       token          375px -> 1440px   line-height   tracking
       --h1            44 -> 108           1.1          -.06em
       --h2            28 ->  48           1.4          -.04em
       --h3            18 ->  24           1.6          -.02em
       --h4            18 ->  20           1.5          -.02em
       --lil-serif     24 (fixed)          1.2           0
       --body          16 (fixed)          1.7           0
       --big-number    44 ->  72           1.3          -.06em
       --small         12 (fixed)          1.5           0

     Tracking is a function of OPTICAL SIZE, not weight: big type needs it
     pulled in, 16px and below needs none. That is exactly what live does.
     ------------------------------------------------------------------ */
  --h1:clamp(2.75rem,1.34rem + 6.01vw,6.75rem);
  --h2:clamp(1.75rem,1.31rem + 1.88vw,3rem);
  --h3:clamp(1.125rem,.99rem + .56vw,1.5rem);
  --h4:clamp(1.125rem,1.08rem + .19vw,1.25rem);
  --lil-serif:1.5rem;
  --body:1rem;
  --big-number:clamp(2.75rem,2.13rem + 2.63vw,4.5rem);
  --small:.75rem;

  --h1-lh:1.1;         --h1-track:-.06em;
  --h2-lh:1.4;         --h2-track:-.04em;
  --h3-lh:1.6;         --h3-track:-.02em;
  --h4-lh:1.5;         --h4-track:-.02em;
  --lil-serif-lh:1.2;  --lil-serif-track:0;
  --body-lh:1.7;       --body-track:0;
  --big-number-lh:1.3; --big-number-track:-.06em;
  --small-lh:1.5;      --small-track:0;

  /* WEIGHTS, measured off live: 400 is the default for almost everything.
     500 = hero strong words, buttons, testimonial name, logo, case title.
     700 = the gallery CTA bubble only. NOTHING on this site is 800. */

  /* Deliberately off-scale, do not "fix": .logo-strip / .lg / .testi__mark are
     em-relative so they track their parent; .wordmark is a decorative
     graphic, not text. Everything else on both pages uses a token above. */

  --r:22px;
  --container:1180px;
  --pad:clamp(20px,4vw,44px);
  --sect:clamp(90px,12vw,150px);
  --ease:cubic-bezier(.22,.8,.24,1);
  --shadow:0 20px 50px -22px rgba(25,23,19,.28);
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  font-family:var(--sans);
  background:var(--bg);
  color:var(--ink);
  font-size:var(--body);
  line-height:var(--body-lh);
  /* Inter Display sets wider than Hanken Grotesk at text sizes */
  letter-spacing:var(--body-track);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;font-weight:400;}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
.container{max-width:var(--container);margin:0 auto;padding:0 var(--pad)}
.section{padding:calc(var(--sect)*.55) 0}
::selection{background:var(--ink);color:var(--bg)}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:6px}

/* ===== Type helpers ===== */
/* Italic accent, not a mono micro-label: keeps its size and italic character,
   only the family changes. */
.eyebrow{
  font-family:var(--sans);font-style:italic;font-weight:400;
  font-size:var(--lil-serif);line-height:var(--lil-serif-lh);letter-spacing:var(--lil-serif-track);
  display:inline-flex;align-items:center;gap:.55em;margin-bottom:18px;
}
.eyebrow::before{content:"";width:30px;height:1px;background:var(--ink);opacity:.45}
.section-title{
  font-size:var(--h2);font-weight:400;
  letter-spacing:var(--h2-track);line-height:var(--h2-lh);margin-bottom:clamp(34px,5vw,56px);
}

/* ===== Buttons ===== */
.btn{
  display:inline-flex;align-items:center;gap:10px;
  padding:15px 28px;border-radius:999px;font-weight:500;font-size:var(--body);
  transition:transform .35s var(--ease),background .3s var(--ease),color .3s var(--ease),box-shadow .35s var(--ease);line-height:var(--body-lh);letter-spacing:var(--body-track);}
.btn svg{width:18px;height:18px;transition:transform .35s var(--ease)}
.btn:hover svg{transform:translateX(4px)}
.btn-primary{background:var(--ink);color:var(--cream)}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 14px 30px -14px rgba(25,23,19,.5)}
.btn-ghost{background:var(--card);color:var(--ink);border:1px solid var(--line)}
.btn-ghost:hover{transform:translateY(-2px);box-shadow:var(--shadow)}

/* ==========================================================================
   NAV — ONE unified dark pill holding, left to right: the wordmark, the
   "Book A Call" CTA and the menu toggle. The menu panel drops directly
   beneath the bar and the bar stays visible above it.
   Open/close timing is unchanged from the previous menu (.35s, var(--ease)).
   ========================================================================== */
.nav{
  position:fixed;inset:0 0 auto 0;z-index:100;
  display:flex;justify-content:center;
  padding:18px clamp(16px,3vw,28px);
  pointer-events:none;   /* only the bar and the open menu are clickable */
}
/* The bar HUGS its contents and sits centred - it is a compact pill, NOT a
   full-width band. min-width only exists to give the dropdown enough room for
   the large menu links; on phones it collapses to the available width. */
.nav__inner{
  position:relative;
  width:max-content;
  min-width:min(420px,calc(100vw - 32px));
  max-width:calc(100vw - 32px);
}

.navbar{
  position:relative;z-index:2;pointer-events:auto;
  display:flex;align-items:center;justify-content:space-between;gap:clamp(24px,4vw,56px);
  background:var(--dark);border-radius:999px;
  padding:8px 8px 8px clamp(20px,2.4vw,30px);
  box-shadow:0 20px 50px -22px rgba(25,23,19,.5);
}
.navbar__right{display:flex;align-items:center;gap:10px}

/* wordmark sits directly on the dark bar — no pill of its own any more */
.logo-pill{
  font-size:var(--h4);line-height:var(--h4-lh);letter-spacing:var(--h4-track);
  font-weight:500;color:var(--cream);
  transition:opacity .3s var(--ease);
}
.logo-pill:hover{opacity:.72}
.logo-pill .x,.wordmark .x{font-family:var(--sans);font-style:italic;font-weight:500;color:var(--orange)}

/* lighter pill inside the black bar */
.nav-cta{
  display:inline-flex;align-items:center;white-space:nowrap;
  background:rgba(250,248,244,.14);color:var(--cream);
  border-radius:999px;padding:12px 22px;
  font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);font-weight:500;
  transition:background .3s var(--ease);
}
.nav-cta:hover{background:rgba(250,248,244,.26)}

.nav-toggle{
  width:46px;height:46px;flex:none;border-radius:50%;border:0;
  background:rgba(250,248,244,.14);
  /* flex, NOT grid: grid stretches the three rows to fill the circle, which
     pushes the bars ~15px apart and stops them meeting in the middle when
     they rotate into the x. Flex keeps the pitch at exactly 2px + 2*2.5px
     margin = 7px, which is the offset the open state below relies on. */
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  transition:background .3s var(--ease);
}
.nav-toggle:hover{background:rgba(250,248,244,.26)}
.nav-toggle span{
  display:block;width:18px;height:2px;background:var(--cream);margin:2.5px 0;
  transition:transform .35s var(--ease),opacity .25s;
}
/* open state: the three bars become an x */
body.menu-open .nav-toggle span:nth-child(1){transform:translateY(7px) rotate(45deg)}
body.menu-open .nav-toggle span:nth-child(2){opacity:0}
body.menu-open .nav-toggle span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* the panel: same width as the bar, dropping from just under it */
.menu{
  position:absolute;top:calc(100% + 10px);left:0;right:0;z-index:1;
  background:var(--dark);border-radius:32px;
  padding:clamp(40px,6vw,66px) clamp(24px,4vw,40px) clamp(30px,4vw,42px);
  box-shadow:0 30px 70px -30px rgba(25,23,19,.6);
  opacity:0;transform:translateY(-12px) scale(.96);transform-origin:top center;
  pointer-events:none;
  transition:opacity .35s var(--ease),transform .35s var(--ease);
}
.menu.open{opacity:1;transform:none;pointer-events:auto}
.menu__links{display:flex;flex-direction:column;align-items:center}
.menu__links a{
  display:block;padding:5px 0;text-align:center;
  font-size:var(--h2);line-height:var(--h2-lh);letter-spacing:var(--h2-track);font-weight:500;
  color:rgba(250,248,244,.5);
  transition:color .25s var(--ease);
}
.menu__links a:hover{color:var(--cream)}
.menu__contact{text-align:center;margin-top:clamp(24px,3.5vw,34px)}
.menu__contact a{
  font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);
  font-weight:500;color:var(--cream);
  transition:color .25s var(--ease);
}
.menu__contact a:hover{color:var(--orange)}
.menu__social{display:flex;justify-content:center;gap:14px;margin-top:clamp(22px,3vw,30px)}
.menu__social a{
  width:46px;height:46px;border-radius:50%;color:var(--cream);
  border:1px solid rgba(250,248,244,.24);display:grid;place-items:center;
  transition:border-color .25s var(--ease),background .25s var(--ease),transform .25s var(--ease);
}
.menu__social a svg{width:19px;height:19px}
.menu__social a:hover{border-color:transparent;background:rgba(250,248,244,.16);transform:translateY(-2px)}

/* phones: shorten the CTA label rather than dropping the button — the call
   to action stays visible at every width */
@media (max-width:345px){
  .nav-cta__long{display:none}
  .nav-cta{padding:12px 18px}
  .navbar{padding-left:20px;gap:10px}
}

/* ==========================================================================
   HERO
   ========================================================================== */
.hero{
  position:relative;min-height:100svh;display:grid;place-items:center;
  padding:130px var(--pad) 70px;overflow:hidden;
  /* live-site treatment: neutral grey studio backdrop, no colour */
  background:linear-gradient(180deg,#E8E7E4 0%,#EDECEA 60%,var(--bg) 100%);
}
.hero__bg{position:absolute;inset:0;pointer-events:none}
.hero__blob{position:absolute;border-radius:50%;filter:blur(70px)}
.hero__blob.a{
  width:56vw;height:56vw;max-width:820px;max-height:820px;
  left:-12%;top:-18%;
  background:radial-gradient(circle at 35% 35%, rgba(25,23,19,.10), rgba(25,23,19,.04) 55%, transparent 70%);
}
.hero__blob.b{
  width:52vw;height:52vw;max-width:760px;max-height:760px;
  right:-14%;bottom:-22%;
  background:radial-gradient(circle at 60% 40%, rgba(25,23,19,.09), rgba(25,23,19,.03) 55%, transparent 72%);
}
.hero__sheen{
  position:absolute;inset:0;
  background:linear-gradient(115deg, transparent 30%, rgba(255,255,255,.75) 50%, transparent 68%);
}
.hero__noise{
  position:absolute;inset:0;background-repeat:repeat;background-size:180px;
  opacity:.4;mix-blend-mode:overlay;
}

.hero__inner{position:relative;text-align:center;max-width:1150px}
#heroHeadline{
  font-size:var(--h1);font-weight:400;
  letter-spacing:var(--h1-track);line-height:var(--h1-lh);
}
.hero__line{
  display:flex;justify-content:center;align-items:center;
  gap:.26em;flex-wrap:wrap;
}
.w.strong{color:var(--ink);font-weight:500}
.w.muted{color:var(--word-muted)}

/* -- inline hero cards -- */
.hero-card{
  position:relative;display:inline-flex;align-items:center;
  height:.92em;border-radius:.22em;overflow:hidden;
  box-shadow:var(--shadow);flex:0 0 auto;
}
.hero-card.phone{
  width:1.75em;transform:rotate(-4deg);background:var(--dark);
  cursor:grab;touch-action:none; /* vertical drag between slides */
}
.hero-card.phone:active{cursor:grabbing}
.hero-card.ticker{width:3.1em;transform:rotate(2.5deg);background:var(--dark);color:var(--cream)}
.hero-card:hover{z-index:2}

.slideshow{position:absolute;inset:0}
.slideshow img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transform:scale(1.08);
  transition:opacity .7s var(--ease),transform 1.4s var(--ease);
}
.slideshow img.on{opacity:1;transform:scale(1)}
/* while dragging the slides follow the pointer with no easing; on release
   they snap with a short transform-only transition */
.slideshow.drag img{transition:none}
.slideshow.snap img{transition:transform .45s var(--ease)}

.logo-strip{
  display:flex;align-items:center;gap:1.4em;
  font-size:.26em;white-space:nowrap;padding-left:1.4em;
  animation:ticker 14s linear infinite;
  will-change:transform;
}
.hero-card.ticker:hover .logo-strip{animation-play-state:paused}
@keyframes ticker{to{transform:translateX(-50%)}}
.lg{opacity:.92;letter-spacing:.02em}
.lg:nth-child(4n+1){font-weight:700;text-transform:lowercase}
/* four fake client wordmarks — one family now, so weight/case/tracking do all
   the differentiating */
.lg:nth-child(4n+2){font-weight:500;letter-spacing:var(--track-label)}
.lg:nth-child(4n+3){font-style:italic;font-weight:500;font-size:1.1em;letter-spacing:-.01em}
.lg:nth-child(4n+4){font-weight:500;text-transform:uppercase;letter-spacing:.3em}

.hero__sub{
  max-width:560px;margin:clamp(26px,4vw,40px) auto 0;
  font-size:var(--body);line-height:var(--body-lh);color:var(--ink-soft);letter-spacing:var(--body-track);font-weight:400;}

/* ==========================================================================
   GALLERY
   ========================================================================== */
.gallery{padding-top:0}
/* Film strip: two columns scroll forever in opposite directions. Both halves
   of a column are identical, so translating by -50% loops seamlessly — the
   same trick as the hero logo ticker. Paused until .on (set by main.js when
   the strip is on screen). */
.gallery__strip{
  position:relative;overflow:hidden;border-radius:var(--r);
  height:clamp(430px,56vw,680px);
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(14px,2vw,24px);
  /* live site wraps the strip in a dark rounded container */
  background:var(--dark);
  padding:clamp(14px,2vw,24px);
}
.gcol{display:flex;flex-direction:column}
.gcol img{
  width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:18px;
  margin-bottom:clamp(14px,2vw,24px);
  box-shadow:0 14px 34px -20px rgba(25,23,19,.3);
}
.gcol--up{animation:colUp 44s linear infinite}
.gcol--down{animation:colDown 52s linear infinite}
.gcol--all{display:none;animation:colUp 64s linear infinite}
/* after the shorthands (which reset play-state) and more specific than them */
.gallery__strip:not(.on) .gcol{animation-play-state:paused}
@keyframes colUp{to{transform:translateY(-50%)}}
@keyframes colDown{from{transform:translateY(-50%)}to{transform:none}}
.gallery__cta{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;
  display:flex;flex-direction:column;align-items:center;
}
.gallery__cta-bubble{
  position:relative;z-index:2;
  background:var(--ink);color:var(--cream);font-weight:700;font-size:var(--body);
  padding:12px 24px;border-radius:999px;white-space:nowrap;
  transform:rotate(-8deg) translateY(10px);
  box-shadow:var(--shadow);line-height:var(--body-lh);letter-spacing:var(--body-track);}
.gallery__cta-circle{
  width:clamp(96px,11vw,148px);aspect-ratio:1;border-radius:50%;
  background:var(--card);box-shadow:var(--shadow);color:var(--ink);
  display:grid;place-items:center;
}
.gallery__cta-circle svg{width:34%;height:34%}
/* no hover states anywhere in the gallery — the live site only changes the cursor */

/* ==========================================================================
   INTRO
   ========================================================================== */
.intro{position:relative;padding:var(--sect) 0;text-align:center}
.intro .container{position:relative;z-index:1;max-width:980px}
.intro__p{
  font-size:var(--h2);font-weight:400;
  letter-spacing:var(--h2-track);line-height:var(--h2-lh);
  max-width:700px;margin:0 auto;
}
.intro__p .iw{color:var(--word-muted)}

/* .pills now matches the global container width on desktop, 
   so the pills don't fly off to the screen edges on ultrawide monitors. */
.pills{
  position:absolute;inset:0;
  max-width:var(--container);margin:0 auto;
  pointer-events:none;
}
.pill-drag{
  position:absolute;z-index:2;
  cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none;
  pointer-events:auto;
}
.pill-drag.dragging{cursor:grabbing;z-index:5}
/* The pill visuals are the live-site SVG exports rendered directly — chrome,
   icon, shadow and tilt are all baked into the files, so the CSS here only
   sizes the image and keeps it inert under the pointer. */
.pill{display:block}
.pill img{
  display:block;height:clamp(48px, 6vw, 88px);width:auto;
  pointer-events:none;-webkit-user-drag:none;user-select:none;
}
/* Final resting spots, positioned by the owner in-browser. Two clean
   columns: same inset both sides, even vertical rhythm with a slight
   left/right stagger. Right-column pills are anchored by `right:` so their
   outer edges align despite the pills having different widths. */
.pill-drag.p1{top:22%;left:16px}
.pill-drag.p2{top:23%;right:16px}
.pill-drag.p3{top:46%;left:32px}
.pill-drag.p4{top:44%;right:32px}
.pill-drag.p5{top:69%;left:12px}
.pill-drag.p6{top:70%;right:12px}

/* ==========================================================================
   PROCESS
   ========================================================================== */
.process{padding:calc(var(--sect)*.4) 0 var(--sect)}
.cards{
  position:relative;
  display:grid;grid-template-columns:repeat(3,1fr);gap:0;
  /* negative margins pull the cards into each other so they overlap */
  padding:0 clamp(10px,1.4vw,20px);
}
.cards > .pcard-wrap{margin:0 -5px}
/* Each string is its own SVG at its natural aspect ratio, parked over one
   gutter, so the endpoint dots stay glued to the cards at any width. */
/* Above the cards (which stack up to z-index 3) so a string is never cut off
   where it crosses one. */
.squiggle{position:absolute;height:auto;pointer-events:none;z-index:5;overflow:visible}
.squiggle path{fill:none;stroke:var(--orange);stroke-linecap:round;stroke-linejoin:round}
/* paths carry vector-effect="non-scaling-stroke", so these render at the
   same screen weight at ANY display size — desktop and mobile now match */
.squiggle.s1 path{stroke-width:2.2}
.squiggle.s2 path{stroke-width:2.33}
/* Desktop keeps the exports' natural orientation — NO rotation. The
   92/166deg rotations belong to the MOBILE layout only (media query). */
.squiggle.s1{left:20%;top:-4px;width:min(216px,18.5%)}
.squiggle.s2{left:57.5%;top:26%;width:min(224px,19%)}

/* Animation wrapper — GSAP owns this transform, .pcard keeps its own.
   The cards overlap, so each wrapper needs its own stacking order. */
.pcard-wrap{display:flex;min-width:0}
.pcard-wrap.w1{z-index:1}
.pcard-wrap.w2{z-index:3}
.pcard-wrap.w3{z-index:2}
.pcard{
  flex:1 1 auto;min-width:0;
  display:flex;flex-direction:column;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(26px,3.2vw,40px);position:relative;
  box-shadow:0 24px 54px -30px rgba(25,23,19,.25);
}
/* Deliberately static: no hover transform. Moving a card would pull it away
   from the strings that point at its corners. */
.pcard.c1{transform:rotate(-4deg)}
.pcard.c2{transform:rotate(4.4deg) translateY(-20px)}
.pcard.c3{transform:rotate(-3.2deg) translateY(6px)}
.num{
  font-family:var(--sans);font-weight:400;
  font-size:var(--big-number);line-height:var(--big-number-lh);
  color:var(--ink);margin-bottom:auto;padding-bottom:clamp(48px,7vw,96px);letter-spacing:var(--big-number-track);}
.pcard h3{font-size:var(--h3);line-height:var(--h3-lh);font-weight:400;letter-spacing:var(--h3-track);margin-bottom:12px}
.pcard p{color:var(--ink-soft);font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);font-weight:400;}

/* ===== Testimonials ===== */
/* Reveal is deliberately NOT GSAP: main.js adds .in via IntersectionObserver
   once a block is a third visible, CSS transitions do the rest. */
.testi{position:relative;padding-right:46px;max-width:520px}
/* the quote TEXT fades in word by word (live behaviour): words start as
   ghost text and sweep to readable when the observer adds .in. Each word's
   transition-delay is set inline by main.js. The block itself never hides. */
.testi__q .tw{opacity:.12;transition:opacity .5s var(--ease)}
.testi.in .testi__q .tw{opacity:1}
/* Live layout: the two quotes are staggered diagonally — the second starts
   below where the first ends, on the right — with a thin divider between. */
.testis{
  display:grid;grid-template-columns:1fr 1px 1fr;
  gap:clamp(26px,4vw,56px);align-items:start;
  margin-top:clamp(64px,9vw,110px);
}
.testi.right{margin-top:clamp(140px,20vw,300px);justify-self:end}
.testi-div{background:var(--line);height:100%;min-height:120px;align-self:stretch}
.testi__q{
  font-size:var(--h3);font-weight:400;
  letter-spacing:var(--h3-track);line-height:var(--h3-lh);
}
/* muted grey closing mark pinned top-right, as on the live site */
.testi__mark{
  position:absolute;top:0;right:0;
  font-family:var(--sans);font-style:italic;font-weight:500;font-size:2.4em;line-height:.55;
  color:var(--word-muted);
}
.testi__who{display:flex;align-items:center;gap:14px;margin-top:24px}
.testi__who img{width:52px;height:52px;border-radius:50%;object-fit:cover}
.testi__who b{display:block;font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);font-weight:500;}
.testi__who span{color:var(--ink-soft);font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);font-weight:400;}

/* ==========================================================================
   CASES
   ========================================================================== */
.cases{padding-top:0}
.cases__grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,3vw,32px)}
/* The three case studies still in progress share a compact 3-up row below the
   two live ones, so an odd card count fills the grid instead of leaving a
   lopsided gap. They are not links yet, so no hover affordance. */
.cases__grid--soon{grid-template-columns:repeat(3,1fr);margin-top:clamp(20px,3vw,32px)}
.case{display:block}
.case--soon{cursor:default}
.case--soon:hover .case__media img{transform:none}
.case__media{
  position:relative;border-radius:var(--r);overflow:hidden;aspect-ratio:4/3;
  box-shadow:0 18px 44px -24px rgba(25,23,19,.3);
}
.case__media img{display:block;width:100%;height:100%;object-fit:cover;object-position:center;transition:transform .8s var(--ease)}
.case:hover .case__media img{transform:scale(1.05)}
.case__label{
  position:absolute;left:14px;bottom:14px;
  font-family:var(--sans);font-weight:500;font-size:var(--small);line-height:var(--small-lh);
  text-transform:uppercase;letter-spacing:var(--track-label);
  background:rgba(20,18,16,.78);color:var(--cream);
  padding:9px 14px;border-radius:999px;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
.case__foot{display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;margin-top:16px;padding:0 4px}
.case__foot h3{font-size:var(--h4);line-height:var(--h4-lh);font-weight:400;letter-spacing:var(--h4-track);}
.tags{display:flex;gap:8px;flex-wrap:wrap}
.tag{
  font-family:var(--sans);font-weight:500;font-size:var(--small);line-height:var(--small-lh);
  text-transform:uppercase;letter-spacing:var(--track-label);
  padding:7px 12px;border-radius:999px;background:#E4E2DE;color:var(--ink);
}

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq__grid{display:grid;grid-template-columns:.8fr 1.2fr;gap:clamp(26px,4vw,52px);align-items:start}
.faq__card{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:clamp(26px,3vw,36px);position:sticky;top:104px;
  box-shadow:0 24px 54px -30px rgba(25,23,19,.22);
}
.faq__card-top{display:flex;align-items:center;gap:16px;margin-bottom:24px}
.faq__card-top img{width:64px;height:64px;border-radius:50%;object-fit:cover}
.faq__card-top p{font-size:var(--body);line-height:var(--body-lh);color:var(--ink-soft);letter-spacing:var(--body-track);font-weight:400;}
.faq__card-top b{color:var(--ink)}
.faq__email{font-size:var(--body);color:var(--ink-soft);margin-top:16px;line-height:var(--body-lh);letter-spacing:var(--body-track);font-weight:400;}
.faq__email a{text-decoration:underline;text-underline-offset:3px;color:var(--ink)}

.faq__item{border-bottom:1px solid var(--line)}
.faq__item:first-child{border-top:1px solid var(--line)}
.faq__q{
  width:100%;display:flex;justify-content:space-between;align-items:center;gap:20px;
  padding:clamp(20px,2.4vw,26px) 4px;text-align:left;
  font-weight:400;font-size:var(--h3);line-height:var(--h3-lh);letter-spacing:var(--h3-track);
}
.plus{position:relative;flex:0 0 auto;width:30px;height:30px;border-radius:50%;border:1px solid var(--line);transition:background .3s,border-color .3s}
.plus::before,.plus::after{
  content:"";position:absolute;top:50%;left:50%;width:12px;height:2px;border-radius:2px;
  background:var(--ink);transform:translate(-50%,-50%);
  transition:transform .4s var(--ease),background .3s;
}
.plus::after{transform:translate(-50%,-50%) rotate(90deg)}
.faq__item.open .plus{background:var(--ink)}
.faq__item.open .plus::before,.faq__item.open .plus::after{background:var(--cream)}
.faq__item.open .plus::after{transform:translate(-50%,-50%) rotate(0deg)}
.faq__a{display:grid;grid-template-rows:0fr;transition:grid-template-rows .5s var(--ease)}
.faq__item.open .faq__a{grid-template-rows:1fr}
.faq__a-inner{overflow:hidden;color:var(--ink-soft);font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);font-weight:400;}
.faq__a-inner p{padding:0 44px 0 4px}
.faq__a-inner p:last-child{padding-bottom:24px}
.faq__a-inner p + p{margin-top:10px}

/* ==========================================================================
   FOOTER
   ========================================================================== */
.footer{
  position:relative;background:var(--dark);color:var(--cream);
  margin-top:calc(var(--sect)*.5);overflow:hidden;
}
.footer__glow{
  position:absolute;left:50%;top:-30%;width:90vw;height:70%;transform:translateX(-50%);
  background:
    radial-gradient(40% 55% at 35% 50%, rgba(245,81,30,.22), transparent 70%),
    radial-gradient(40% 55% at 65% 50%, rgba(10,151,255,.2), transparent 70%);
  filter:blur(30px);pointer-events:none;
}
.footer__inner{position:relative;max-width:var(--container);margin:0 auto;padding:clamp(56px,7vw,90px) var(--pad) 0}

/* band 1 - one quiet row: nav left, social right */
.footer__row{
  display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap;
}
.footer__nav{display:flex;gap:clamp(20px,3vw,38px);flex-wrap:wrap}
.footer__nav a{
  font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);
  font-weight:400;opacity:.8;transition:opacity .25s var(--ease),color .25s var(--ease);
}
.footer__nav a:hover{opacity:1;color:var(--orange)}
.footer__social{display:flex;gap:12px}
.footer__social a{
  width:42px;height:42px;border-radius:50%;color:var(--cream);
  border:1px solid rgba(250,248,244,.22);display:grid;place-items:center;
  transition:border-color .25s var(--ease),background .25s var(--ease),transform .25s var(--ease);
}
.footer__social a svg{width:18px;height:18px}
.footer__social a:hover{border-color:transparent;background:rgba(250,248,244,.16);transform:translateY(-2px)}

/* band 2 - meta */
.footer__meta{
  display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;
  margin-top:clamp(18px,2.4vw,26px);
  font-size:var(--small);line-height:var(--small-lh);letter-spacing:var(--small-track);
  font-weight:400;opacity:.55;
}
.footer__meta a{text-decoration:underline;text-underline-offset:3px;transition:opacity .25s var(--ease)}
.footer__meta a:hover{opacity:.75}

/* Sign-off wordmark. Kept, but at roughly half its old size and with the
   orange banner image gone — .footer__glow already carries the brand colour,
   and it was banner + 300px wordmark + two link columns stacking that made
   this footer feel like a dumping ground. */
.wordmark{
  position:relative;z-index:2;text-align:center;user-select:none;pointer-events:none;
  font-weight:500;letter-spacing:-.055em;
  /* .82 clipped the y descender against .footer{overflow:hidden}; at half
     the old size that reads as a bug rather than a deliberate bleed */
  line-height:1;padding-bottom:.06em;
  font-size:clamp(4rem,13vw,11rem);
  color:var(--cream);opacity:.92;
  margin:clamp(28px,4vw,44px) 0 0;
}
.wordmark .x{color:inherit}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width:960px){
  /* single full-width column on mobile, one seamless bottom-to-top loop */
  .gallery__strip{height:clamp(430px,120vw,560px);grid-template-columns:1fr}
  .gcol--up,.gcol--down{display:none}
  .gcol--all{display:flex}
  /* Stacked cards keep the live site's tilt + slight overlap */
  .cards{grid-template-columns:1fr;gap:26px;padding:0;max-width:560px;margin:0 auto}
  .cards > .pcard-wrap{margin:-8px 0}
  .pcard.c1{transform:rotate(-2.6deg)}
  .pcard.c2{transform:rotate(2.2deg)}
  .pcard.c3{transform:rotate(-2deg)}
  /* Strings stay visible when stacked — they run vertically down the gaps
     between the cards. The top values are fallbacks; main.js pins each string
     to the centre of the gap between its two cards (placeStrings). */
  .squiggle{display:block}
  .squiggle.s1{left:auto;right:14px;top:28%;width:148px;transform:rotate(92deg)}
  /* 272deg = the 92deg vertical loop inverted, sitting a notch higher */
  .squiggle.s2{left:auto;right:10px;top:56%;width:154px;transform:rotate(272deg)}
  .testis{grid-template-columns:1fr}
  .testi{max-width:none}
  .testi.right{margin-top:0;justify-self:start}
  .testi-div{height:1px;min-height:0;width:100%;align-self:auto}
  .cases__grid,.cases__grid--soon{grid-template-columns:1fr}
  .faq__grid{grid-template-columns:1fr}
  .faq__card{position:static}
  /* Pills become a robust flex container that wraps cleanly.
     No !important anywhere — GSAP animates via inline transforms and an
     !important rule would silently freeze them. */
  .pills{
    position:static;pointer-events:auto;
    order:2;display:flex;
    flex-wrap:wrap;
    gap:12px 8px;justify-content:center;
    align-items:center;
    max-width:380px;
    margin-top:16px;
  }
  .pill-drag{position:static; touch-action:auto;}
  .pill img{height:64px}
  /* display:contents on .container drops its side padding, so .intro has to
     supply the horizontal gutter itself or the text runs edge to edge. */
  .intro{
    display:flex;flex-direction:column;align-items:center;
    padding:calc(var(--sect)*.6) var(--pad) var(--sect);
  }
  .intro .container{display:contents}
  .intro .eyebrow{order:0}
  .intro__p{order:1;margin-bottom:26px;max-width:100%}
}
@media (max-width:560px){
  .gallery__strip{gap:10px}
  .gcol img{margin-bottom:10px}
  .hero{padding-top:110px}
}

/* ===== No-JS / pre-JS fallback & reduced motion ===== */
.no-anim [data-reveal]{opacity:1;transform:none}
.no-anim .slideshow img:first-child{opacity:1;transform:none}
.no-anim .testi__q .tw{opacity:1}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important}
  .logo-strip{animation:none}
  .gcol--up,.gcol--down,.gcol--all{animation:none}
  .testi__q .tw{transition-delay:0s!important}
}

/* ==========================================================================
   ===== CASE STUDY =====
   Used only by the pages under /work/. Namespaced with a cs- prefix so it can
   never collide with the homepage rules above. Every colour is a :root token
   and every text element uses one of the Section 4 type tokens.
   Shared components are reused as-is: .nav/.menu, .eyebrow, .section-title,
   .testi and .footer all come from the sections above.

   NOTE: the before/after slider (.ba*) the previous KhelCourt design used is
   gone — that project was built from zero, so there is no "before". Recover it
   from git history (commit 078d928) if a future case study needs one.
   ========================================================================== */

/* --- shared bits --- */
.cs-head{margin-bottom:clamp(30px,4vw,44px)}
.cs-head .section-title{margin-bottom:0}
.cs-sub{
  max-width:62ch;margin-top:16px;color:var(--ink-soft);
  font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);
}

/* Every uppercase micro-label on the page, in one place. */
.cs-meta b,.cs-calls__k,.cs-side b,.cs-gap b,.cs-lstep .no,.cs-nextstrip small,
.cs-form__k,.cs-alt,.cs-send,.cs-ph b,.cs-fld::placeholder{
  font-size:var(--small);line-height:var(--small-lh);font-weight:500;
  text-transform:uppercase;letter-spacing:var(--track-label);
}
/* Small text that is a phrase, not a label — no uppercase, no extra tracking. */
.cs-call span,.cs-shot__cap,.cs-formnote,.cs-ph,.cs-ph i{
  font-size:var(--small);line-height:var(--small-lh);letter-spacing:var(--small-track);
}

/* Dashed box standing in for every image not yet exported (Phase 4). */
.cs-ph{
  position:absolute;inset:0;display:grid;place-items:center;align-content:center;
  text-align:center;padding:22px;color:var(--word-muted);font-weight:500;
}
.cs-ph::after{content:"";position:absolute;inset:12px;border:1.5px dashed rgba(198,191,178,.4);border-radius:14px}
.cs-ph b{display:block;margin-bottom:5px;opacity:.75}
.cs-ph i{display:block;font-style:normal;margin-top:7px;opacity:.7;font-weight:400}

/* --- case hero --- */
.cs-hero{padding:clamp(122px,15vw,168px) 0 0}
.cs-hero .eyebrow{margin-bottom:6px}
.cs-title{
  font-size:var(--h1);line-height:var(--h1-lh);letter-spacing:var(--h1-track);
  font-weight:500;margin:6px 0 20px;
}
.cs-title em,.cs-big em{font-style:italic;font-weight:500;color:var(--orange)}
.cs-lede{
  max-width:52ch;color:var(--ink-soft);font-weight:400;
  font-size:var(--h4);line-height:var(--h4-lh);letter-spacing:var(--h4-track);
}
.cs-meta{
  display:grid;grid-template-columns:repeat(4,1fr);gap:18px;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:20px 0;margin:clamp(28px,4vw,36px) 0 clamp(30px,4vw,40px);
}
.cs-meta b{display:block;color:var(--ink-soft);margin-bottom:6px}
.cs-meta span{font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);font-weight:400}
.cs-hero-img{
  position:relative;border-radius:var(--r);overflow:hidden;
  box-shadow:var(--shadow);aspect-ratio:16/8;background:var(--dark);
}
.cs-hero-img img,.cs-sol__hero img,.cs-shot img,.cs-contact__vis img{width:100%;height:100%;object-fit:cover}

/* --- overview --- */
.cs-ov{display:grid;grid-template-columns:1.25fr .9fr;gap:clamp(34px,4.5vw,56px);align-items:start}
.cs-big{font-size:var(--h3);line-height:var(--h3-lh);letter-spacing:var(--h3-track);font-weight:400}
.cs-sides{display:grid;gap:12px}
.cs-side{
  background:var(--card);border:1px solid var(--line);border-radius:16px;
  padding:20px 22px;box-shadow:0 24px 54px -30px rgba(25,23,19,.25);
}
.cs-side b{display:block;color:var(--orange);margin-bottom:7px}
.cs-side h4{font-size:var(--h4);line-height:var(--h4-lh);letter-spacing:var(--h4-track);font-weight:400}
.cs-side p{color:var(--ink-soft);margin-top:5px}

/* --- the problem + the phone-call vignette (this page's signature) --- */
.cs-prob{display:grid;grid-template-columns:1fr .82fr;gap:clamp(34px,4.5vw,56px);align-items:start}
.cs-prob__title{
  font-size:var(--h2);line-height:var(--h2-lh);letter-spacing:var(--h2-track);
  font-weight:400;margin:14px 0 20px;
}
.cs-prob p{color:var(--ink-soft);max-width:56ch;margin-bottom:16px}
.cs-calls{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:26px;box-shadow:var(--shadow)}
.cs-calls__k{color:var(--ink-soft);padding-bottom:14px;border-bottom:1px solid var(--line);margin-bottom:6px}
.cs-call{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:14px 0;border-bottom:1px solid var(--line)}
.cs-call b{font-size:var(--body);line-height:var(--body-lh);letter-spacing:var(--body-track);font-weight:500}
.cs-call span{color:var(--word-muted)}
.cs-call--win{border-bottom:0;padding-top:18px}
.cs-call--win b,.cs-call--win span{color:var(--orange)}
.cs-call--win span{font-weight:500}

/* --- market gaps --- */
.cs-gaps{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.cs-gap{
  background:var(--card);border:1px solid var(--line);border-radius:16px;
  padding:24px;box-shadow:0 24px 54px -30px rgba(25,23,19,.25);
}
.cs-gap b{display:block;color:var(--orange);margin-bottom:12px}
.cs-gap h4{font-size:var(--h4);line-height:var(--h4-lh);letter-spacing:var(--h4-track);font-weight:400;margin-bottom:7px}
.cs-gap p{color:var(--ink-soft)}

/* --- solution blocks (image-led) --- */
.cs-sol{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(30px,3.5vw,44px);align-items:stretch}
.cs-sol__txt{display:flex;flex-direction:column}
.cs-sol__title{margin-bottom:0}
.cs-sol__txt .cs-sub{margin:14px 0 30px}
.cs-flist{display:flex;flex-direction:column;margin-top:auto}
.cs-fitem{display:flex;gap:14px;align-items:baseline;padding:15px 0;border-top:1px solid var(--line)}
.cs-fitem b{font-weight:500;flex:none;min-width:170px}
.cs-fitem span{color:var(--ink-soft)}
.cs-sol__hero{
  position:relative;border-radius:var(--r);overflow:hidden;background:var(--dark);
  box-shadow:var(--shadow);min-height:520px;
}
.cs-sol--flip .cs-sol__hero{order:-1}
.cs-shots{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:16px}
.cs-shot{
  position:relative;border-radius:16px;overflow:hidden;background:var(--dark);
  box-shadow:var(--shadow);aspect-ratio:16/10;
}
.cs-shot--wide{aspect-ratio:16/8;margin-top:16px}
.cs-shot__cap{
  position:absolute;left:14px;bottom:14px;z-index:2;font-weight:500;
  background:rgba(250,248,244,.94);color:var(--ink);
  border-radius:999px;padding:7px 14px;box-shadow:0 24px 54px -30px rgba(25,23,19,.25);
}

/* --- booking lifecycle --- */
.cs-life{display:flex;gap:10px;flex-wrap:wrap;margin-top:8px}
.cs-lstep{
  flex:1;min-width:130px;background:var(--card);border:1px solid var(--line);
  border-radius:999px;padding:12px 18px;display:flex;align-items:center;gap:11px;
  box-shadow:0 24px 54px -30px rgba(25,23,19,.25);
}
.cs-lstep .no{color:var(--orange);flex:none}
.cs-lstep b{font-weight:500;white-space:nowrap}
.cs-lstep:last-child{background:var(--ink);color:var(--cream);border-color:transparent}
.cs-life-note{color:var(--ink-soft);margin-top:18px;max-width:60ch}

/* --- outcomes --- */
.cs-outcomes{
  background:var(--dark);color:var(--cream);border-radius:var(--r);
  padding:clamp(44px,6vw,64px) clamp(26px,6vw,74px);box-shadow:var(--shadow);
}
.cs-outcomes .eyebrow::before{background:var(--cream)}
.cs-outcomes__title{
  font-size:var(--h2);line-height:var(--h2-lh);letter-spacing:var(--h2-track);
  font-weight:400;margin:14px 0 18px;
}
.cs-o-lede{color:var(--word-muted);max-width:66ch}
.cs-stats{
  display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(26px,3vw,32px);
  margin-top:clamp(32px,4vw,46px);padding-top:clamp(28px,3.5vw,38px);
  border-top:1px solid rgba(250,248,244,.12);
}
.cs-stat b{
  display:block;font-size:var(--big-number);line-height:var(--big-number-lh);
  letter-spacing:var(--big-number-track);font-weight:400;
}
.cs-stat > span{display:block;margin-top:10px;color:var(--word-muted)}

/* --- compact next-project strip --- */
.cs-next-sect{padding:0 0 clamp(50px,7vw,80px)}
.cs-nextstrip{
  display:flex;justify-content:space-between;align-items:center;gap:24px;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:26px 0;
}
.cs-nextstrip small{display:block;color:var(--ink-soft);margin-bottom:5px}
.cs-nextstrip h3{font-size:var(--h3);line-height:var(--h3-lh);letter-spacing:var(--h3-track);font-weight:400}
.cs-go{font-size:var(--h3);line-height:1;color:var(--orange);transition:transform .3s var(--ease)}
.cs-nextstrip:hover .cs-go{transform:translateX(6px)}

/* --- contact --- */
.cs-contact{display:grid;grid-template-columns:1.05fr 1fr;border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow);background:var(--card)}
/* The dark panel holds ONLY the headline + paragraph, centred both ways. It is
   also the slot for a full-bleed background image in Phase 4. */
.cs-contact__vis{
  position:relative;min-height:520px;background:var(--dark);color:var(--cream);
  display:flex;align-items:center;justify-content:center;
  padding:clamp(32px,5vw,48px);text-align:center;
}
.cs-cv-mid{position:relative;z-index:2}
.cs-cv-mid h2{
  font-size:var(--h2);line-height:var(--h2-lh);letter-spacing:var(--h2-track);
  font-weight:400;margin-bottom:16px;
}
.cs-cv-mid p{max-width:36ch;margin:0 auto;opacity:.85}
.cs-form{padding:clamp(30px,4vw,44px) clamp(24px,4vw,52px);display:flex;flex-direction:column}
.cs-form__k{color:var(--ink-soft);text-align:center;margin-bottom:26px}
.cs-fld{
  width:100%;margin-bottom:12px;padding:16px 18px;
  background:#E4E2DE;border:1px solid transparent;border-radius:16px;
  font-family:var(--sans);font-weight:400;font-size:var(--body);
  line-height:var(--body-lh);letter-spacing:var(--body-track);color:var(--ink);
  transition:border-color .25s var(--ease),background .25s var(--ease);
}
.cs-fld::placeholder{color:var(--ink-soft)}
.cs-fld:focus{outline:none;border-color:var(--orange);background:var(--card)}
textarea.cs-fld{min-height:132px;resize:vertical}
/* the terms line used to sit here and supply the gap above the button; with it
   gone .cs-send carries that space itself (12px field margin + 22px = 34px) */
.cs-send{
  align-self:center;margin-top:22px;
  background:var(--ink);color:var(--cream);border-radius:999px;
  padding:18px 40px;box-shadow:var(--shadow);
  transition:transform .3s var(--ease),box-shadow .35s var(--ease);
}
.cs-send:hover{transform:translateY(-2px)}
.cs-send[disabled]{opacity:.55;cursor:default;transform:none}
/* Empty until a submit resolves. Orange is the problem state; --ok is the
   sent state. */
.cs-formnote{color:var(--orange);text-align:center;margin-top:14px}
.cs-formnote--ok{color:var(--green)}
.cs-formnote:empty{margin-top:0}
.cs-alt{color:var(--ink-soft);text-align:center;margin-top:auto;padding-top:32px}
.cs-alt a{color:var(--orange);text-decoration:underline;text-underline-offset:3px}

/* --- case study responsive --- */
@media (max-width:960px){
  .cs-ov,.cs-prob,.cs-sol{grid-template-columns:1fr;gap:34px}
  .cs-sol--flip .cs-sol__hero{order:0}
  .cs-sol__hero{min-height:440px}
  .cs-gaps{grid-template-columns:1fr 1fr}
  .cs-stats{grid-template-columns:1fr 1fr;gap:28px}
  .cs-contact{grid-template-columns:1fr}
  /* only two centred elements live in the panel now, so it does not need to be
     anywhere near as tall once it stacks above the form */
  .cs-contact__vis{min-height:300px}
}
@media (max-width:640px){
  .cs-meta{grid-template-columns:1fr 1fr}
  .cs-hero-img{aspect-ratio:4/3}
  .cs-gaps{grid-template-columns:1fr}
  /* Two-shot rows become a horizontal swipe strip: 82% cards, snap, next card
     peeking in. One gesture instead of a tall stack. */
  .cs-shots{
    display:flex;overflow-x:auto;gap:12px;padding-bottom:6px;
    scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;
  }
  .cs-shots::-webkit-scrollbar{display:none}
  .cs-shots .cs-shot{flex:0 0 82%;scroll-snap-align:start;aspect-ratio:16/11}
  /* optional imagery drops off phones entirely */
  .cs-shot--wide{display:none}
  /* shorter crop so the solution hero does not eat the whole screen */
  .cs-sol__hero{min-height:0;aspect-ratio:4/5}
  .cs-fitem{flex-direction:column;gap:4px}
  .cs-fitem b{min-width:0}
  .cs-lstep{min-width:calc(50% - 5px)}
  .cs-stats{gap:24px}
  .cs-contact__vis{min-height:260px}
}

/* ==========================================================================
   ===== CASE STUDY: RED STATE =====
   ONLY the components KhelCourt didn't already have. Everything else on
   work/redstate/index.html reuses the shared case-study classes above —
   .cs-hero/.cs-title/.cs-meta/.cs-ov/.cs-side/.cs-sol/.cs-shots/.cs-life/
   .cs-stats/.cs-nextstrip/.cs-contact are all shared, not duplicated.
   Same rules apply: :root tokens only, and every text element on a Section 4
   type token.
   ========================================================================== */

/* --- micro-labels introduced by this page --- */
.cs-pair > b,.cs-pair__fix span,.cs-cmp__col h4{
  font-size:var(--small);line-height:var(--small-lh);font-weight:500;
  text-transform:uppercase;letter-spacing:var(--track-label);
}

/* --- problem + fix pair cards --- */
.cs-pairs{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.cs-pair{
  background:var(--card);border:1px solid var(--line);border-radius:16px;
  padding:26px;box-shadow:0 24px 54px -30px rgba(25,23,19,.25);
}
.cs-pair > b{display:block;color:var(--orange);margin-bottom:12px}
.cs-pair h4{
  font-size:var(--h4);line-height:var(--h4-lh);letter-spacing:var(--h4-track);
  font-weight:400;margin-bottom:10px;
}
.cs-pair p{color:var(--ink-soft)}
/* the fix is the payoff — divided off, and in full-strength ink */
.cs-pair__fix{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
.cs-pair__fix span{display:block;color:var(--ink-soft);margin-bottom:7px}
.cs-pair__fix p{color:var(--ink)}

/* --- old vs revamped compare --- */
.cs-cmp{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:clamp(34px,4.5vw,56px)}
.cs-cmp__col{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:30px;box-shadow:0 24px 54px -30px rgba(25,23,19,.25);
}
.cs-cmp__col--new{background:var(--dark);color:var(--cream);border-color:transparent}
.cs-cmp__col h4{color:var(--ink-soft);padding-bottom:16px;border-bottom:1px solid var(--line);margin-bottom:4px}
.cs-cmp__col--new h4{color:var(--orange);border-bottom-color:rgba(250,248,244,.14)}
.cs-cmp__col ul{list-style:none}
.cs-cmp__col li{
  position:relative;padding:13px 0 13px 26px;color:var(--ink-soft);
  border-bottom:1px solid var(--line);
}
.cs-cmp__col--new li{color:var(--word-muted);border-bottom-color:rgba(250,248,244,.10)}
.cs-cmp__col li:last-child{border-bottom:0}
.cs-cmp__col li::before{content:"\2014";position:absolute;left:0;color:var(--word-muted)}
.cs-cmp__col--new li::before{content:"\2192";color:var(--orange)}

/* --- before / after slider ---
   Reusable: main.js wires every .ba on the page. --cut is the clip position,
   written by the drag handler. A pane can hold a single <img> or, as on Red
   State, a .ba__shots row of framed screenshots. */
.ba{
  position:relative;border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow);
  background:var(--card);cursor:col-resize;
  touch-action:pan-y;-webkit-user-select:none;user-select:none;
}
.ba__pane{position:absolute;inset:0}
.ba__pane--before{position:static}
.ba__pane--after{clip-path:inset(0 0 0 var(--cut,50%))}
.ba__tag{
  position:absolute;top:16px;z-index:3;pointer-events:none;
  font-size:var(--small);line-height:var(--small-lh);font-weight:500;
  text-transform:uppercase;letter-spacing:var(--track-label);
  background:rgba(20,18,16,.78);color:var(--cream);padding:6px 13px;border-radius:999px;
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
}
.ba__tag--before{left:16px}
.ba__tag--after{right:16px}
.ba__handle{position:absolute;top:0;bottom:0;left:var(--cut,50%);width:2px;background:var(--cream);z-index:4;transform:translateX(-1px)}
.ba__grip{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:46px;height:46px;border-radius:50%;background:var(--card);color:var(--ink);
  box-shadow:var(--shadow);display:grid;place-items:center;font-weight:500;letter-spacing:1px;
}
.ba-note{
  font-size:var(--small);line-height:var(--small-lh);letter-spacing:var(--small-track);
  color:var(--ink-soft);margin-top:14px;text-align:center;
}

/* --- the three screenshot frames inside a slider pane ---
   Both panes carry the identical geometry (same slots, same gaps, same radius)
   so the wipe compares like with like: storefront, product page, listing. */
.ba__pane{background:var(--bg)}
.ba__shots{position:absolute;inset:0;padding:4% 5%;display:flex;gap:3%;align-items:flex-start}
.ba__pane--before .ba__shots{position:static}
/* The screenshots are 1000x750, so the frame is 4/3 too: cover crops nothing
   and no background can show through on any side. Do not give this box a
   height, a min-height or a background. */
.ba__shot{
  flex:1;min-width:0;width:100%;height:auto;aspect-ratio:4/3;
  border-radius:14px;overflow:hidden;
  box-shadow:0 10px 26px -14px rgba(25,23,19,.16);
}
.ba__shot img{
  display:block;width:100%;height:100%;
  object-fit:cover;object-position:center;
}

/* Phone: three frames side by side would be 90px wide and unreadable, so they
   stack. The container gets a taller ratio to pay for it, and the shots clear
   the Before/After tags. The slider itself is unchanged. */
@media (max-width:640px){
  /* Stacked: flex:1 would let the absolutely-positioned "after" pane shrink its
     cards off 4/3, and a percentage row-gap resolves to 0 against the "before"
     pane's auto height. Fixed basis and a px gap keep both panes identical. */
  .ba__shots{flex-direction:column;padding:48px 5% 4%;gap:10px}
  .ba__shot{flex:0 0 auto}
}

/* --- the 1776 limited drop + scarcity meter --- */
.cs-drop{
  background:var(--dark);color:var(--cream);border-radius:var(--r);
  padding:clamp(44px,6vw,64px) clamp(26px,6vw,74px);box-shadow:var(--shadow);
}
.cs-drop .eyebrow::before{background:var(--cream)}
.cs-drop__title{
  font-size:var(--h2);line-height:var(--h2-lh);letter-spacing:var(--h2-track);
  font-weight:400;margin:14px 0 18px;
}
.cs-drop__lede{color:var(--word-muted);max-width:64ch}
.cs-meter{margin-top:clamp(32px,4vw,46px);border-top:1px solid rgba(250,248,244,.12);padding-top:clamp(28px,3.5vw,36px)}
.cs-meter__top{display:flex;justify-content:space-between;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:16px}
.cs-meter__top b{font-size:var(--h4);line-height:var(--h4-lh);letter-spacing:var(--h4-track);font-weight:500}
.cs-meter__top span{font-size:var(--small);line-height:var(--small-lh);letter-spacing:var(--small-track);color:var(--word-muted)}
.cs-meter__track{height:10px;border-radius:999px;background:rgba(250,248,244,.12);overflow:hidden}
/* width is animated from 0 by main.js when the bar scrolls into view */
.cs-meter__fill{height:100%;width:0;border-radius:999px;background:linear-gradient(90deg,var(--orange),rgba(245,81,30,.5))}
/* Compact stat row under the bar. Reuses the .cs-stats/.cs-stat structure from
   Outcomes so the two read as the same component, but one size down (--h2, not
   --big-number): this sits inside the dark card beneath the meter rather than
   being a section of its own, and the caption is a micro-label, not a
   sentence. Inherits .cs-stats--3's 2-up/1-up collapse. */
.cs-drop__stats{margin-top:clamp(26px,3.2vw,34px);padding-top:clamp(24px,3vw,30px)}
.cs-drop__stats .cs-stat b{
  font-size:var(--h2);line-height:var(--h2-lh);letter-spacing:var(--h2-track);
}
.cs-drop__stats .cs-stat > span{
  margin-top:6px;font-size:var(--small);line-height:var(--small-lh);
  font-weight:500;text-transform:uppercase;letter-spacing:var(--track-label);
}

/* --- outcomes, light variant (the 1776 block above is already dark, so two
       dark bands back to back would read heavy) --- */
.cs-outcomes--light{background:var(--card);color:var(--ink);border:1px solid var(--line);box-shadow:0 24px 54px -30px rgba(25,23,19,.25)}
.cs-outcomes--light .eyebrow::before{background:var(--ink)}
.cs-outcomes--light .cs-stats{border-top-color:var(--line)}
.cs-outcomes--light .cs-stat > span{color:var(--ink-soft)}
.cs-stats--3{grid-template-columns:repeat(3,1fr)}
/* the "brand" / "sauces" suffix riding next to a big number */
.cs-unit{font-size:.36em;font-weight:500;letter-spacing:var(--h4-track);margin-left:.1em;color:var(--ink-soft)}

/* --- red state responsive --- */
@media (max-width:960px){
  .cs-pairs,.cs-cmp{grid-template-columns:1fr}
  .cs-stats--3{grid-template-columns:1fr 1fr}
  /* The Outcomes row goes 2-up here because its captions are full sentences.
     The drop stats are three short figures, so they stay 3-up and avoid
     orphaning the third one; they drop to 1-up with everything else at 640. */
  .cs-drop__stats{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:640px){
  /* .ba goes taller here and its shots stack: see the slider block above. */
  .cs-stats--3{grid-template-columns:1fr}
  .cs-cmp__col{padding:24px}
}
/* ===== CASE STUDY: real images in the former placeholder slots =====
   Append to the end of assets/styles.css. */

.cs-hero-img img,
.cs-sol__hero img,
.cs-shot img{
  display:block;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:top center;
}

/* Hero: the screenshot is 16:9 and the slot was 16:8, which chopped the
   bottom off. Let the image set the height instead of cropping it. */
.cs-hero-img{aspect-ratio:16/9;height:auto}

/* Portrait page shots: give the container a real ratio rather than the old
   fixed min-height, so nothing is over-cropped. */
.cs-sol__hero{min-height:0;aspect-ratio:4/5}

/* Device-frame composites are already letterboxed on their own dark canvas,
   so they sit inside the slot rather than being cropped by it. */
.cs-shot img[src*="-duo"],
.cs-hero-img img[src*="kc-hero"],
.cs-shot--wide img[src*="kc-flow"]{
  object-fit:contain;
  object-position:center;
  background:#17171b;
}

@media (max-width:640px){
  .cs-sol__hero{aspect-ratio:3/4}
}

