/* ============================================================
   ToJupiter V2 — Case study / success story styles
   Loaded IN ADDITION to styles.css (tokens, reset, buttons, nav,
   footer, reveal) and resources.css (light nav variant, the book-a-call
   modal, the .r-cta closing band, .r-pull pull-quote). Everything here
   is namespaced .case-* so it can never collide with the homepage
   .cs-* case-study CARDS or the resources .r-* module.
   Rhythm: dark cosmic hero + stat bar, then a light editorial two-column
   body with a sticky profile sidebar, then a dark CTA band. Not a toggle.
   ============================================================ */

body.case-page{background:var(--r-paper);color:var(--r-ink);}
/* matches the nav .container exactly, so the main column's left edge lines up
   with the logo and the sidebar's right edge with the nav CTA */
.case-wrap{max-width:var(--container);margin:0 auto;padding:0 32px;width:100%;}

/* ============================================================
   HERO (dark cosmic) — headline + premium quote on the left,
   the 3 headline stats stacked in the right column.
   ============================================================ */
.case-top{position:relative;background:var(--navy);color:#fff;overflow:hidden;}
.case-top::before{/* planet-limb glow, bottom-right */
  content:"";position:absolute;right:-12%;bottom:-40%;width:820px;height:820px;border-radius:50%;
  background:radial-gradient(circle at 50% 50%,rgba(166,64,255,0.42),rgba(120,0,224,0.16) 42%,transparent 66%);
  filter:blur(4px);pointer-events:none;}
.case-top::after{/* faint drifting stars */
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.7;
  background-image:
    radial-gradient(1.5px 1.5px at 14% 26%,rgba(255,255,255,.6),transparent),
    radial-gradient(1px 1px at 62% 16%,rgba(233,153,255,.6),transparent),
    radial-gradient(1.5px 1.5px at 82% 46%,rgba(255,255,255,.4),transparent),
    radial-gradient(1px 1px at 36% 66%,rgba(255,255,255,.35),transparent),
    radial-gradient(1px 1px at 90% 74%,rgba(166,64,255,.5),transparent);}
.case-top__inner{position:relative;z-index:1;}

/* the ToJupiter scene: a banded planet rising past the bottom-right corner,
   lit along the limb that faces the content, with two faint orbit rings */
.case-top__deco{position:absolute;inset:0;pointer-events:none;}
.case-top__planet{position:absolute;right:-300px;bottom:-540px;width:880px;height:880px;border-radius:50%;
  background:
    radial-gradient(circle at 36% 30%,rgba(166,64,255,.32),transparent 58%),
    repeating-linear-gradient(112deg,rgba(166,64,255,.15) 0 44px,rgba(120,0,224,.09) 44px 96px,rgba(76,0,143,.13) 96px 158px),
    radial-gradient(circle at 38% 30%,#170A40,#0A0630 62%,#060428 80%);
  box-shadow:
    0 0 110px 8px rgba(166,64,255,.4),
    inset 46px 64px 130px -44px rgba(166,64,255,.55),
    inset 12px 18px 40px -10px rgba(233,153,255,.35);}
.case-top__ring{position:absolute;border:1px solid rgba(233,153,255,.13);border-radius:50%;}
.case-top__ring--1{width:1400px;height:1400px;right:-560px;bottom:-810px;}
.case-top__ring--2{width:1820px;height:1820px;right:-770px;bottom:-1020px;border-color:rgba(233,153,255,.08);}

.case-hero{display:grid;grid-template-columns:minmax(0,1.16fr) minmax(0,0.84fr);gap:64px;align-items:center;
  padding:132px 0 84px;}
.case-crumb{font-size:13px;color:rgba(255,255,255,.62);letter-spacing:.2px;margin-bottom:26px;}
.case-crumb a{color:rgba(255,255,255,.62);}
.case-crumb a:hover{color:#fff;}
.case-crumb span{color:#fff;}

.case-eyebrow{display:inline-block;font-size:13px;font-weight:700;letter-spacing:.02em;
  color:#fff;margin-bottom:18px;}
.case-hero h1{font-family:var(--r-display);font-weight:800;letter-spacing:-.02em;line-height:1.06;
  font-size:clamp(32px,4.4vw,52px);color:#fff;margin:0;}
.case-hl{background:linear-gradient(120deg,var(--purple-4),var(--purple-1));-webkit-background-clip:text;background-clip:text;color:transparent;}
/* premium quote card under the headline: glass, gradient mark, and a subtle
   gradient glow that travels around the border (replaced an earlier gloss
   sweep, which pulled the eye off the words). */
.case-heroquote{position:relative;margin-top:32px;border-radius:20px;padding:24px 28px 22px;
  background:linear-gradient(150deg,rgba(255,255,255,0.07),rgba(255,255,255,0.02));
  box-shadow:0 30px 70px -42px rgba(166,64,255,.55),inset 0 1px 0 rgba(255,255,255,.08);}
.case-heroquote::before{content:"\201C";display:block;font-family:Georgia,'Times New Roman',serif;font-weight:700;
  font-size:80px;line-height:.62;height:.5em;margin:4px 0 14px;
  background:linear-gradient(120deg,var(--purple-4),var(--purple-1));-webkit-background-clip:text;background-clip:text;color:transparent;}
/* rotating conic-gradient ring, masked to a 1.5px border. @property lets the
   angle animate smoothly; where it is unsupported (or reduce-motion is on) the
   ring simply sits static, still a gradient border. It never hides the quote. */
@property --caseGlow{syntax:"<angle>";initial-value:0deg;inherits:false;}
.case-heroquote::after{content:"";position:absolute;inset:0;border-radius:inherit;padding:1.5px;pointer-events:none;
  background:conic-gradient(from var(--caseGlow,0deg),
    rgba(233,153,255,.85),rgba(166,64,255,.14) 25%,rgba(120,0,224,.55) 50%,rgba(233,153,255,.12) 73%,rgba(233,153,255,.85));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;
  animation:caseGlowSpin 8s linear infinite;}
@keyframes caseGlowSpin{to{--caseGlow:360deg;}}
.case-heroquote p{position:relative;font-family:var(--r-display);font-weight:600;font-size:clamp(19px,2.1vw,24px);
  line-height:1.36;letter-spacing:-.01em;color:#fff;margin:0;}
.case-heroquote figcaption{position:relative;display:flex;align-items:center;gap:12px;margin-top:18px;}
.case-heroquote .case-avatar{width:42px;height:42px;border-radius:50%;flex:0 0 auto;}
.case-heroquote b{display:block;font-weight:600;font-size:14.5px;color:#fff;}
.case-heroquote figcaption span span{display:block;font-size:13px;color:rgba(255,255,255,.62);}

/* the 3 headline stats, stacked in the hero's right column.
   Dark frosted panel so the planet behind stays subdued. */
.case-hstats{display:flex;flex-direction:column;border-radius:24px;padding:10px 30px;
  background:rgba(16,13,48,.52);
  backdrop-filter:blur(24px) saturate(120%);-webkit-backdrop-filter:blur(24px) saturate(120%);
  border:1px solid rgba(255,255,255,0.18);
  box-shadow:0 40px 90px -50px rgba(166,64,255,.5),inset 0 1px 0 rgba(255,255,255,.10);}
.case-hstat{padding:24px 0 26px;border-top:1px solid rgba(255,255,255,.1);}
.case-hstat:first-child{border-top:0;}
.case-hstat__num{font-family:var(--r-display);font-weight:800;letter-spacing:-.03em;line-height:1;
  font-size:clamp(34px,3.4vw,46px);
  background:linear-gradient(120deg,var(--purple-4),var(--purple-1));-webkit-background-clip:text;background-clip:text;color:transparent;}
.case-hstat__label{font-size:14.5px;font-weight:600;color:#fff;margin-top:9px;}
.case-hstat__ctx{font-size:13px;line-height:1.5;color:rgba(255,255,255,.6);margin-top:3px;}

/* ============================================================
   FULL-WIDTH STAT BAR — optional template variant for data-rich
   clients (3-col, or --six = 2 rows of 3). The usecure page uses
   the stacked .case-hstats in the hero instead.
   ============================================================ */
.case-stats{position:relative;z-index:1;border-top:1px solid rgba(255,255,255,.12);
  display:grid;grid-template-columns:repeat(3,1fr);gap:0;padding:0;margin-top:8px;}
.case-stat{padding:46px 40px 54px;border-left:1px solid rgba(255,255,255,.12);}
.case-stat:first-child{border-left:0;padding-left:0;}
.case-stats--six{grid-template-columns:repeat(3,1fr);}
.case-stats--six .case-stat:nth-child(4){border-left:0;padding-left:0;}
.case-stats--six .case-stat:nth-child(n+4){border-top:1px solid rgba(255,255,255,.12);}
.case-stat__num{font-family:var(--r-display);font-weight:800;letter-spacing:-.03em;line-height:1;
  font-size:clamp(38px,4.6vw,58px);color:#fff;}
.case-stat:first-child .case-stat__num{background:linear-gradient(120deg,var(--purple-4),var(--purple-1));-webkit-background-clip:text;background-clip:text;color:transparent;}
.case-stat__label{font-size:15px;font-weight:600;color:#fff;margin-top:14px;}
.case-stat__ctx{font-size:13.5px;line-height:1.5;color:rgba(255,255,255,.6);margin-top:6px;}

/* ============================================================
   BODY — light editorial two-column with sticky sidebar
   ============================================================ */
/* NB no align-items:start here: the aside must stretch to the full row
   height or its sticky child has no room to travel and never pins.
   The body deliberately narrows to the blog layout (1160px, 48px padding,
   300px sidebar) while the hero above keeps the full nav-width wrap. */
.case-body{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:56px;
  max-width:1160px;padding-left:48px;padding-right:48px;
  padding-top:76px;padding-bottom:92px;}
.case-main{min-width:0;}
.case-aside{min-width:0;}
.case-aside__sticky{position:sticky;top:96px;display:flex;flex-direction:column;gap:16px;}

/* main column typography */
.case-section+.case-section{margin-top:56px;}
.case-main h2{font-family:var(--r-display);font-weight:800;letter-spacing:-.02em;color:var(--navy);
  font-size:clamp(25px,3vw,32px);line-height:1.14;margin:0 0 18px;}
.case-main h3{font-family:var(--r-display);font-weight:700;color:var(--navy);font-size:19px;margin:34px 0 12px;
  display:flex;align-items:center;gap:10px;}
.case-main h3::before{content:"";width:22px;height:2px;background:linear-gradient(90deg,var(--purple-1),var(--purple-4));border-radius:2px;}
.case-main p{font-size:16px;line-height:1.72;color:var(--r-ink);margin:0 0 16px;}
.case-main strong{font-weight:700;color:var(--navy);}
.case-main a:not(.tj-btn){color:var(--purple-2);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px;}
.case-main a:not(.tj-btn):hover{color:var(--purple-3);}
.case-main .tj-btn{text-decoration:none;}

/* workstream / bullet list with bold lead-ins */
/* symmetric 20px above and below: the paragraph after the list was sitting
   flush against the last bullet */
.case-list{list-style:none;margin:20px 0;padding:0;display:flex;flex-direction:column;gap:14px;}
.case-list li{position:relative;padding-left:22px;font-size:16px;line-height:1.62;color:var(--r-ink);}
/* minimal solid purple dot, matching the blog .r-takeaways bullets */
.case-list li::before{content:"";position:absolute;left:0;top:10px;width:8px;height:8px;border-radius:50%;
  background:var(--purple-1);}
.case-list li b,.case-list li strong{color:var(--navy);}

/* pull quote lifted between sections: a light "paper" card so it stands out
   from the body, with the large gradient quote mark inside */
.case-pull{margin:40px 0;padding:26px 32px 24px;border-radius:18px;
  background:linear-gradient(158deg,#fff,var(--r-paper2));
  border:1px solid var(--r-line-l);
  box-shadow:0 26px 60px -46px rgba(76,0,143,.42);}
.case-pull::before{content:"\201C";display:block;font-family:Georgia,'Times New Roman',serif;font-weight:700;
  font-size:56px;line-height:.62;height:.5em;margin:0 0 10px;
  background:linear-gradient(120deg,var(--purple-2),var(--purple-1));-webkit-background-clip:text;background-clip:text;color:transparent;}
.case-pull p{font-family:var(--r-display);font-weight:600;font-size:clamp(20px,2.3vw,25px);line-height:1.38;
  letter-spacing:-.01em;color:var(--navy);margin:0;}
.case-pull cite{display:block;margin-top:14px;font-style:normal;font-size:14px;font-weight:500;color:var(--r-ink-soft);}

/* impact stats: clean editorial grid, hairline rules, gradient numbers */
.case-metrics{display:grid;grid-template-columns:repeat(2,1fr);gap:0 44px;margin:24px 0 14px;}
.case-metric{border-top:1px solid var(--r-line-l);padding:20px 0 22px;}
.case-metric__num{font-family:var(--r-display);font-weight:800;letter-spacing:-.025em;line-height:1;
  font-size:clamp(30px,3vw,38px);
  background:linear-gradient(120deg,var(--purple-2),var(--purple-1));-webkit-background-clip:text;background-clip:text;color:transparent;}
.case-metric__txt{font-size:14.5px;line-height:1.55;color:var(--r-ink-soft);margin-top:9px;}

/* about-the-client: gradient-border card with a soft corner glow */
.case-about{margin-top:14px;border-radius:22px;padding:1.5px;
  background:linear-gradient(135deg,rgba(166,64,255,.55),rgba(233,153,255,.22) 45%,rgba(76,0,143,.45));
  box-shadow:0 30px 70px -50px rgba(76,0,143,.5);}
.case-about__inner{position:relative;overflow:hidden;background:#fff;border-radius:20.5px;padding:30px 32px 28px;}
.case-about__inner::before{content:"";position:absolute;right:-70px;top:-70px;width:230px;height:230px;border-radius:50%;
  background:radial-gradient(circle,rgba(166,64,255,.14),transparent 70%);pointer-events:none;}
.case-about p{position:relative;font-size:16px;}
.case-about .tj-btn{position:relative;margin-top:20px;}

/* inline section image */
.case-figure{margin:30px 0 0;}
.case-figure .case-ph{aspect-ratio:16/9;}
.case-figure figcaption{margin-top:12px;font-size:13.5px;color:var(--r-ink-soft);text-align:center;}

/* a figure whose image keeps its own shape (portrait screenshots, product shots) */
/* Two class selectors, so this beats the generic `.case-figure img` rule further
   down the file regardless of source order. Both were 0-1-1 and the later one was
   silently winning, which cropped full-page screenshots to 16:9. */
.case-figure.case-figure--natural img{aspect-ratio:auto;width:auto;height:auto;max-width:100%;max-height:640px;margin:0 auto;object-fit:contain;}

/* ad-creative gallery: masonry columns, because real ad screenshots are
   portrait at wildly different heights and must never be cropped or stretched */
.case-shots{margin:26px 0 0;column-count:2;column-gap:18px;}
.case-shots figure{break-inside:avoid;margin:0 0 18px;}
.case-shots img{width:100%;height:auto;display:block;border-radius:14px;border:1px solid var(--r-line-l);
  box-shadow:0 20px 44px -30px rgba(12,14,38,.45);}
.case-shots figcaption{margin-top:9px;font-size:12.5px;line-height:1.45;color:var(--r-ink-soft);}
.case-shots__note{margin-top:4px;font-size:13.5px;color:var(--r-ink-soft);text-align:center;}

/* ============================================================
   SIDEBAR — profile card, compact CTA, quick facts
   ============================================================ */
.case-profile{border:1px solid var(--r-line-l);border-radius:22px;background:#fff;padding:22px;
  box-shadow:0 26px 60px -44px rgba(76,0,143,.4);}
.case-profile__logo{height:30px;width:auto;max-width:170px;object-fit:contain;display:block;margin-bottom:6px;}
.case-profile__logo--compact{height:24px;}  /* visually heavy wordmarks (e.g. Deck) */
.case-profile__logo.case-ph{width:150px;height:38px;margin-bottom:0;}
.case-profile__rows{margin:16px 0 0;display:flex;flex-direction:column;}
.case-prow{display:flex;flex-direction:column;gap:2px;padding:9px 0;border-top:1px solid var(--r-line-l);}
.case-prow:first-child{border-top:0;padding-top:2px;}
.case-prow dt{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--r-ink-soft);margin:0;}
.case-prow dd{margin:0;font-size:14px;line-height:1.4;color:var(--navy);font-weight:500;}
.case-prow dd a{color:var(--purple-2);}
.case-chips{display:flex;flex-wrap:wrap;gap:7px;margin-top:4px;}
.case-chip{font-size:12px;font-weight:600;color:var(--purple-3);background:rgba(166,64,255,.1);border-radius:var(--r-pill);padding:4px 11px;}

.case-facts{border:1px solid var(--r-line-l);border-radius:18px;padding:18px 20px;background:var(--r-paper2);}
.case-facts h2{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--r-ink-soft);margin:0 0 10px;}
.case-facts ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px;}
.case-facts li{font-size:13.5px;line-height:1.4;color:var(--navy);padding-left:18px;position:relative;}
.case-facts li::before{content:"";position:absolute;left:0;top:7px;width:6px;height:6px;border-radius:50%;background:var(--purple-1);}

/* ============================================================
   RELATED STORIES (light) + closing band uses .r-cta (reused)
   ============================================================ */
.case-related{background:var(--r-paper2);border-top:1px solid var(--r-line-l);padding:72px 0 84px;}
.case-related .case-wrap{max-width:1160px;}
.case-related__head{font-family:var(--r-display);font-weight:800;letter-spacing:-.02em;color:var(--navy);
  font-size:clamp(22px,3vw,30px);margin:0 0 8px;text-align:center;}
.case-related__sub{font-size:16px;line-height:1.55;color:var(--r-ink-soft);margin:0 auto 34px;max-width:640px;text-align:center;}
/* auto-fit + centered so the grid reads as a curated set whether one story is
   live or several: a single card sits centred, more flow into a row */
/* Three explicit columns, not auto-fit. With a fixed max track (380px) auto-fit
   counts how many MAX-width tracks fit, not min-width ones, so the third card
   only joined the row above ~1250px and every page showed a 2 + 1 orphan.
   Equal fr columns share whatever width there is and stay on one row. */
.case-rgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px;
  max-width:1184px;margin:0 auto;}
.case-rcard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--r-line-l);border-radius:18px;overflow:hidden;
  text-decoration:none;transition:transform .2s ease,box-shadow .2s ease;}
.case-rcard:hover{transform:translateY(-3px);box-shadow:0 30px 60px -40px rgba(76,0,143,.5);}
.case-rcard__thumb{aspect-ratio:16/10;}
.case-rcard__body{padding:20px 22px 24px;}
.case-rcard__client{font-size:12.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--purple-2);}
.case-rcard__metric{font-family:var(--r-display);font-weight:800;color:var(--navy);font-size:19px;line-height:1.2;margin:8px 0 6px;}
.case-rcard__line{font-size:14px;color:var(--r-ink-soft);line-height:1.5;}

/* ============================================================
   IMAGE PLACEHOLDER — labelled grey block (swap for real asset)
   ============================================================ */
.case-ph{display:flex;align-items:center;justify-content:center;text-align:center;
  border:1px dashed #C9C6DE;border-radius:18px;background:
    repeating-linear-gradient(-45deg,rgba(166,64,255,.05) 0 12px,transparent 12px 24px),var(--r-paper2);
  color:var(--r-ink-soft);font-size:12.5px;font-weight:600;letter-spacing:.02em;padding:18px;line-height:1.45;width:100%;}
.case-ph--dark{border-color:rgba(255,255,255,.28);color:rgba(255,255,255,.72);
  background:repeating-linear-gradient(-45deg,rgba(255,255,255,.04) 0 12px,transparent 12px 24px),rgba(255,255,255,.03);}
.case-avatar.case-ph{border-radius:50%;padding:0;font-size:0;}

/* real images swapped in over placeholders */
img.case-avatar{object-fit:cover;}
.case-figure img{width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:16px;border:1px solid var(--r-line-l);display:block;}
/* one consistent dark cosmic panel behind every logo (was three different
   purple gradients per nth-child); logos render white for a uniform, premium set */
.case-rcard__thumb{display:flex;align-items:center;justify-content:center;padding:22px;position:relative;overflow:hidden;
  background:
    radial-gradient(120% 130% at 15% 0%,rgba(166,64,255,.32),transparent 55%),
    linear-gradient(150deg,#0B0733,#150A3D 52%,#060428);}
.case-rcard__thumb img{position:relative;width:auto;max-width:60%;max-height:46%;filter:brightness(0) invert(1);opacity:.95;}

/* ============================================================
   BEFORE / AFTER SLIDER — two page screenshots in one frame with
   a draggable divider. The whole frame is an invisible full-size
   range input, so mouse, touch and keyboard all work natively and
   no JS is needed beyond mapping value -> --pos. Without JS it
   rests at a 50/50 split, both halves visible.
   ============================================================ */
.case-ba{margin:30px 0 0;}
.case-ba+.case-ba{margin-top:26px;}
.case-ba__frame{position:relative;aspect-ratio:16/9;border-radius:16px;overflow:hidden;--pos:50%;
  border:1px solid var(--r-line-l);background:var(--r-paper2);
  box-shadow:0 24px 54px -34px rgba(12,14,38,.5);}
.case-ba__frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top center;display:block;}
.case-ba__before{position:absolute;inset:0;clip-path:inset(0 calc(100% - var(--pos)) 0 0);}
.case-ba__divider{position:absolute;top:0;bottom:0;left:var(--pos);width:2px;margin-left:-1px;background:#fff;
  box-shadow:0 0 14px rgba(4,6,46,.5);pointer-events:none;}
.case-ba__grip{position:absolute;top:50%;left:var(--pos);transform:translate(-50%,-50%);width:38px;height:38px;border-radius:50%;
  background:#fff;box-shadow:0 8px 22px -6px rgba(4,6,46,.55);display:grid;place-items:center;pointer-events:none;}
.case-ba__grip::before{content:"\2194";font-size:16px;font-weight:700;color:var(--purple-2);}
.case-ba__tag{position:absolute;top:12px;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:#fff;background:rgba(4,6,46,.72);padding:5px 12px;border-radius:100px;pointer-events:none;}
.case-ba__tag--before{left:12px;}
.case-ba__tag--after{right:12px;}
.case-ba__range{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:ew-resize;
  appearance:none;-webkit-appearance:none;}
.case-ba__frame:has(.case-ba__range:focus-visible){outline:2px solid var(--purple-2);outline-offset:2px;}
.case-ba figcaption{margin-top:12px;font-size:13.5px;color:var(--r-ink-soft);text-align:center;}

/* ============================================================
   SCREENSHOT SLIDER — horizontal scroll-snap carousel.
   Deliberately CSS-first: the track is a real scroll container, so touch,
   trackpad and keyboard all work with no JS at all. Slides are never hidden
   (no opacity or display toggling), which matters because the global
   prefers-reduced-motion rule kills every animation and transition with
   !important; a slider that faded slides in would be permanently blank for
   those users. The arrows and dots are progressive enhancement and stay
   hidden until the script marks the slider ready.
   ============================================================ */
.case-slider{margin:30px 0 0;}
.case-slider__track{display:flex;gap:16px;overflow-x:auto;scroll-snap-type:x mandatory;
  scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:none;}
.case-slider__track::-webkit-scrollbar{display:none;}
.case-slider__track:focus-visible{outline:2px solid var(--purple-2);outline-offset:4px;border-radius:18px;}
.case-slider__slide{flex:0 0 100%;min-width:0;scroll-snap-align:center;margin:0;}
.case-slider__slide img{width:100%;height:auto;display:block;border-radius:16px;
  border:1px solid var(--r-line-l);box-shadow:0 24px 54px -34px rgba(12,14,38,.5);}
.case-slider__cap{margin-top:12px;font-size:13.5px;line-height:1.45;color:var(--r-ink-soft);text-align:center;}
.case-slider__nav{display:none;align-items:center;justify-content:center;gap:14px;margin-top:16px;}
.case-slider.is-ready .case-slider__nav{display:flex;}
.case-slider__btn{width:34px;height:34px;border-radius:50%;border:1px solid var(--r-line-l);background:#fff;
  display:grid;place-items:center;cursor:pointer;color:var(--purple-2);font-size:15px;line-height:1;padding:0;}
.case-slider__btn:hover:not([disabled]){border-color:var(--purple-1);}
.case-slider__btn[disabled]{opacity:.3;cursor:default;}
/* Dots read as 7px but the button is a 24px square, so the tap target clears
   the WCAG minimum without the indicator looking heavy. The visible dot is the
   pseudo-element; the button itself is transparent. */
.case-slider__dots{display:flex;align-items:center;gap:2px;}
.case-slider__dot{width:24px;height:24px;border:0;padding:0;margin:0;cursor:pointer;
  background:none;display:grid;place-items:center;}
.case-slider__dot::before{content:"";width:7px;height:7px;border-radius:50%;background:#D9D6E6;}
.case-slider__dot[aria-current="true"]::before{width:20px;border-radius:100px;background:var(--purple-2);}
@media (prefers-reduced-motion:reduce){.case-slider__track{scroll-behavior:auto;}}

/* the inlined Beat Cyberto game module (.cygm, self-styled) sits centred */
.case-game{margin:34px 0 6px;display:flex;justify-content:center;}

/* ============================================================
   SLACK MESSAGE — a real client message rendered as a Slack
   (dark theme) capture, dropped between narrative sections. Static
   single message; the dark card stands out on the light body.
   ============================================================ */
.case-slack{margin:44px 0;width:100%;border-radius:16px;overflow:hidden;background:#1A1D21;
  border:1px solid rgba(255,255,255,.09);
  box-shadow:0 34px 70px -44px rgba(12,14,38,.7),0 6px 18px -12px rgba(0,0,0,.5);}
.case-slack__bar{display:flex;align-items:center;gap:7px;padding:11px 18px;border-bottom:1px solid rgba(255,255,255,.07);
  color:#D1D2D3;font-size:13.5px;font-weight:700;letter-spacing:-.1px;}
.case-slack__hash{color:#8E9297;font-weight:400;font-size:16px;line-height:1;}
.case-slack__msg{display:flex;gap:12px;align-items:flex-start;padding:16px 18px 4px;}
.case-slack__av{width:40px;height:40px;border-radius:9px;flex:0 0 auto;object-fit:cover;display:block;}
.case-slack__content{min-width:0;}
.case-slack__line{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:3px;}
.case-slack__name{font-size:15px;font-weight:800;color:#fff;letter-spacing:-.1px;}
.case-slack__time{font-size:12px;color:#9A9DA1;}
/* .case-slack scope raises specificity above .case-main p (which is class+element
   and would otherwise repaint the message in dark body ink on the dark card) */
.case-slack .case-slack__text{font-size:15px;line-height:1.5;color:#fff;margin:0;}
.case-slack__react{display:inline-flex;align-items:center;gap:6px;margin:10px 0 2px;padding:2px 10px 2px 8px;
  border-radius:12px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);}
.case-slack__react .emoji{font-size:14px;line-height:1;}
.case-slack__react .count{font-size:12px;font-weight:700;color:#C6C8CB;}
.case-slack__cap{padding:0 18px 15px 70px;margin:0;font-size:12.5px;color:#8E9297;}

/* ============================================================
   ABOUT-BOX FAQ — reuses the site .faq accordion (native <details>),
   compacted to sit inside the gradient "about the client" card so it
   doubles as a soft, GEO-friendly pitch for the featured client.
   ============================================================ */
.case-faq{margin:22px 0 4px;}
.case-faq__lead{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--r-ink-soft);margin:0 0 4px;}
.case-faq .faq__list{max-width:none;margin:0;}
.case-faq .faq__item{border-bottom:1px solid var(--r-line-l);}
.case-faq .faq__q{font-size:15px;padding:14px 2px;color:var(--navy);}
.case-faq .faq__a{font-size:14.5px;line-height:1.6;color:var(--r-ink-soft);padding:0 2px 16px;}

/* ============================================================
   LANDING PAGE PREVIEW — the real client page, rendered live in an
   iframe, cropped to its hero with a control that opens the rest in
   place. A screenshot goes stale the day the page changes; this does
   not, and it stays sharp at any zoom.

   The page is rendered at a fixed 1280px and scaled down to the column,
   because rendering it at ~700px would show its tablet layout instead
   of the design being discussed. JS sets --lp-scale and the frame
   height; without JS the iframe falls back to width:100% and the hero
   is still perfectly readable (never gate content on scripts).
   ============================================================ */
.case-lp{margin:30px 0 0;}
.case-lp__frame{position:relative;height:460px;border-radius:16px;overflow:hidden;
  background:#fff;border:1px solid var(--r-line-l);
  box-shadow:0 30px 60px -45px rgba(76,0,143,.45);
  transition:height .45s cubic-bezier(.4,0,.2,1);}
/* This is someone else's page on our site: a render, not a working page.
   pointer-events stops every click, tabindex keeps it out of the tab order. */
.case-lp__doc{display:block;width:100%;height:1400px;border:0;pointer-events:none;}
.case-lp.is-ready .case-lp__doc{width:1280px;transform-origin:0 0;transform:scale(var(--lp-scale,1));}
.case-lp__fade{position:absolute;left:0;right:0;bottom:0;height:120px;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,0),rgba(255,255,255,.94));
  opacity:1;transition:opacity .35s ease;}
.case-lp.is-open .case-lp__fade{opacity:0;}
/* controls sit under the frame, not floating inside it: once the frame is
   3000px tall an absolutely-positioned button is unreachable */
.case-lp__ctrls{display:none;align-items:center;justify-content:center;
  gap:18px;flex-wrap:wrap;margin-top:14px;}
/* is-measured, not is-ready: until the document height is known there is
   nothing to expand to, and a button that resolves to height 0 is worse
   than no button */
.case-lp.is-measured .case-lp__ctrls{display:flex;}
.case-lp__toggle{font:inherit;font-size:14px;font-weight:600;color:var(--purple-3);
  background:#fff;border:1px solid var(--r-line-l);border-radius:100px;
  padding:9px 22px;cursor:pointer;transition:border-color .2s,color .2s;}
.case-lp__toggle:hover{border-color:var(--purple-1);color:var(--purple-2);}
.case-lp__toggle:focus-visible{outline:2px solid var(--purple-2);outline-offset:3px;}
.case-lp .case-lp__cap{margin-top:12px;font-size:13.5px;line-height:1.45;
  color:var(--r-ink-soft);text-align:center;}
@media (prefers-reduced-motion:reduce){
  .case-lp__frame{transition:none;}
  .case-lp__fade{transition:none;}
}

/* ============================================================
   AD SWIPE FILE — two rows of live ad creative drifting in
   opposite directions, any card opens full size.

   A wall, not a carousel, on purpose: the point of a swipe file is
   volume and range, and a one-at-a-time slider hides both. Two rows
   moving opposite ways read as "there is a lot of this" in about the
   vertical space of a single screenshot.

   Every row is a real scroll container (overflow-x:auto) and the
   animation only runs on the track inside it. So the wall works three
   ways with the same markup: it drifts, it can be dragged or swiped,
   and with no JS at all (or under reduced motion, where the global
   rule kills the keyframes) it is still a pair of scrollable rows
   with every ad present. Nothing is ever hidden behind an animation.

   The script clones each track's cards once for the seamless -50%
   loop; the clones are aria-hidden and tabindex -1 so the wall costs
   13 tab stops, not 26.
   ============================================================ */
.case-swipe{margin:26px 0 0;}
.case-swipe__panel{background:var(--r-paper2);border:1px solid var(--r-line-l);
  border-radius:20px;padding:18px 0;overflow:hidden;}
.case-swipe__rows{display:flex;flex-direction:column;gap:14px;
  -webkit-mask-image:linear-gradient(to right,transparent,#000 5%,#000 95%,transparent);
  mask-image:linear-gradient(to right,transparent,#000 5%,#000 95%,transparent);}
.case-swipe__row{overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-webkit-overflow-scrolling:touch;}
.case-swipe__row::-webkit-scrollbar{display:none;}
/* No gap and no padding here on purpose. translateX(-50%) is 50% of the
   track's border box, so it only lands seamlessly when the two card sets
   are exactly half each. A flex gap adds one extra gap between the sets
   (n-1 inside a set, n between them) and padding adds more still, and
   either one makes the loop jump. The spacing is a margin on the card,
   so every card carries its own gap and the halves stay equal. */
.case-swipe__track{display:flex;width:max-content;
  animation:swipeDrift 78s linear infinite;will-change:transform;}
/* second row runs the other way and slower, so the two never lock into
   a grid and the wall keeps reading as a wall */
.case-swipe__row--back .case-swipe__track{animation-duration:96s;animation-direction:reverse;}
/* pause on any intent to look: hover, keyboard focus, or a finger down */
.case-swipe:hover .case-swipe__track,
.case-swipe:focus-within .case-swipe__track,
.case-swipe.is-held .case-swipe__track{animation-play-state:paused;}
@keyframes swipeDrift{from{transform:translateX(0);}to{transform:translateX(-50%);}}

.case-swipe__card{flex:0 0 auto;display:block;padding:0;margin:0 14px 0 0;border:1px solid var(--r-line-l);
  border-radius:14px;overflow:hidden;background:#fff;cursor:zoom-in;text-align:left;
  box-shadow:0 18px 40px -30px rgba(12,14,38,.5);
  transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease;}
.case-swipe__card:hover{transform:translateY(-3px);border-color:var(--purple-1);
  box-shadow:0 26px 54px -30px rgba(76,0,143,.45);}
.case-swipe__card:focus-visible{outline:2px solid var(--purple-2);outline-offset:3px;}
.case-swipe__card img{display:block;height:236px;width:auto;max-width:none;}
.case-swipe__hint{margin:12px 0 0;font-size:13.5px;line-height:1.45;
  color:var(--r-ink-soft);text-align:center;}

/* lightbox: built by the script, so it costs nothing when JS is off */
.case-swipe__lb{position:fixed;inset:0;z-index:200;display:flex;align-items:center;
  justify-content:center;padding:28px;background:rgba(4,6,46,.86);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);}
.case-swipe__lb[hidden]{display:none;}
.case-swipe__fig{margin:0;max-width:min(680px,100%);display:flex;flex-direction:column;align-items:center;}
.case-swipe__fig img{display:block;max-width:100%;max-height:72vh;width:auto;height:auto;
  border-radius:16px;box-shadow:0 40px 90px -40px rgba(0,0,0,.8);}
.case-swipe__cap{margin-top:16px;text-align:center;color:#fff;}
.case-swipe__cap b{display:block;font-size:11.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--purple-4);}
.case-swipe__cap span{display:block;margin-top:6px;font-size:14.5px;line-height:1.5;color:rgba(255,255,255,.82);}
.case-swipe__btn{position:absolute;width:44px;height:44px;border-radius:50%;padding:0;
  border:1px solid rgba(255,255,255,.28);background:rgba(255,255,255,.1);color:#fff;
  font-size:19px;line-height:1;cursor:pointer;display:grid;place-items:center;}
.case-swipe__btn:hover{background:rgba(255,255,255,.2);}
.case-swipe__btn:focus-visible{outline:2px solid var(--purple-4);outline-offset:3px;}
.case-swipe__btn--close{top:22px;right:22px;}
.case-swipe__btn--prev{left:22px;top:50%;margin-top:-22px;}
.case-swipe__btn--next{right:22px;top:50%;margin-top:-22px;}

@media (max-width:640px){
  .case-swipe__card img{height:190px;}
  .case-swipe__lb{padding:16px;}
  .case-swipe__fig img{max-height:62vh;}
  .case-swipe__btn{width:40px;height:40px;}
  .case-swipe__btn--prev{left:10px;}
  .case-swipe__btn--next{right:10px;}
  .case-swipe__btn--close{top:12px;right:12px;}
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width:920px){
  .case-hero{grid-template-columns:1fr;gap:36px;padding:118px 0 56px;}
  .case-hstats{padding:6px 24px;}
  .case-body{grid-template-columns:1fr;gap:0;padding-top:44px;padding-bottom:68px;padding-left:22px;padding-right:22px;}
  /* sidebar collapses to the top of the content, right under the stat bar */
  .case-aside{order:-1;margin-bottom:36px;}
  .case-aside__sticky{position:static;}
  .case-metrics{gap:14px;}
  /* three across gets too narrow to read the metric line below this */
  .case-rgrid{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:640px){
  .case-wrap{padding:0 22px;}
  .case-top__planet{width:540px;height:540px;right:-240px;bottom:-360px;}
  .case-top__ring--1{width:900px;height:900px;right:-420px;bottom:-560px;}
  .case-top__ring--2{display:none;}
  .case-stats{grid-template-columns:1fr;}
  .case-stat{border-left:0;padding:26px 0;border-top:1px solid rgba(255,255,255,.12);}
  .case-stat:first-child{padding-top:8px;border-top:0;}
  .case-stats--six .case-stat:nth-child(4){border-top:1px solid rgba(255,255,255,.12);}
  .case-metrics{grid-template-columns:1fr;}
  .case-shots{column-count:1;}
  /* JS reads the same 320 breakpoint value, keep the two in step */
  .case-lp__frame{height:320px;}
  .case-lp__fade{height:90px;}
  .case-rgrid{grid-template-columns:1fr;}
  .case-heroquote{padding:20px 20px 18px;}
  .case-about__inner{padding:24px 20px 22px;}
}
@media (max-width:380px){
  .case-wrap{padding:0 16px;}
  .case-hero h1{font-size:29px;}
}

/* reduced motion: content is visible by default (reveal system arms only
   below-fold), so nothing to rescue here beyond honouring the global rule. */
