/* site-specific additions layered on top of colors_and_type.css */

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--page);
  color: var(--fg-1);
  font-family: var(--font-body);
  text-transform: lowercase;
  -webkit-font-smoothing: antialiased;
}
.preserve-case { text-transform: none; }

button, input, textarea { font-family: inherit; text-transform: inherit; }
button { cursor: pointer; }
a { color: inherit; text-decoration: none; }

/* ── scrollbar (minimal) ─────────────────────────────────────────── */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #cfcfcf; border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: #bfbfbf; }

/* ── animations / micro-interactions ─────────────────────────────── */
@keyframes k-reveal-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
@keyframes k-reveal-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes k-ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@keyframes k-blink {
  0%, 60% { opacity: 1; }
  61%, 100% { opacity: 0.2; }
}
@keyframes k-pulse-dot {
  0% { box-shadow: 0 0 0 0 rgba(0, 210, 34, 0.5); }
  80% { box-shadow: 0 0 0 8px rgba(0, 210, 34, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 210, 34, 0); }
}
@keyframes k-draw-line {
  from { stroke-dashoffset: 100%; }
  to   { stroke-dashoffset: 0; }
}
@keyframes k-shimmer {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

.reveal { opacity: 0; transform: translateY(12px); transition: opacity .6s cubic-bezier(.22,1,.36,1), transform .6s cubic-bezier(.22,1,.36,1); }
.reveal.in { opacity: 1; transform: none; }

/* ── standard hovers ─────────────────────────────────────────────── */
.k-btn { transition: background .18s ease, color .18s ease, transform .18s ease, border-color .18s ease; }
.k-btn:hover { transform: translateY(-1px); }
.k-btn:active { transform: translateY(1px); }

.k-link { position: relative; }
.k-link::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 1px; background: currentColor; transform: scaleX(0);
  transform-origin: 0 50%; transition: transform .35s cubic-bezier(.22,1,.36,1);
}
.k-link:hover::after { transform: scaleX(1); }

.k-tile { transition: box-shadow .28s ease; }

/* ── utility for dot-grid tiles ──────────────────────────────────── */
.k-grid-tile {
  background-color: var(--page);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20'><rect x='0' y='0' width='2' height='2' fill='%23d6d6d6'/></svg>");
  background-size: 20px 20px;
}

/* ── live counter ticker (orange stats bar) ─────────────────────── */
.k-ticker-track {
  display: inline-flex; gap: 64px; white-space: nowrap;
  animation: k-ticker 40s linear infinite;
}

/* ── input reset ─────────────────────────────────────────────────── */
input, textarea {
  font: inherit; color: inherit; outline: none; border: none; background: transparent;
}
input::placeholder, textarea::placeholder { color: var(--fg-3); text-transform: lowercase; }

/* ── cursor on dot-grid for hero (faint crosshair effect) ────────── */
.k-cursor-none { cursor: crosshair; }

/* ── tweaks panel ────────────────────────────────────────────────── */
.tweaks {
  position: fixed; right: 20px; bottom: 20px; z-index: 9999;
  background: var(--ink); color: var(--paper);
  border-radius: 6px; padding: 14px 16px; min-width: 260px;
  font-family: var(--font-body); font-size: 12px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.25);
  display: none;
}
.tweaks.on { display: block; animation: k-reveal-up .3s cubic-bezier(.22,1,.36,1) both; }
.tweaks h4 { margin: 0 0 10px; font-size: 10px; font-weight: 500; opacity: 0.6; text-transform: lowercase; letter-spacing: 0.02em; }
.tweaks .row { display: flex; align-items: center; justify-content: space-between; padding: 6px 0; gap: 12px; border-top: 1px solid rgba(255,255,255,0.08); }
.tweaks .row:first-of-type { border-top: 0; }
.tweaks .row label { opacity: 0.8; }
.tweaks .pick { display: inline-flex; gap: 4px; }
.tweaks .pick button {
  background: transparent; color: rgba(255,255,255,0.6); border: 1px solid rgba(255,255,255,0.2);
  border-radius: 4px; padding: 4px 8px; font-size: 11px; text-transform: lowercase;
}
.tweaks .pick button.on { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.tweaks .swatch { width: 16px; height: 16px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.2); display: inline-block; }

/* ── card hover lift ─────────────────────────────────────────────── */
.k-card-hover { transition: transform .3s cubic-bezier(.22,1,.36,1); }
.k-card-hover:hover { transform: translateY(-3px); }

/* ── portfolio table hover ───────────────────────────────────────── */
.pf-row { transition: background .18s ease; }
.pf-row:hover { background: rgba(31,0,254,0.04); }
.pf-row:hover .pf-arrow { transform: translateX(4px); color: var(--blue); }
.pf-arrow { transition: transform .2s ease, color .2s ease; }

/* ── dashed blueprint border ─────────────────────────────────────── */
.bp-dashed { border: 1px dashed rgba(0,0,0,0.2); }
.bp-dashed-light { border: 1px dashed rgba(255,255,255,0.3); }

/* ── type refinements for Manrope fallback ───────────────────────── */
h1, h2, h3, h4, h5, h6, p { margin: 0; }


/* ─────────────────────────────────────────────────────────────────
   responsive layer — three breakpoints:
     • desktop  ≥ 992px        (default rules above)
     • tablet   768px – 991px  (max-width: 991px)
     • mobile   ≤  767px       (max-width: 767px)
   notes:
     - the site is heavily inline-styled (React style={}); we use
       attribute selectors `[style*="…"]` to override grids without
       editing every component. !important is required because
       inline styles win otherwise.
     - tokens (--sp-22, font scale, --dot-pitch) are scaled at the
       :root level so any var()-driven sizes follow automatically.
     ───────────────────────────────────────────────────────────── */

/* combo-hero headline → divider gap: bump bottom padding so the
   "under your brand" line doesn't kiss the borderTop separator below.
   Lives outside media queries — same fix is needed at every width. */
.kp-hero-combo-headline { padding-bottom: 24px !important; }

/* navigator rows (combo + experimental hero left island): if a class
   name doesn't fit on one line, truncate with an ellipsis instead of
   wrapping to a second line. Applies on every breakpoint. */
.kp-nav-rows { min-width: 0; }
.kp-nav-rows > div {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  max-width: 100%;
}

/* ── team-calls pin-and-advance scrollytelling ──────────────────────
   Outer is 3× viewport tall (one bucket per featured project). Inner
   is sticky, height: 100svh, padding matches what the original
   `<Section pad="12px 20px 20px">` used to add — the visual position
   of the tile is unchanged when the section first comes into view.
   Disabled on tablet/mobile (≤991px) where the section behaves like
   a normal block: outer collapses to auto-height and inner unstuck.
   The number 300svh = FEATURED.length (3) × 100svh; if you change
   the FEATURED count in sections_team_calls.jsx, update this too. */
.kp-tc-pin-outer {
  position: relative;
  height: 300svh;
}
.kp-tc-pin-inner {
  /* sticks below the sticky nav-shell (20px pad + 62px nav = 82px),
     same gap to nav that every other <Section pad="12px 20px 20px">
     gets. Tile inside subtracts the same 82px (via `100svh - 114`). */
  position: sticky;
  top: 82px;
  height: calc(100svh - 82px);
  padding: 12px 20px 20px;
  display: flex;
  flex-direction: column;
}

/* ── lifecycle-live pin-and-advance scrollytelling ──────────────────
   Same mechanic as team_calls above. Outer is N× viewport tall (one
   bucket per step in LL_STEPS); inner sticks at top:82px for one
   viewport per slide, releasing once the user has scrolled past the
   block. Disabled on mobile (≤767px) where the section becomes a
   normal static block and prev/next manipulate idx directly.
   The number 900svh = LL_STEPS.length (9 = 8 numbered + extras) ×
   100svh; if you change the LL_STEPS count in
   sections_lifecycle_live.jsx, update this too. */
.kp-ll-pin-outer {
  position: relative;
  height: 900svh;
}

/* Lifecycle replaced everywhere by LifecycleLive — the static 8-step
   list (#lifecycle) is hidden on every breakpoint. The interactive
   pinned walkthrough (#approach-live) shows on desktop at 1:1 and on
   tablet/mobile uses transform:scale to fit the viewport (see
   .kp-ll-stage-scaled below). Internal desktop styles stay unchanged
   on desktop; on tablet/mobile we just swap the reference dimensions
   to a portrait box and stack the stage's grid (meta on top, frame
   below) — JS reads the CSS dimensions to compute the scale factor. */
#lifecycle { display: none !important; }

.kp-ll-stage-scaled {
  width: 1280px;
  height: 620px;
}
.kp-ll-pin-inner {
  position: sticky;
  top: 82px;
  height: calc(100svh - 82px);
  padding: 12px 20px 20px;
  display: flex;
  flex-direction: column;
}

/* Pair-card caption stabilizer (base — applies all breakpoints).
   Reserves a worst-case caption height so cards don't change size
   project-to-project as user pages between FEATURED items with
   different role lengths ("Founders, Creative Mules" wraps to 2
   lines; "Dev Team" stays single-line). Without this reservation,
   cards "jump" in height during slide changes. Tablet block tightens
   it further to 60px since padding is reduced there. */
.kp-pair-caption {
  min-height: 88px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* Clamp both name AND role to 2 lines max. Name unclamped previously
   could wrap to 3 lines on narrow tablet column (`Anastasia & Alexandra`
   at ~149px effective width), pushing caption past min-height and making
   cards jump in size between projects. */
.kp-pair-caption > div:first-child,
.kp-pair-caption > div:last-child {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ═════════════════════════════════════════════════════════════════
   TABLET — 768 to 991
   ═════════════════════════════════════════════════════════════════ */
@media (max-width: 991px) {

  /* ── token rescale ─────────────────────────────────────────── */
  :root {
    --sp-22: 56px;
    --sp-20: 60px;
    --dot-pitch: 32px;

    --fs-display-xxl: 60px;
    --fs-display-xl:  44px;
    --fs-display-l:   34px;
    --fs-display-m:   24px;
    --fs-display-s:   20px;
    --fs-body-l:      15px;
  }

  /* ── section / card padding ────────────────────────────────── */
  /* nav-shell + sections share the same horizontal pad so the
     dark nav pill aligns with the cards beneath it */
  .kp-nav-shell { padding-left: 12px !important; padding-right: 12px !important; }
  .kp-section { padding-left: 12px !important; padding-right: 12px !important; }
  .kp-card[style*="padding: 40"] { padding: 28px !important; }
  .kp-card[style*="padding:40"]  { padding: 28px !important; }

  /* ── nav: hide overflowing meta, keep links + CTA ─────────── */
  .kp-nav-pill { display: none !important; }
  .kp-nav-time, .kp-nav-divider { display: none !important; }
  .kp-nav-links { gap: 14px !important; }
  .kp-nav-links a { font-size: 12px !important; }

  /* ── grids: collapse N-col → fewer columns ────────────────── */
  /* repeat(N, …) patterns */
  [style*="grid-template-columns: repeat(2"]   { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  [style*="grid-template-columns: repeat(3"]   { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  [style*="grid-template-columns: repeat(4"]   { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  [style*="grid-template-columns: repeat(5"]   { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  [style*="grid-template-columns: repeat(6"]   { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }

  /* `1fr 1fr 1fr 1fr` and `1fr 1fr 1fr` shrink to two */
  [style*="grid-template-columns: 1fr 1fr 1fr"] { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }

  /* big asymmetric two-pane layouts: stack at tablet */
  [style*="grid-template-columns: 1fr 1.3fr"],
  [style*="grid-template-columns: 1fr 1.25fr"],
  [style*="grid-template-columns: 1fr 1.1fr"],
  [style*="grid-template-columns: 1.1fr 1fr"],
  [style*="grid-template-columns: 1.25fr 1fr"],
  [style*="grid-template-columns: 1fr 1.6fr"],
  [style*="grid-template-columns: minmax(0, 1.35fr)"],
  [style*="grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr)"],
  [style*="grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr)"] {
    grid-template-columns: minmax(0, 1fr) !important;
    min-height: 0 !important;
  }

  /* fixed-width side rails — stack under content at tablet */
  [style*="grid-template-columns: 260px 1fr"],
  [style*="grid-template-columns: 300px 1fr 280px"],
  [style*="grid-template-columns: clamp(200px, 18vw, 260px) 1fr"],
  [style*="grid-template-columns: clamp(260px, 22vw, 340px) 1fr"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  /* dense data tables: allow horizontal scroll instead of cramming */
  [style*="grid-template-columns: 60px 1.5fr 1fr 1.3fr 1fr 40px"],
  [style*="grid-template-columns: 92px 1fr 1.6fr 130px"],
  [style*="grid-template-columns: 220px 1fr 120px"] {
    overflow-x: auto !important;
  }

  /* ── hero combo: keep navigator on the LEFT at tablet ─────── */
  /* Width is sized so even the deepest row ('▸ hero_features-grid')
     fits on one line at any tablet viewport without ellipsis. */
  .kp-hero-combo {
    grid-template-columns: clamp(220px, 28vw, 280px) minmax(0, 1fr) !important;
    height: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    overflow: visible !important;
  }
  .kp-hero-combo-nav {
    /* let it grow with main column; no max-height clip */
    max-height: none !important;
    overflow: hidden !important;
    /* match the right card's SectionHeader inset (16px) so the
       'navigator' label and the right card's overline sit on the
       same y-line */
    padding-top: 16px !important;
  }
  /* navigator top row: window-dots + 'navigator' label.
     Match SectionHeader's IconButton row height (32px) so the
     centred label aligns with the right card's overline. */
  .kp-hero-combo-nav > div:first-child {
    min-height: 32px !important;
  }
  /* compact deep indents on tablet — combined with the wider column,
     guarantees long class names fit on one line. inline-style values
     are exact strings from nav_hero.jsx, so the [style*=...] match
     is stable. */
  .kp-hero-combo-nav [style*="padding: 4px 6px 4px 44px"] { padding-left: 28px !important; }
  .kp-hero-combo-nav [style*="padding: 4px 6px 4px 58px"] { padding-left: 38px !important; }
  /* drop the ellipsis truncation on tablet — width is now sufficient,
     so we explicitly want full text on one line */
  .kp-hero-combo .kp-nav-rows > div {
    text-overflow: clip !important;
  }
  .kp-hero-combo-main { min-height: 0 !important; }

  /* on tablet: chips [white-label][client-first v2][sprint-ready] flow
     in-line, left-aligned with the h1 below — same posture as mobile.
     Earlier this row was absolutely-positioned top-right to share a
     line with a SectionHeader overline that's since been removed. */
  .kp-hero-combo .kp-hero-combo-main .kp-card .kp-hero-combo-headline > .reveal:first-child {
    position: static !important;
    top: auto !important;
    right: auto !important;
    left: auto !important;
    margin: 0 0 12px 0 !important;
  }
  .kp-hero-combo .kp-hero-combo-main .kp-card .kp-hero-combo-headline > .reveal:first-child > div {
    margin-bottom: 0 !important;
  }
  .kp-hero-combo .kp-hero-combo-main .kp-card > div:first-child > div:nth-child(2) > span:first-child {
    display: none !important;
  }

  /* hero variants A/B/C: relax min-heights so they don't crop content */
  [style*="min-height: 720"],
  [style*="minHeight: 720"] { min-height: 0 !important; }

  /* full-viewport sections (team_calls, hero combo) — let them grow */
  [style*="height: calc(100svh"] {
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
  }

  /* card hero/safe — hide far-corner annotation rail (right column tag) */
  [style*="position: absolute"][style*="right: 40"][style*="top: 150"] { display: none !important; }

  /* ── team-calls: pin stays active on tablet ────────────────────
     The global `[style*="height: calc(100svh"]` rule above forces the
     tile to auto-height on ≤991px, which would collapse our pinned
     viewport-locked tile. Restore the inline calc height (and the
     overflow clip) for `.kp-tc-tile` only — other full-viewport
     sections still flow naturally. */
  .kp-tc-tile {
    height: calc(100svh - 114px) !important;
    max-height: 900px !important;
    overflow: hidden !important;
  }

  /* zero horizontal pad on pin-inner at tablet — `.kp-section` already
     provides 12px each side; pin-inner's default 20px H pad would
     stack on top, making team_calls visibly narrower than every other
     section by 40px total at this breakpoint. Same bug as mobile. */
  .kp-tc-pin-inner {
    padding: 12px 0 20px !important;
  }

  /* ── lifecycle-live: same tablet treatment as team_calls ───────
     The global `[style*="height: calc(100svh"]` rule above forces the
     tile to auto-height on ≤991px, which would collapse our pinned
     viewport-locked tile. Restore the inline calc height (and the
     overflow clip) for `.kp-ll-tile` so the pin stays viewport-locked
     on tablet too. Note: we do NOT override .kp-ll-stage here — the
     inner desktop layout is preserved verbatim on tablet and a JS-
     driven transform:scale (see .kp-ll-stage-scaled) fits it. */
  .kp-ll-tile {
    height: calc(100svh - 114px) !important;
    max-height: 980px !important;
    overflow: hidden !important;
  }
  .kp-ll-pin-inner {
    padding: 12px 0 20px !important;
  }

  /* ── lifecycle-live tablet+mobile: portrait reference + stack ────
     Switch the scaled wrapper from 1280×620 landscape to 880×860
     portrait. Inside, the stage grid stacks meta on top of frame so
     the text reads first (per user spec). JS picks scale from the
     smaller of (areaW/refW, areaH/refH) — same logic, different ref. */
  .kp-ll-stage-scaled {
    width: 880px !important;
    height: 860px !important;
  }
  .kp-ll-stage {
    grid-template-columns: minmax(0, 1fr) !important;
    grid-template-rows: auto minmax(0, 1fr) !important;
    gap: 24px !important;
    align-items: stretch !important;
  }
  .kp-ll-stage > .kp-ll-frame-wrap {
    grid-row: 2;
    min-height: 0 !important;
  }
  .kp-ll-stage > div:not(.kp-ll-frame-wrap) {
    grid-row: 1;
  }
}


/* ═════════════════════════════════════════════════════════════════
   MOBILE — ≤ 767
   ═════════════════════════════════════════════════════════════════ */
@media (max-width: 767px) {

  /* ── token rescale ─────────────────────────────────────────── */
  :root {
    --sp-22: 40px;
    --sp-20: 40px;
    --sp-14: 36px;
    --sp-10: 28px;
    --dot-pitch: 24px;

    --fs-display-xxl: 44px;
    --fs-display-xl:  34px;
    --fs-display-l:   26px;
    --fs-display-m:   20px;
    --fs-display-s:   18px;
    --fs-body-l:      14px;
    --fs-body:        14px;
  }

  body { font-size: 14px; }

  /* ── section + nav shell padding ───────────────────────────── */
  /* keep horizontal pad identical so nav and cards share an edge */
  .kp-nav-shell { padding: 12px 10px 0 !important; }
  .kp-section   { padding-left: 10px !important; padding-right: 10px !important; }

  .kp-card[style*="padding: 40"] { padding: 18px !important; }
  .kp-card[style*="padding:40"]  { padding: 18px !important; }

  /* hand-coded paddings inside section bodies (`padding: "80px 40px..."` etc.) */
  [style*="padding: 80px 40px"] { padding: 32px 18px !important; }
  [style*="padding: 60px 40px"] { padding: 28px 18px !important; }
  [style*="padding: 48px 40px"] { padding: 24px 18px !important; }
  [style*="padding: 40px 40px"] { padding: 20px 18px !important; }

  /* ── nav: condense to logo + hamburger ─────────────────────── */
  .kp-nav { height: 56px !important; padding: 0 8px 0 14px !important; }
  .kp-nav-links { display: none !important; }
  .kp-nav-time, .kp-nav-divider, .kp-nav-cta { display: none !important; }
  .kp-nav-burger { display: inline-flex !important; }
  .kp-nav-cluster { gap: 8px !important; }

  /* ── grids: everything → 1 col ─────────────────────────────── */
  [style*="grid-template-columns: repeat(2"],
  [style*="grid-template-columns: repeat(3"],
  [style*="grid-template-columns: repeat(4"],
  [style*="grid-template-columns: repeat(5"],
  [style*="grid-template-columns: repeat(6"] {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 12px !important;
  }

  [style*="grid-template-columns: 1fr 1fr"] {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 12px !important;
  }

  /* asymmetric two-pane already handled at tablet, ensure 1col here */
  [style*="grid-template-columns: 1fr 1.3fr"],
  [style*="grid-template-columns: 1fr 1.25fr"],
  [style*="grid-template-columns: 1fr 1.1fr"],
  [style*="grid-template-columns: 1.1fr 1fr"],
  [style*="grid-template-columns: 1.25fr 1fr"],
  [style*="grid-template-columns: 1fr 1.6fr"],
  [style*="grid-template-columns: minmax(0, 1.35fr)"],
  [style*="grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr)"],
  [style*="grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr)"],
  [style*="grid-template-columns: 260px 1fr"],
  [style*="grid-template-columns: 300px 1fr 280px"],
  [style*="grid-template-columns: 220px 1fr 120px"],
  [style*="grid-template-columns: 92px 1fr 1.6fr 130px"],
  [style*="grid-template-columns: 60px 1.5fr 1fr 1.3fr 1fr 40px"],
  [style*="grid-template-columns: clamp(200px, 18vw, 260px) 1fr"],
  [style*="grid-template-columns: clamp(260px, 22vw, 340px) 1fr"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  /* ── hero combo: full stack, no svh-locked height ──────────── */
  .kp-hero-combo {
    grid-template-columns: minmax(0, 1fr) !important;
    height: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    overflow: visible !important;
  }
  /* hide webflow-style navigator island on phones — may bring back later */
  .kp-hero-combo-nav { display: none !important; }

  /* tablet rule pinned the [white-label][client-first v2][sprint-ready]
     chips to top-right of the card (so they sat on the same line as
     the SectionHeader overline). On phones there is no such overline
     and the right-side anchor leaves them visually detached from the
     headline. Restore normal flow + left-align with h1's left edge. */
  .kp-hero-combo .kp-hero-combo-main .kp-card .kp-hero-combo-headline {
    padding-top: clamp(20px, 4svh, 36px) !important;
    /* Tighten horizontal padding on mobile — desktop uses
       clamp(24,3vw,40)=24px which on top of section 10px puts
       content ~34px from screen edge (other sections ~10-20px).
       Match the visual rhythm: 14px inside the island. */
    padding-left: 14px !important;
    padding-right: 14px !important;
  }
  .kp-hero-combo-split {
    padding-left: 14px !important;
    padding-right: 14px !important;
  }
  .kp-hero-combo .kp-hero-combo-main .kp-card .kp-hero-combo-headline > .reveal:first-child {
    position: static !important;
    top: auto !important;
    right: auto !important;
    left: auto !important;
    margin-bottom: 12px !important;
  }
  .kp-hero-combo .kp-hero-combo-main .kp-card .kp-hero-combo-headline > .reveal:first-child > div {
    margin-bottom: 0 !important;
  }

  /* card / hero min-heights: drop or relax */
  [style*="min-height: 720"],
  [style*="minHeight: 720"],
  [style*="min-height: 640"],
  [style*="minHeight: 640"],
  [style*="min-height: 560"],
  [style*="minHeight: 560"],
  [style*="min-height: 540"],
  [style*="minHeight: 540"],
  [style*="min-height: 520"],
  [style*="minHeight: 520"],
  [style*="min-height: 460"],
  [style*="minHeight: 460"],
  [style*="min-height: 320"],
  [style*="min-height: 280"],
  [style*="min-height: 240"],
  [style*="min-height: 220"],
  [style*="min-height: 180"] { min-height: 0 !important; }

  /* drop full-viewport height locks */
  [style*="height: calc(100svh"] {
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
  }

  /* ── decorative absolute pieces: hide on mobile ───────────── */
  /* hero-safe annotation rail (right edge tag stack) */
  [style*="position: absolute"][style*="right: 40"][style*="top: 150"] { display: none !important; }
  /* hero-safe bottom signature line */
  [style*="position: absolute"][style*="bottom: 24"][style*="left: 40"][style*="right: 40"] { display: none !important; }

  /* hero combo bottom orange strip — let it wrap naturally */
  [style*="background: var(--orange)"][style*="justify-content: space-between"] {
    flex-wrap: wrap;
    gap: 8px;
  }

  /* ── primary CTA buttons (Button primitive, .k-cta) → full-width ─
     Project rule: hero-style CTAs always span the full row on mobile.
     Excludes IconButton (.k-btn span) and ad-hoc inline buttons in
     the team_calls hero (skip / full-portfolio) — those don't carry
     the .k-cta class. */
  button.k-cta {
    width: 100% !important;
    min-width: 0 !important;
  }
  /* anchor-wrapped buttons: let the wrapping <a> stretch too,
     otherwise the button's 100% resolves against an inline anchor */
  a:has(> button.k-cta) {
    display: block;
    width: 100%;
  }

  /* ── bracket connectors: keep team_calls bracket on mobile, hide
     sections_b motion bracket. The team_calls "aligned & shipped"
     bracket reads correctly with 2-column pair cards (which we
     restore below). The sections_b "motion & 3d" bracket points at
     a layout that fully collapses to one column on mobile so its
     metaphor still breaks — keep that hidden. */
  .kp-frames-connector { display: none !important; }

  /* ── team_calls bottom controls: stack on mobile ──────────────
     The three-column grid (kicker / pill / buttons) doesn't fit in
     a phone width. Stack vertically, hide the kicker (redundant on
     mobile since the section overline already says "featured · …"),
     center the pill, and stack skip + full-portfolio buttons below
     full-width with full-portfolio on top per the old-site layout. */
  .kp-tc-controls {
    grid-template-columns: 1fr !important;
    gap: 10px !important;
    text-align: center;
  }
  .kp-tc-controls > * { justify-self: stretch !important; }
  .kp-tc-controls > :first-child { display: none; }
  /* prev/next pill spans full width on mobile so it matches
     full-portfolio button below */
  .kp-tc-controls > div:nth-child(2) {
    width: 100%;
    justify-content: center;
  }
  .kp-tc-controls > div:last-child {
    flex-direction: column !important;
    width: 100%;
    gap: 8px !important;
  }
  /* hide skip on mobile — full-portfolio is the only CTA */
  .kp-tc-controls > div:last-child > button { display: none !important; }
  .kp-tc-controls > div:last-child > a { width: 100%; }
  .kp-tc-controls > div:last-child a > button {
    width: 100% !important;
    display: block;
  }

  /* ── team_calls mobile stage: pair cards on top, preview below ──
     Old-site composition (per user spec): two pair cards 2-col at top,
     "aligned & shipped" bracket pointing down at them inside pair-block,
     project preview below, skip + full-portfolio buttons stacked at
     bottom. Pin/sticky and JS auto-advance disabled at this breakpoint
     so users page projects manually via prev-next + dots. */
  .kp-tc-stage {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) !important;
    grid-template-rows: auto auto !important;
    gap: 12px !important;
    align-items: start !important;
  }
  /* Pair-block moves to row 1, frame to row 2. Stage's children are
     [pair-block, frame-wrap] in DOM order; grid-row swap pins them
     in desired visual order without DOM reshuffling. */
  .kp-tc-stage > .kp-tc-frame-wrap { grid-row: 2; }
  .kp-tc-stage > div:not(.kp-tc-frame-wrap) { grid-row: 1; }

  /* Preview window: enforce 3:2 aspect ratio on mobile so the
     browser-chrome reads at consistent proportions across breakpoints
     instead of stretching to whatever vertical space remains. */
  .kp-tc-frame-wrap {
    aspect-ratio: 3 / 2;
    min-height: 0 !important;
  }

  /* Pair cards: keep 2-column side-by-side layout on mobile (the
     global "1fr 1fr → 1col" rule would stack them). Cards stay small
     and readable at phone widths. */
  .kp-tc-pair-cards {
    grid-template-columns: 1fr 1fr !important;
  }

  /* Hide overline row + meta-below-cards on mobile to leave room
     for the stacked stage. The bottom controls already carry the
     "proj 01/03" indicator inside the prev-next pill, and the pin
     scroll hint is meaningless on a phone. */
  .kp-tc-overline-row { display: none !important; }
  .kp-tc-meta-row { display: none !important; }
  .kp-tc-scrub-hint { display: none !important; }
  /* Hide preview placeholder note + corner videoNote on mobile —
     they crowd the small preview frame. Push the centered placeholder
     copy down so the section tag has breathing room from the window
     chrome at the top. */
  .kp-tc-preview-note { display: none !important; }
  .kp-tc-video-note { display: none !important; }
  .kp-tc-preview-copy {
    top: calc(50% + 18px) !important;
  }

  /* On mobile pin/sticky mechanic is intentionally disabled — section
     becomes a normal static block. Outer collapses to its content
     height; inner unsticks; tile drops viewport-locked height and
     overflow:hidden so stacked content (preview on top, pair cards
     below, controls at bottom) flows naturally. JS auto-advance is
     also bypassed at ≤767px in sections_team_calls.jsx. */
  .kp-tc-pin-outer {
    height: auto !important;
  }
  .kp-tc-pin-inner {
    position: static !important;
    top: auto !important;
    height: auto !important;
    /* zero horizontal pad — `.kp-section` already adds 10px each side
       on mobile; doubling here was making this section visibly narrower
       than every other section on a phone viewport. */
    padding: 12px 0 16px !important;
  }
  .kp-tc-tile {
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow: visible !important;
    padding: 14px 14px 14px !important;
  }

  /* ── lifecycle-live mobile: pin OFF, manual prev/next slider ──────
     Per spec: on mobile the section no longer fits itself to the
     viewport height — it becomes a plain slider. Pin disabled, tile
     auto-height, meta rendered outside scaled wrapper at native
     typography (LifecycleLive JSX renders <LLMeta/> conditionally
     when isMobile=true). The scaled wrapper holds only the preview
     frame at desktop reference dimensions, scaled to fit phone width. */
  .kp-ll-pin-outer { height: auto !important; }
  .kp-ll-pin-inner {
    position: static !important;
    top: auto !important;
    height: auto !important;
    padding: 12px 0 16px !important;
  }
  .kp-ll-tile {
    height: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    overflow: visible !important;
  }
  /* Hide top tag-pills row (01..08+) and the meta's mini progress
     dots; the bottom prev/next pill already shows the position. */
  .kp-ll-tag-pills { display: none !important; }
  .kp-ll-progress-dots { display: none !important; }
  /* Step number ("01") gets dialed back ~35% on phones — at 7.5svh
     it dominates the meta block on narrow viewports. */
  .kp-ll-step-num {
    font-size: 44px !important;
  }
  /* CTA height: desktop default is 62px (set in primitives.jsx).
     On phones that's oversized — hero already inlines 48 to compensate,
     this collapses every other Button.k-btn to the same height for a
     uniform mobile rhythm. The `button.k-btn` selector keeps IconButton
     (a <span> with the same class) at its native 22×22 chip size. */
  button.k-btn {
    height: 48px !important;
  }
  /* WhatWeBring 4-tile grid: on desktop each tile is min-height 240 with
     the stat row pushed to the bottom (margin-top:auto) so all four align
     across the row. On a stacked phone layout that just leaves a big void
     between "01/04" and the stat — collapse to natural height and let
     the stat sit right after the meta row. */
  .kp-wwb-tile {
    min-height: 0 !important;
    padding: 18px !important;
    gap: 10px !important;
  }
  .kp-wwb-stat {
    margin-top: 0 !important;
  }
  /* Slack-style progress-report mock: desktop padding/gaps/avatar are
     sized for a wide card. On a phone the message gets pushed off the
     left margin by ~80px (28 padding + 40 avatar + 14 gap). Mirror the
     real Slack mobile rhythm — ~14 padding, 30 avatar, 10 gap. */
  .kp-slack-chrome {
    padding: 10px 14px !important;
  }
  /* The channel chrome packs channel name + members + date into one
     row. At 390px the row breaks across three wrap-lines. Drop the
     dot-separator + "4 members" + the right-hand date on mobile —
     real Slack's mobile channel header is just the name. */
  .kp-slack-chrome-dot,
  .kp-slack-chrome-members,
  .kp-slack-chrome-date {
    display: none !important;
  }
  .kp-slack-body {
    padding: 16px 14px 18px !important;
  }
  .kp-slack-msg {
    gap: 10px !important;
  }
  .kp-slack-avatar {
    width: 30px !important;
    height: 30px !important;
    border-radius: 6px !important;
    font-size: 12px !important;
  }
  /* Slack's quote-block on mobile sits tight against the parent text. */
  .kp-slack-body blockquote,
  .kp-slack-body [style*="borderLeft"] {
    padding-left: 10px !important;
  }
  /* Collaborators frames (Spline + Rive): on desktop the two frames sit
     side-by-side with a 340px min-height that crops the artboards on a
     phone-width column. Stack them vertically and let aspect-ratio
     drive the height — 4:5 fits Yuji's character_creator_alien.riv
     fully (and the same proportion gets re-used for the Spline scene
     above so they read as a matched pair). */
  .kp-collab-frames {
    grid-template-columns: 1fr !important;
    /* Desktop relies on the bracket-connector (.kp-frames-connector) to
       create the visual gap between the overline cluster and the
       frames. That connector is display:none on mobile, so add the
       breathing room here as a margin-top on the frames grid itself. */
    margin-top: 24px !important;
  }
  /* Section container: desktop top padding is 7svh (~60px on a phone)
     which leaves a huge dead band above the "modern websites" heading.
     Tighten on mobile so the section sits closer to its neighbour. */
  .kp-collab-tile {
    padding: 28px 20px 24px !important;
  }
  /* Pixel-perfect section: desktop is a 2-col × 2-row composition
     (huge blue "rubber" panel left, preproject + qa stacked right).
     On a phone the right panels get squeezed into a ~180px column and
     wrap one-word-per-line. Collapse the whole thing into a single
     vertical stack and undo the inner 2-col grids in each panel. */
  .kp-pp-grid {
    grid-template-columns: 1fr !important;
    grid-template-rows: auto !important;
  }
  .kp-pp-left {
    grid-row: auto !important;
    min-height: clamp(380px, 60svh, 520px) !important;
  }
  .kp-pp-panel {
    grid-template-columns: 1fr !important;
  }
  /* Page-builder section: drop the "webflow components · green" pill on
     mobile — the same info is conveyed by the green dots on each block
     in the catalog below, and removing it lets the overline ("page
     builder kit · for marketing teams") share its row with the info
     icon at the regular header rhythm (no flex-column hack, no padding
     bump). */
  .kp-pb-header-pill {
    display: none !important;
  }
  /* Canvas chrome inside the page builder mock: the faux-tab text was
     padded 4px from the card edge while the block outlines below were
     padded 14px — produced a visible misalignment along the left/right
     edges. Match them at 14px so the dots-row, the tab text, and the
     stacked-block outlines all share one vertical edge. Also hide the
     desktop/tablet/mobile breakpoint toggles — they're noise on a phone
     viewport. */
  .kp-pb-canvas-chrome {
    padding: 0 14px !important;
  }
  .kp-pb-canvas-bps {
    display: none !important;
  }
  /* Footer: doesn't carry the .kp-section class, so the global mobile
     rule `.kp-section { padding: 10px }` didn't apply — and the inner
     ink card kept its desktop 40px padding too. Match both to the rest
     of the page so the footer's side gutters line up with every other
     section's card edge. */
  .kp-footer {
    padding: 12px 10px 20px !important;
  }
  .kp-footer-inner {
    padding: 28px 18px !important;
    gap: 36px !important;
  }
  /* Page-builder section: act-2 live builder is a 3-col grid (tray /
     canvas / brand-lock) on desktop; stack vertically on phones and
     drop the 540px min-heights so each panel sizes to its content. */
  .kp-pb-builder {
    grid-template-columns: 1fr !important;
  }
  .kp-pb-builder > * {
    min-height: 0 !important;
  }
  /* Act-3 catalog: 6-col on desktop falls back to a phone-friendly 2-col
     grid (2 felt cramped at 3 in user test — labels were getting clipped). */
  .kp-pb-catalog {
    grid-template-columns: 1fr 1fr !important;
  }
  /* Catalog header tabs scroll horizontally instead of wrapping into a
     second row so they keep their Tag pill shape. */
  .kp-pb-catalog-tabs {
    width: 100%;
    overflow-x: auto;
    flex-wrap: nowrap !important;
    -webkit-overflow-scrolling: touch;
  }
  .kp-pb-catalog-tabs > * { flex-shrink: 0; }
  /* Footer-strip: stack copy + CTAs as separate rows so the "request
     the kit" button doesn't land on top of the heading. */
  .kp-pb-footer {
    flex-direction: column !important;
    align-items: stretch !important;
    padding: 18px !important;
  }
  .kp-pb-footer-actions {
    width: 100%;
  }
  .kp-pb-footer-actions > button.k-btn {
    width: 100% !important;
    min-width: 0 !important;
  }
  /* Portfolio table: desktop is a 6-col grid (no. / project / type /
     industry / partner / arrow). On a phone the column header collapses
     to a single tall column (each label on its own line) and rows look
     just as fractured. Turn each row into a self-contained card with
     name + type/ind/partner stacked, drop the header entirely. */
  .kp-portfolio-head {
    display: none !important;
  }
  .kp-portfolio-row {
    grid-template-columns: 1fr auto !important;
    grid-template-areas:
      "no arrow"
      "project arrow"
      "type type"
      "ind ind"
      "partner partner" !important;
    gap: 4px 10px !important;
    padding: 14px 16px !important;
  }
  .kp-pf-no { grid-area: no; }
  .kp-pf-project { grid-area: project; font-size: 15px !important; }
  .kp-pf-type { grid-area: type; }
  .kp-pf-ind { grid-area: ind; font-size: 12px !important; }
  .kp-pf-partner {
    grid-area: partner; font-size: 12px !important;
    font-family: var(--font-mono); color: var(--fg-3) !important;
  }
  .kp-pf-arrow { grid-area: arrow; align-self: center; }
  /* Featured snapshot cards: 2-col on desktop, stack on mobile. */
  .kp-portfolio-featured {
    grid-template-columns: 1fr !important;
  }
  /* Collab section (#collab): SectionHeader is absolutely positioned
     with overline left + tab pills right; on desktop the left column
     padding-top: 80 keeps them clear of the heading, but on mobile the
     pills overlap the "ready to build" copy and the tabs spill past the
     right edge. Stack the grid; stack the header internally so overline
     sits above pills, both full-width; bump content padding to clear
     the header. */
  .kp-collab-grid {
    grid-template-columns: 1fr !important;
  }
  #collab .kp-card > div:first-child {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 8px;
  }
  .kp-collab-tabs {
    display: flex !important;
    width: 100%;
    box-sizing: border-box;
  }
  .kp-collab-tabs > button { flex: 1; justify-content: center; }
  .kp-collab-left {
    padding: 110px 22px 32px !important;
  }
  .kp-collab-right {
    padding: 32px 22px 32px !important;
  }
  /* When mode === "meeting" right uses padding:0 inline; preserve that
     so the calendar embed flushes against its container edges. */
  #collab .kp-collab-right[style*="padding: 0"] {
    padding: 0 !important;
  }
  /* Smooth out the background wash transition on mobile — pin's
     scroll-driven RAF doesn't run here so the wash jumps between
     positions. Apply only on mobile (desktop's RAF would fight
     the transition and produce jitter). */
  .kp-ll-progress-wash {
    transition: transform 0.55s cubic-bezier(.22, 1, .36, 1) !important;
  }

  /* ── Mobile type rhythm ─────────────────────────────────────────
     Bring all section headings to a consistent 32px floor on mobile,
     matching the hero h1. Many sections set inline clamp(36px, ...)
     which on a 414 viewport resolves to 36px — visibly heavier than
     the hero. Universal override here keeps the rhythm consistent
     across capabilities / process / what-we-bring / progress-report /
     handover-course / practices / reviews / collaborators. */
  .k-display-xl,
  .k-display-l {
    font-size: 32px !important;
    line-height: 1.08 !important;
  }
  .k-display-m {
    font-size: 22px !important;
    line-height: 1.15 !important;
  }

  /* Process section mobile — gantt collapses to timeline-only
     (phase number + title + duration move INTO each milestone bar
     so the table doesn't need its 220px label / 120px duration cols).
     Vertical paddings tightened. Still horizontally scrollable
     (Notion-style) for narrow phones via min-width on each row. */
  .kp-process-headline { margin-top: 24px !important; }
  .kp-process-gantt {
    overflow-x: auto !important;
    overflow-y: hidden !important;
    -webkit-overflow-scrolling: touch;
  }
  .kp-process-gantt > div {
    min-width: 480px !important;
    grid-template-columns: minmax(0, 1fr) !important;
    padding: 8px 14px !important;
  }
  /* Hide left (phase number+title) and right (duration) columns —
     their content is now inside each milestone bar. */
  .kp-process-gantt > div > *:first-child,
  .kp-process-gantt > div > *:last-child {
    display: none !important;
  }
  /* Swap which label inside each bar is visible. */
  .kp-gantt-bar-tag { display: none !important; }
  .kp-gantt-bar-label-mobile { display: inline-flex !important; align-items: center; }
  /* Stage-area on mobile: aspect-ratio matches scaled reference
     (1280:800) so the area's own height tracks the visible scaled
     height — no phantom whitespace below the preview. Slightly
     taller than desktop's 1280:620 so the mini-preview reads at a
     decent size on phones (~414×258 visible at 414px width). */
  .kp-ll-stage-area {
    flex: none !important;
    aspect-ratio: 1280 / 800;
    height: auto !important;
    justify-content: flex-start !important;
    align-items: flex-start !important;
    margin-top: 12px;
  }
  /* Reference: 1280px desktop width, 800px height (chosen for
     comfortable phone-sized preview). Scenes use inset:0 so they
     render at full reference dimensions, then scale down via the
     CSS var --ll-scale set by JS. */
  .kp-ll-stage-scaled {
    width: 1280px !important;
    height: 800px !important;
    transform-origin: top left !important;
  }
  /* Stage shell on mobile is just the scaled frame container — no
     2-col grid (LLMeta is rendered outside scaled at native size).
     Reset the frame-wrap grid-row override from the tablet block —
     otherwise the explicit row 2 forces the browser to add an
     implicit row 2 (49px) and frame-wrap collapses there. */
  .kp-ll-stage {
    grid-template-columns: minmax(0, 1fr) !important;
    grid-template-rows: minmax(0, 1fr) !important;
  }
  .kp-ll-stage > .kp-ll-frame-wrap {
    grid-row: auto !important;
    grid-column: auto !important;
  }
  /* Bottom controls — stack vertically for narrow phone widths.
     Center pill + buttons stay readable; left kicker hides as before. */
  .kp-ll-controls {
    grid-template-columns: 1fr !important;
    gap: 10px !important;
    text-align: center;
  }
  .kp-ll-controls > * { justify-self: stretch !important; }
  .kp-ll-controls > :first-child { display: none; }
  .kp-ll-controls > div:nth-child(2) {
    width: 100%;
    justify-content: center;
  }
  .kp-ll-controls > div:last-child {
    flex-direction: column !important;
    width: 100%;
    gap: 8px !important;
  }
  .kp-ll-controls > div:last-child > button { display: none !important; }
  .kp-ll-controls > div:last-child > a { width: 100%; }
  .kp-ll-controls > div:last-child a > button {
    width: 100% !important;
    display: block;
  }

  /* ── hero features 2×3 grid: keep cells contiguous on mobile ─────
     The global "1fr 1fr → 1col + gap:12px" rule turns this bordered
     card into spaced cells, which exposes uneven inline borders
     (right-border on every other item, no bottom-border on items 5/6).
     Override: zero gap + clean separator borders, only between items. */
  .kp-hero-features {
    gap: 0 !important;
  }
  .kp-hero-features > .k-tile {
    border-right: none !important;
    border-bottom: 1px solid var(--stroke-divider) !important;
  }
  .kp-hero-features > .k-tile:last-child {
    border-bottom: none !important;
  }

  /* ── type clamps inside hero (already use clamp) — let them shrink ── */
  /* nothing to do, they're driven by vw/svh */

  /* ── tweaks panel: shrink to fit phone ─────────────────────── */
  .tweaks {
    right: 8px !important; bottom: 8px !important;
    min-width: 0 !important; max-width: calc(100vw - 16px);
    padding: 10px 12px !important;
  }

  /* ── lifecycle rows: bigger horizontal padding on mobile ───────
     Inline padding is `26px 4px` for 4-column desktop layout where the
     parent card's 40px pad does the visual breathing. On mobile the
     card pad collapses to 18px (line ~412), leaving content only 22px
     from screen edge — feels cramped. Mirror the card pad here so the
     inset is symmetric (18 + 18 = 36px from screen edge, ~equivalent
     visual feel as desktop's 40 + 4). */
  #lifecycle .k-tile {
    padding: 26px 18px !important;
  }

  /* ── scrollbar can take a bit more room than 10px on mobile ─ */
  ::-webkit-scrollbar { width: 6px; height: 6px; }
}


/* ═════════════════════════════════════════════════════════════════
   WIDER MOBILE — 481 to 767  (team_calls vertical budget guard)
   At narrow phones (≤480) pair-card image stays 1:1 — fits.
   At wider phones (481–767) cards grow proportionally with width
   and a 1:1 image becomes too tall, pushing bottom controls out
   of tile height (overflow:hidden clips full-portfolio button,
   prev-next pill overlaps cards). Cap pair-card image at 16/10
   so cards stay short enough that preview + cards + connector +
   controls all fit inside `calc(100svh - 96px)` budget.
   ═════════════════════════════════════════════════════════════════ */
@media (min-width: 481px) and (max-width: 767px) {
  .kp-pair-media {
    aspect-ratio: 16 / 10 !important;
  }
  /* hide decorative connector on wider phones — bracket arms reach
     too far visually when cards become small relative to their parent
     width, and a quiet caption-less stack reads cleaner here. */
  .kp-pair-connector { display: none !important; }
}

/* ═════════════════════════════════════════════════════════════════
   SHARED — anti-overflow utilities at any narrow viewport
   ═════════════════════════════════════════════════════════════════ */
@media (max-width: 991px) {
  /* prevent React inline `width: 1180/1200` from forcing horizontal scroll */
  [style*="max-width: 1180"],
  [style*="max-width: 1200"] { max-width: 100% !important; }

  /* clamp huge raw inline font-sizes used outside clamp() */
  h1[style*="font-size: 96"],
  h1[style*="font-size: 104"],
  h1[style*="font-size: 180"] { font-size: clamp(36px, 8vw, 72px) !important; }

  /* let tags / pill rows wrap instead of overflow */
  [style*="display: inline-flex"][style*="gap: 8"] { flex-wrap: wrap; }
}

/* ═════════════════════════════════════════════════════════════════
   TABLET ONLY — 768 to 991  (team_calls stage refinement)
   The global "(clamp(260px, 22vw, 340px) 1fr) → 1col" collapse at
   line 254 is fine for most asymmetric grids, but on team_calls it
   pushes the two pair cards on top of the project preview, which
   then squashes vertically. Override: keep two columns on tablet,
   narrow the left rail so the preview gets meaningful width, and
   stack the two pair cards vertically (one card wide) inside it.
   Bracket connector is hidden too — its arms point at horizontal
   columns, the metaphor breaks once cards go vertical.
   ═════════════════════════════════════════════════════════════════ */
@media (min-width: 768px) and (max-width: 991px) {
  .kp-tc-stage {
    grid-template-columns: clamp(140px, 22vw, 200px) minmax(0, 1fr) !important;
    gap: clamp(14px, 2vw, 24px) !important;
  }
  .kp-tc-pair-cards {
    grid-template-columns: minmax(0, 1fr) !important;
    /* width:100% replaces a previous `align-self: center` — in a flex-
       column parent, align-self is the CROSS axis (horizontal), so it
       was shrinking the grid to content width. Caption text length
       differed between slides (e.g. "Founders, Creative Mules" longer
       than "Dev Team") → grid width changed → card media (aspect-
       ratio 16/10) widened/heightened → visible card-size jump on
       slide change. Vertical centering is already handled by the
       parent flex column's justify-content: center. */
    width: 100% !important;
    align-content: center !important;
    gap: 10px !important;
  }
  .kp-pair-connector { display: none !important; }
  /* Pair-card media: drop from 1:1 to 16/10 on tablet so two stacked
     cards + captions don't eat enough vertical to clip into eyebrow.
     Inline aspectRatio: "1 / 1" wins without !important. */
  .kp-pair-media {
    aspect-ratio: 16 / 10 !important;
  }
  /* Pair-card caption: tighten padding + line-height so each card
     gives back another ~10-14px vertical to the stack. */
  .kp-tc-pair-cards > div > div:last-child {
    padding: 8px 10px !important;
    line-height: 1.25 !important;
  }
  /* Lock caption to a FIXED 96px box (height + max-height, not just
     min-height). Worst-case content height = 2-line name (32.5px at
     line-height 1.25) + 4px gap + 2-line role (27.5px) + 16px vert
     padding = 80px, comfortably under 96. min-height alone still let
     captions grow when font metrics nudged content over 96, making
     cards a few px taller on some slides — that's the project-to-
     project size jump we kept seeing. Inner divs already clamp at
     2 lines + overflow:hidden, so locking the box is safe. */
  .kp-pair-caption {
    height: 96px !important;
    min-height: 96px !important;
    max-height: 96px !important;
    box-sizing: border-box;
    overflow: hidden;
  }
  /* Preview window: consistent 3:2 aspect ratio across breakpoints
     instead of stretching to fill the tile column (which would make
     it portrait at tablet width). align-self: center keeps the empty
     vertical space balanced above and below. */
  .kp-tc-frame-wrap {
    aspect-ratio: 3 / 2;
    align-self: center;
    min-height: 0 !important;
  }
  /* Hide the meta-row on tablet — same rule as mobile (line ~626).
     "proj N/3 · client" duplicates the 01/02/03 tags at the top and
     the kopytok pill at the bottom; "scroll to scrub preview →"
     duplicates the LiveDot hint inside the preview frame. With meta
     visible, the parent flex column centers (connector + cards +
     meta) as a group, pushing the cards' visual center above the
     right preview's center. Hiding restores Y-alignment between
     pair cards and the project frame. */
  .kp-tc-meta-row {
    display: none !important;
  }
}

/* ═════════════════════════════════════════════════════════════════
   STAT STRIP — gap-as-background dividers across breakpoints
   The grid container is painted in `--stroke-divider`, gap=1px,
   each cell repaints itself paper. The Card's overflow:hidden +
   border-radius crops the outer ring. This handles 5-col / 2-col /
   1-col wraps without per-cell border logic. Mobile global rule at
   line ~433 forces gap:12px on every repeat() grid — explicitly
   pin gap back to 1px here so dividers stay tight on mobile.
   ═════════════════════════════════════════════════════════════════ */
@media (min-width: 768px) and (max-width: 991px) {
  /* On tablet repeat(5)→repeat(2) (line ~254). Five cells in two
     columns leaves the 5th alone in row 3 — span it across both
     columns so it reads as a closing wide cell, not an orphan. */
  .kp-stat-strip > .k-tile:nth-child(5) {
    grid-column: 1 / -1;
  }
  /* 3-card sections (Capabilities, Practices, …) — same orphan-row
     treatment. The global grid rule collapses 1fr 1fr 1fr → repeat(2)
     at this breakpoint, leaving the 3rd card alone in row 2. Span it
     full width to close the block cleanly. Children are .reveal
     wrappers, not the .k-tile directly, so we target wrapper position.
     Add new section classes here as more 3-card grids appear. */
  .kp-capabilities-grid > :nth-child(3),
  .kp-practices-grid > :nth-child(3),
  .kp-page-builder-rail > :nth-child(3) {
    grid-column: 1 / -1;
  }

  /* PixelPerfect — on tablet stack all three panels vertically.
     The default 2-col grid (1.35fr | 1fr) with the left panel
     spanning both rows leaves the right column too narrow — words
     in "preproject guidance for designers" wrap one-per-line.
     Force 1-col + reset the grid-row span so all three render in
     DOM order. ID selector beats the global attribute-selector
     override above for the inner row reset. */
  #pixel-perfect .kp-section-inner > div[style*="grid-template-columns"] {
    grid-template-columns: minmax(0, 1fr) !important;
    grid-template-rows: auto !important;
  }
  #pixel-perfect .kp-section-inner > div[style*="grid-template-columns"] > * {
    grid-row: auto !important;
    grid-column: auto !important;
  }
}
@media (max-width: 767px) {
  /* Override the global `gap: 12px !important` from line ~435. */
  .kp-stat-strip {
    gap: 1px !important;
  }
  /* Tighten cells on mobile — full-width single column with the
     desktop padding (36 24) + min-height 140 produces ~5 × 220px
     of vertical real estate. Drop padding and min-height so the
     stat strip stays a digestible block. */
  .kp-stat-strip > .k-tile {
    padding: 22px 18px !important;
    min-height: 0 !important;
  }
}

/* ── 3-card sections cards (tablet + mobile) ─────────────────────
   Tighter padding inside the cards once they're on a phone-narrow
   column, and the bullet list pulls up against the blurb (gap halved
   via negative margin) so the eye groups them as one block. */
@media (max-width: 991px) {
  .kp-capabilities-grid .k-tile,
  .kp-practices-grid .k-tile {
    padding: 18px !important;
    gap: 14px !important;
    min-height: 0 !important;
  }
  /* desktop pushes the bullet list to the bottom via margin-top:auto so
     all 3 cards align — on a stacked phone layout we want the list to
     sit tight under the blurb instead. */
  .kp-capabilities-grid .k-tile > ul,
  .kp-practices-grid .k-tile > ul {
    margin-top: -7px !important;
  }
}

/* Collaborators frames (Spline + Rive): the Rive artboard's intrinsic
   ratio is ~11:7, and we want both frames to read as a matched pair, so
   the stage uses that ratio at every breakpoint (no fixed min-height —
   fit:Contain in the Rive runtime handles letterboxing within the box). */
.kp-collab-stage {
  aspect-ratio: 11 / 7;
  min-height: 0;
}

/* always: kill horizontal scroll without creating a scroll container.
   `overflow-x: hidden` would break `position: sticky` for descendants
   (because hidden on one axis forces the other to `auto`, so body becomes
   the y-scroll container instead of the viewport). `clip` clips without
   creating a scroll container, so sticky still binds to the viewport. */
html, body { overflow-x: clip; }
