/* ═══════════════════════════════════════════════════════════════
   intro-stats.css
   
   Ported VERBATIM from prototype 01-homepage.html:
   - #intro / .intro-wrap / .intro-head-block / titles  (lines 932-947)
   - .vw-stats with :root brand palette + cards         (lines 949-1183)
   - mobile spacing tweaks                              (lines 3405-3443)
   ═══════════════════════════════════════════════════════════════ */

#intro{
  background:var(--white);
  padding:120px 24px 80px;  /* more hero→about space, tighter about→works */
  border-bottom:1px solid var(--line);
}
.intro-wrap{max-width:var(--max);margin:0 auto}
.intro-head-block{text-align:center;margin-bottom:60px}
.intro-main-title{
  font-size:clamp(1.8rem,4vw,2.8rem);font-weight:900;font-family:var(--font-title);
  letter-spacing:-0.04em;line-height:1.12;margin-bottom:14px;
}
.intro-main-title em{font-style:normal;color:var(--orange)}
.intro-lead{
  font-size:1rem;font-weight:300;color:var(--mid);
  line-height:1.72;max-width:540px;margin:0 auto 28px;
}

/* ═══════════════════════════════════════
   STATS — The work, in numbers (v21)
═══════════════════════════════════════ */

  :root {
    /* =============================================================
       BRAND PALETTE  —  tweak here to re-skin the whole section
       ============================================================= */
    --vw-coral:  #FB7E5D;
    --vw-pink:   #F472B6;
    --vw-purple: #A78BFA;
    --vw-blue:   #38BDF8;

    /* Soft tint variants (the drifting wash behind each card) */
    --vw-coral-wash:  #fed4bf;
    --vw-pink-wash:   #fbcfe8;
    --vw-purple-wash: #ddd6fe;
    --vw-blue-wash:   #bae6fd;

    /* RGB channels for rgba() in shadows / outlines */
    --vw-coral-rgb:  251, 126, 93;
    --vw-pink-rgb:   244, 114, 182;
    --vw-purple-rgb: 167, 139, 250;
    --vw-blue-rgb:   56, 189, 248;

    /* Typography — clamp() scales with viewport */
    /* v0.8.3 (Vic feedback): cap reduced from 72px → 56px. At 1920×1080
       and similar wide desktops, the 4-column stats grid with max-width
       1280px gives each card ~320px. The "1,500+" string at 72px font-size
       with letter-spacing -0.045em ran wider than 320px and overlapped
       neighboring cards. 56px gives enough headroom for the longest
       string at the longest letter-spacing. Smaller viewports still scale
       down via the clamp() lower bound. */
    --vw-size-number:     clamp(40px, 4.6vw, 56px);
    --vw-size-label:      clamp(18px, 1.75vw, 26px);
    --vw-size-descriptor: clamp(12px, 1vw, 15px);

    /* Surfaces */
    --vw-stage-bg: #ffffff;
    --vw-card-bg:  #ffffff;
    --vw-ink:      #0a0a0a;
    --vw-ink-soft: #5a5a5a;
  }

  /* Demo page frame removed — integrated into #intro */

  /* =============================================================
     SECTION
     ============================================================= */
  .vw-stats {
    background: var(--vw-stage-bg);
    padding: 0;
    font-family: "Inter", sans-serif;
    box-sizing: border-box;
  }

  /* =============================================================
     GRID  —  auto-fit collapses 4-up → 2-up → 1-up
     ============================================================= */
  .vw-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: clamp(10px, 1.2vw, 16px);
    max-width: 1280px;
    margin: 0 auto;
  }
  /* Tablet portrait + mobile: 2x2 grid (6+/50+ on top, 150+/1,500+ below).
     v0.22.7 — gaps tightened per Vic feedback. Was 10px @ ≤860px and
     8px @ ≤420px; the cards felt too floaty on mobile. Tighter rhythm
     now: 6px / 4px. Applies to BOTH homepage and About since they
     share intro-stats.css. */
  @media (max-width: 860px) {
    .vw-grid { grid-template-columns: repeat(2, 1fr); gap: 6px; }
  }
  @media (max-width: 420px) {
    .vw-grid { gap: 4px; }
  }

  /* =============================================================
     CARD
     ============================================================= */
  .vw-card {
    position: relative;
    background: var(--vw-card-bg);
    border-radius: 20px;
    padding: clamp(22px, 2.2vw, 34px) clamp(10px, 1.5vw, 24px);
    overflow: hidden;
    text-align: center;
    box-shadow:
      0 0 0 1px rgba(10, 10, 10, 0.04),
      0 1px 4px rgba(0, 0, 0, 0.02);
    /* LEAVE — even slower, gentler dissipation (v23) */
    transition:
      transform  1800ms cubic-bezier(0.16, 1, 0.3, 1),
      box-shadow 2200ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .vw-card:hover {
    transform: translateY(-4px);
    /* ENTER — more deliberate arrival (v23) */
    transition:
      transform  1400ms cubic-bezier(0.22, 1, 0.36, 1),
      box-shadow 1600ms cubic-bezier(0.22, 1, 0.36, 1);
  }

  /* Glow wash — position is driven by --gx / --gy from the script */
  .vw-card::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    opacity: 0.4;
    pointer-events: none;
    transition: opacity 2000ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .vw-card:hover::before {
    opacity: 0.62;
    transition: opacity 1300ms cubic-bezier(0.22, 1, 0.36, 1);
  }

  /* Per-variant wash colors */
  .vw-card.vw-coral::before  { background: radial-gradient(circle 180px at var(--gx, 50%) var(--gy, 50%), var(--vw-coral-wash),  transparent 65%); }
  .vw-card.vw-pink::before   { background: radial-gradient(circle 180px at var(--gx, 50%) var(--gy, 50%), var(--vw-pink-wash),   transparent 65%); }
  .vw-card.vw-purple::before { background: radial-gradient(circle 180px at var(--gx, 50%) var(--gy, 50%), var(--vw-purple-wash), transparent 65%); }
  .vw-card.vw-blue::before   { background: radial-gradient(circle 180px at var(--gx, 50%) var(--gy, 50%), var(--vw-blue-wash),   transparent 65%); }

  /* Per-variant hover outline + shadow */
  .vw-card.vw-coral:hover {
    box-shadow:
      inset 0 0 0 1px rgba(var(--vw-coral-rgb), 0.42),
      0 12px 28px -10px rgba(var(--vw-coral-rgb), 0.30),
      0 1px 4px rgba(0, 0, 0, 0.02);
  }
  .vw-card.vw-pink:hover {
    box-shadow:
      inset 0 0 0 1px rgba(var(--vw-pink-rgb), 0.42),
      0 12px 28px -10px rgba(var(--vw-pink-rgb), 0.30),
      0 1px 4px rgba(0, 0, 0, 0.02);
  }
  .vw-card.vw-purple:hover {
    box-shadow:
      inset 0 0 0 1px rgba(var(--vw-purple-rgb), 0.45),
      0 12px 28px -10px rgba(var(--vw-purple-rgb), 0.33),
      0 1px 4px rgba(0, 0, 0, 0.02);
  }
  .vw-card.vw-blue:hover {
    box-shadow:
      inset 0 0 0 1px rgba(var(--vw-blue-rgb), 0.48),
      0 12px 28px -10px rgba(var(--vw-blue-rgb), 0.34),
      0 1px 4px rgba(0, 0, 0, 0.02);
  }

  /* =============================================================
     CARD CONTENT
     ============================================================= */
  .vw-content {
    position: relative;
    z-index: 1;
  }

  .vw-number {
    font-family: var(--font-title);
    font-weight: 900;
    font-size: var(--vw-size-number);
    line-height: var(--vw-size-number);
    letter-spacing: -0.045em;
    font-variant-numeric: tabular-nums;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    height: var(--vw-size-number);
    margin-bottom: clamp(10px, 1vw, 16px);
  }

  .vw-card.vw-coral  .vw-number { color: var(--vw-coral); }
  .vw-card.vw-pink   .vw-number { color: var(--vw-pink); }
  .vw-card.vw-purple .vw-number { color: var(--vw-purple); }
  .vw-card.vw-blue   .vw-number { color: var(--vw-blue); }

  .vw-digit-slot {
    display: inline-block;
    height: var(--vw-size-number);
    overflow: hidden;
    line-height: var(--vw-size-number);
    vertical-align: top;
  }
  .vw-digit-strip {
    display: flex;
    flex-direction: column;
    transform: translateY(0);
    /* v0.20.10 — `filter` joins `transform` on the GPU layer hint so the
       motion-blur animation below doesn't repaint to CPU during spin. */
    will-change: transform, filter;
  }

  /* v0.20.10 — Vertical motion blur on the digit strip while spinning.
     ─────────────────────────────────────────────────────────────────
     Vic feedback: the rolling odometer should feel "in motion" during
     the transition, not static digits sliding past. The keyframe
     animates ONLY `filter` (not `transform`) so it doesn't fight the
     inline `transform: translateY(...)` that spinDigit() writes to
     .style — both run simultaneously, transform handles the roll, the
     animation handles the blur.

     Blur intensity peaks early in the curve (where the cubic-bezier
     ease-out is moving fastest) and eases off toward the settle point.
     CSS `filter: blur()` is symmetric (single radius), but during fast
     vertical movement the eye reads it as directional motion blur —
     no SVG `<feGaussianBlur stdDeviation="0 4">` complexity required.

     Animation duration matches SPIN_DURATION (1800ms) in
     intro-stats.js so the blur is in lockstep with the transform
     transition. The .is-spinning class is added at spin-start and
     removed at transitionend by spinDigit() — same listener that
     handles the silent snap-back, so it's "free" to wire. */
  /* v0.20.11 — bumped peak blur 2.8 → 6.5px per Vic feedback ("increase
     the odometer vertical motion blur"). The cubic-bezier(0.22, 1, 0.36, 1)
     ease-out moves the strip fastest in the first ~30% of the curve, so
     the blur is heaviest at 8% (peak velocity) and tapers in lockstep
     with the deceleration. Saturation drops slightly during peak so the
     "smear" reads as motion rather than a tinted glow. */
  @keyframes vw-spin-blur {
    0%   { filter: blur(0); }
    6%   { filter: blur(6.5px) saturate(0.86); }
    20%  { filter: blur(5.6px) saturate(0.88); }
    45%  { filter: blur(3.8px) saturate(0.93); }
    70%  { filter: blur(1.8px) saturate(0.97); }
    88%  { filter: blur(0.6px); }
    100% { filter: blur(0); }
  }
  .vw-digit-strip.is-spinning {
    animation: vw-spin-blur 1800ms cubic-bezier(0.22, 1, 0.36, 1);
  }
  .vw-digit-strip > span {
    display: block;
    height: var(--vw-size-number);
    line-height: var(--vw-size-number);
  }
  .vw-separator,
  .vw-suffix {
    display: inline-block;
    line-height: var(--vw-size-number);
  }

  .vw-divider {
    width: 55%;
    height: 2px;
    background: var(--vw-ink);
    margin: 0 auto 10px;
  }

  .vw-label {
    font-family: var(--font-title);
    font-weight: 700;
    font-size: var(--vw-size-label);
    letter-spacing: -0.015em;
    line-height: 1;
    color: var(--vw-ink);
    margin-bottom: 6px;
    text-transform: lowercase;
  }

  .vw-descriptor {
    font-family: var(--font-title);
    font-weight: 500;
    font-size: var(--vw-size-descriptor);
    letter-spacing: 0.005em;
    line-height: 1.4;
    color: var(--vw-ink-soft);
    text-transform: lowercase;
  }

  /* =============================================================
     REDUCED MOTION  —  honour the user's OS preference
     ============================================================= */
  @media (prefers-reduced-motion: reduce) {
    .vw-card,
    .vw-card:hover,
    .vw-card::before,
    .vw-card:hover::before,
    .vw-digit-strip {
      transition: none !important;
    }
    /* v0.20.10 — also kill the motion-blur animation under reduced-motion. */
    .vw-digit-strip.is-spinning {
      animation: none !important;
      filter: none !important;
    }
    .vw-card:hover {
      transform: none;
    }
  }

/* ── Mobile section spacing tighten-up + title scale ── */
/* (subset of prototype lines 3405-3443 relevant to intro/stats) */
/* ═══ Mobile section spacing tighten-up + title scale ═══ */
@media (max-width: 600px) {
  /* v0.32.163 — section padding normalised to the shared rhythm
     token. Was 48/20/56 for #intro and 56/20 for #jobs-cta — both
     now follow the canonical 56 × 24. */
  #intro{padding:var(--vw-section-pad-y-mobile, 56px) var(--vw-section-pad-x-mobile, 24px)}
  #jobs-cta{padding:var(--vw-section-pad-y-mobile, 56px) var(--vw-section-pad-x-mobile, 24px)}

  /* Mobile titles all match .s-title (jobs-cta) sizing for consistency */
  .intro-main-title,
  .port-title,
  .vt-clients__title,
  .vn-title-group h2 {
    font-size: clamp(2rem, 4.2vw, 3rem) !important;
    font-weight: 900 !important;
    font-family: var(--font-title) !important;
    letter-spacing: -0.04em !important;
    line-height: 1.08 !important;
  }
  /* Eyebrows: consistent small cap */
  .eyebrow,
  .port-eyebrow,
  .vt-clients__eyebrow {
    font-size: 0.68rem !important;
  }

  /* mobile more-details button — back to absolute bottom of
     .gal-right so it aligns with the bottom edge of the big hero image */
  .gal-actions{
    position:absolute !important;
    bottom:0 !important;
    left:0 !important;
    padding-left:2px !important;
    margin:0 !important;
  }
  .gal-meta{padding-bottom:46px !important}

  /* Footer mobile — top-align logo and "pages" column. The SVG's viewBox
     has whitespace above the glyphs; the negative margin-top from desktop
     already compensates. Make sure both columns start flush. */
  .ft-left-col > div { margin-top: 0 }
}


/* ──────────────────────────────────────────────────────────────
   FEATURE CARD VARIANT (v0.14.13)
   ──────────────────────────────────────────────────────────────
   The .vw-card.vw-feature variant replaces the numeric stat
   layout with an image + title/body block on a custom gradient
   background. Editors pick the gradient from the Stats admin
   page; the picker's start color (color1) drives THREE things:
   the gradient itself (passed through as --vw-feat-bg), the
   card's drop shadow tint, and the card's border tint.

   The "drop shadow + outline that sync with the gradient color"
   is implemented via CSS color-mix on the same --vw-feat-color
   variable that the editor picks. One color choice → coherent
   card. No JS required, no per-card stylesheet generation.

   Inline-style on the article element supplies these vars:
       --vw-feat-bg     : the full computed gradient string
       --vw-feat-color  : the start color (color1) for tints

   Browser support: color-mix is in all modern browsers as of
   2024 (Chrome 111+, Safari 16.2+, Firefox 113+). The fallbacks
   below kick in on older browsers — a solid border + soft
   neutral shadow — so the card never breaks. */
.vw-card.vw-feature {
  background: var(--vw-feat-bg, linear-gradient(135deg, #1a1a1a 0%, #2a1810 100%));
  /* Fallback border + shadow first (older browsers see only these) */
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.32);
  /* Modern browsers: tint border and shadow from --vw-feat-color */
  border-color: color-mix(in srgb, var(--vw-feat-color, #F27A0F) 55%, transparent);
  box-shadow:
    0 18px 48px color-mix(in srgb, var(--vw-feat-color, #F27A0F) 35%, transparent),
    0 0 0 1px color-mix(in srgb, var(--vw-feat-color, #F27A0F) 15%, transparent);
  position: relative;
  overflow: hidden;
  transition: transform .35s cubic-bezier(.2,.8,.2,1), box-shadow .35s ease;
}
.vw-card.vw-feature:hover {
  transform: translateY(-3px);
  box-shadow:
    0 24px 60px color-mix(in srgb, var(--vw-feat-color, #F27A0F) 45%, transparent),
    0 0 0 1px color-mix(in srgb, var(--vw-feat-color, #F27A0F) 25%, transparent);
}

/* Image area — sits at the top of the card, fills width, ~55% of card height.
   object-fit:cover crops to a clean rectangle regardless of the source aspect. */
.vw-card.vw-feature .vw-feat-img {
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 14px;
  margin-bottom: 14px;
  background: rgba(0, 0, 0, 0.18);
}
.vw-card.vw-feature .vw-feat-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Title + body — same .vw-content wrapper as stats cards, but
   typography swaps to the editorial display style. The numeric
   font-size variables don't apply here (no .vw-number element). */
.vw-card.vw-feature .vw-feat-title {
  font-family: 'DM Sans', system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(20px, 2.2vw, 28px);
  line-height: 1.15;
  color: #fff;
  margin: 0 0 6px;
  letter-spacing: -0.01em;
}
.vw-card.vw-feature .vw-feat-body {
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 400;
  font-size: clamp(13px, 1.1vw, 15px);
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.78);
  margin: 0;
}

/* When the feature card is rendered, the per-slot color theme rules
   (vw-coral .vw-number, etc) try to color a .vw-number element that
   doesn't exist — they're simply no-ops. No reset needed. */
