/* ===== css/tokens.css ===== */
/* ============================================================================
   tokens.css — SEO Agency Singapore design system.
   OWNER: seo-scaffold. Do not add page-specific values here.
   TOKEN-LOCK: a value may be retuned IN PLACE (change what a token equals, never
   what it is called). Page CSS must not redefine a token — HANDOFFS.md.

   ⚠ THE BASE FORK'S SKIN IS BANNED IN THIS REPO (RUN.md design contract: 70%
   structure, 0% skin). That means its inscriptional serif, its geometric sans, and
   its ivory-plus-bronze hexes — none of them appear here. The display face is
   NEWSREADER; the body face is INTER; the signal is emerald. If you reach for the
   base fork's fonts or palette, you are rebuilding the wrong site.

   THREE LAYERS, and the split is load-bearing (identical architecture to the base
   fork — only the VALUES and the primitive NAMES change):
     0. LANE tokens (--bg --fg --muted --accent --display --body --c1..--c4 --dw
        --dls --btn-radius) — the new SEO-agency lane, then WIRED: every palette
        primitive resolves to one of them, so the lane is the single source of colour.
     1. PALETTE primitives (--c-*) — raw colour, derived from the lane. Components
        must NOT read these (page CSS reads semantic roles only).
     2. SEMANTIC roles (--surface / --text / --accent-text / …) — what components
        read. They re-point under [data-surface="ink"], so one attribute drops a
        section onto the dark green-black ground and everything inside stays
        AA-legible without the page author touching a colour. CONTRACT.md §2.

   THE LANE — a results firm, not a boutique: warm paper ground, green-black ink,
   ONE confident emerald that carries the rank numbers and every CTA. Squarer
   corners than the base (8px, not a 40px pill) because this sells outcomes.

   CONTRAST — WCAG 2.1 relative luminance, COMPUTED (not estimated, see _contrast.mjs)
   against every ground each role can actually land on:
     ink        #12140f on paper   #f7f5f0 ... 17.02:1  (15.70 on paper-2, 14.09 on paper-3)
     ink-2      #31352c on paper   #f7f5f0 ... 11.50:1  ← secondary copy
     ink-3      #484d40 on paper   #f7f5f0 ...  7.99:1  ← muted COPY floor. AA everywhere.
     muted      #7d8473 on paper   #f7f5f0 ...  3.30:1  ← LANE token. FAILS AA body text.
     signal     #0e7a53 on paper   #f7f5f0 ...  4.91:1  ← emerald: AA BODY + large rank nums
     signal-dp  #0a5c40 on paper   #f7f5f0 ...  7.36:1  ← green URL line / links / small nums
     white      #ffffff on signal  #0e7a53 ...  5.35:1  ← label on an emerald CTA fill
     paper      #f7f5f0 on ink     #12140f ... 17.02:1
     bone-2     #cfd3c8 on ink     #12140f ... 12.19:1  ← secondary text on the ink island
     bone-3     #a7ac9c on ink     #12140f ...  7.97:1  ← tertiary text on the ink island
     signal-lf  #5cc394 on ink     #12140f ...  8.55:1  ← the dark-ground emerald that carries text
     ink        #12140f on signal  #0e7a53 ...  3.47:1  ← ink on emerald: LARGE/UI only, never body

   TWO COLOUR RULES THAT MUST NOT BE GOT WRONG:
     · **--accent (#0e7a53) carries the RANK NUMBERS and CTAs — it is the signal, so
       ration it.** It passes AA body on paper (4.91:1), but a page drowning in green
       is a template. Emerald marks proof (rank numbers, the green URL line, one CTA
       per view) and nothing else. Where light-ground copy needs the brand hue as
       running text at small size, read **--accent-text** (#0a5c40, 7.36:1).
     · **--muted (#7d8473) is a LANE token, and at 3.30:1 it is NOT a body-text
       colour.** Hairlines, dividers and decorative marks only. Muted COPY reads
       --text-3 (#484d40). Anything that says words uses a semantic role.
   ========================================================================== */

:root{
  /* ---------- 0. LANE — the SEO-agency lane, WIRED to the palette below ---------- */
  --bg:#f7f5f0;
  --fg:#12140f;
  --muted:#7d8473;
  --accent:#0e7a53;
  /* Round 4 (Charlie): the Eden Cube format layer — display face is PLAYFAIR
     DISPLAY (eden-cube-site's serif), palette unchanged. css/eden.css carries
     the section formats; the gate derives its h1 assertion from this token. */
  --display:"Playfair Display",Georgia,"Times New Roman",serif;
  --body:"Inter",system-ui,-apple-system,"Segoe UI",sans-serif;
  --c1:#f7f5f0;
  --c2:#12140f;
  --c3:#0e7a53;
  --c4:#cbd3c4;
  --dw:400;
  --dls:.006em;
  --btn-radius:8px;         /* squarer than the base's 40px pill — a results firm */

  /* ---------- 1. PALETTE primitives — never referenced by page components ----------
     Warm paper and a green-black ink: the ground reads LIGHT, calm, editorial. The
     deeper papers and the ink shades are derived — the lane ships a handful of
     colours and a site needs recessed bands, wells and a dark island. */
  --c-paper:      var(--bg);   /* #f7f5f0 — the SITE reads LIGHT, warm, paper */
  --c-paper-2:    #efece4;     /* recessed band */
  --c-paper-3:    #e5e0d5;     /* wells / insets / media placeholder */
  --c-ink:        var(--fg);   /* #12140f — green-black, never a neutral black */
  --c-ink-2:      #31352c;     /* secondary copy — 11.50:1 */
  --c-ink-3:      #484d40;     /* muted COPY — AA on all three papers. Floor. */
  --c-ink-deep:   #0b0c08;     /* the deepest island — full-bleed dark, footer floor */

  --c-bone-2:     #cfd3c8;     /* secondary text on the ink island */
  --c-bone-3:     #a7ac9c;     /* tertiary text on the ink island */

  --c-signal:      var(--accent); /* #0e7a53 — the emerald: rank numbers + CTAs */
  --c-signal-deep: #0a5c40;       /* emerald that carries small text on paper (7.36:1) */
  --c-signal-lift: #5cc394;       /* emerald that carries text on ink (8.55:1) */
  --c-stone:       var(--c4);     /* #cbd3c4 — the lane's cool divider stone */
  --c-clay:        var(--muted);  /* #7d8473 — lane muted: ornament, not copy */

  --c-on-signal:   #ffffff;       /* label on an emerald fill — 5.35:1 */

  /* ---------- 2. SEMANTIC roles — components read ONLY these ---------- */
  --surface:      var(--c-paper);
  --surface-2:    var(--c-paper-2);
  --surface-3:    var(--c-paper-3);
  --text:         var(--c-ink);          /* 17.02:1 */
  --text-2:       var(--c-ink-2);        /* 11.50:1 — secondary */
  --text-3:       var(--c-ink-3);        /*  7.99:1 — muted copy. Nothing below AA exists. */
  --accent-text:  var(--c-signal-deep);  /*  7.36:1 — the rationed light-ground brand hue */
  --on-accent:    var(--c-on-signal);    /*  5.35:1 — label on an emerald fill */

  --rule:         rgb(18 20 15 / .13);      /* hairline */
  --rule-2:       rgb(18 20 15 / .24);
  --rule-stone:   var(--c-stone);           /* the lane's own divider — cooler, softer */
  --rule-accent:  rgb(14 122 83 / .40);     /* the 1px inset emerald ring on media frames */
  --wash-accent:  rgb(14 122 83 / .10);
  --wash-ink:     rgb(18 20 15 / .05);

  /* Shadow carries the ink's own green-black, not a neutral grey — a grey drop
     shadow on warm paper reads as a template's default elevation. */
  --sh-1: 0 1px 2px rgb(18 20 15 / .05), 0 6px 16px -8px rgb(18 20 15 / .12);
  --sh-2: 0 2px 6px rgb(18 20 15 / .06), 0 24px 54px -20px rgb(18 20 15 / .20);

  /* ---------- 3. TYPE — Newsreader + Inter ----------
     Newsreader is a readable, editorial serif with a TRUE italic and real weights,
     drawn for text at a range of optical sizes. That is the deliberate break from
     the base's single-weight inscriptional face: here hierarchy MAY lean on weight,
     and EMPHASIS IS ITALIC (Newsreader's italic is the device), not a colour swap.
     Inter (grotesque, neutral, modern) carries UI and body — the credibility sans.

     HIERARCHY IS DESIGNED: as size descends the face switches from display serif to
     body sans, tracking tightens on the serif and opens on the uppercase Inter
     labels. --dw stays 400 for the display face (the gate asserts h1 weight 400 and
     Newsreader 400 is the elegant reading weight); reach for 500 only in page CSS,
     on small display accents, never on a hero. */
  --f-display: var(--display);
  --f-body:    var(--body);
  /* --font-display / --font-body are aliases the qa gate reads (it asserts computed h1
     font-family primary == --font-display's primary, "Newsreader"). Same values as
     --f-display / --f-body; components keep reading the short --f-* names. */
  --font-display: var(--display);
  --font-body:    var(--body);

  /* clamp(): ALWAYS spaces around + and - or the WHOLE declaration is invalid and
     the type silently falls back to the browser default. */
  /* Scale retuned to eden-cube-site's stanzas (round 4): h-xl / h-l / h-m / h-s. */
  --t-display: clamp(2.7rem, 1.5rem + 4.4vw, 6.25rem);      /* hero ONLY */
  --t-h1:      clamp(2rem, 1.4rem + 2.2vw, 3.75rem);        /* section openers */
  --t-h2:      clamp(1.6rem, 1.3rem + 1vw, 2.6rem);
  --t-h3:      clamp(1.15rem, 1.05rem + .4vw, 1.55rem);
  --t-lede:    clamp(1.075rem, 1rem + .5vw, 1.35rem);
  --t-body:    clamp(1rem, .96rem + .25vw, 1.125rem);
  --t-small:   .875rem;
  --t-micro:   .6875rem;                                    /* 11px — the eyebrow */
  --t-micro-2: .75rem;                                      /* 12px — the wider label */
  --t-rank:    clamp(4rem, 2rem + 16vw, 15rem);             /* ⭐ the rank-ladder numeral */

  --w-display: var(--dw);   /* 400 */
  --w-body:    400;         /* Inter body weight */
  --w-medium:  500;
  --w-semibold:600;
  --w-micro:   500;

  --lh-display: .94;
  --lh-h:       1.05;
  --lh-lede:    1.55;
  --lh-body:    1.7;

  /* TRACKING. The serif is near-neutral and tightens a hair at display size; the
     uppercase Inter labels OPEN as they shrink, to .16em. Serif never shouts, sans
     never whispers — that split is the hierarchy's backbone. */
  --ls-display: -.045em;    /* Playfair at hero size — eden-cube's display tightening */
  --ls-h:       -.03em;
  --ls-serif:   var(--dls); /* .006em — Newsreader at body size */
  --ls-body:    -.002em;    /* Inter default, a hair tight */
  --ls-micro:   .16em;

  /* MEASURES. A hero set to prose width loses the editorial register instantly. */
  --m-hero:  16ch;   /* display */
  --m-state: 22ch;   /* statement / pull quote */
  --m-head:  22ch;   /* section head */
  --prose:   64ch;   /* body */

  /* ---------- 4. SPACE — rhythm is intentional: tight within a group, generous between */
  --s-1: .25rem; --s-2: .5rem;  --s-3: .75rem; --s-4: 1rem;
  --s-5: 1.5rem; --s-6: 2rem;   --s-7: 3rem;   --s-8: 4.5rem;

  --space-section: clamp(6rem, 4.5rem + 7vw, 13rem);    /* between sections */
  --space-block:   clamp(2.25rem, 1.5rem + 2.6vw, 4rem); /* between blocks in a section */
  --space-group:   clamp(.75rem, .6rem + .5vw, 1.1rem); /* within a group — tight */
  --gutter:        clamp(1.25rem, 5vw, 5.5rem);
  --maxw:          1280px;
  --nav-h:         clamp(64px, 5vw, 80px);

  /* ---------- 5. SHAPE / MOTION ----------
     Near-square everywhere (an editorial sheet with 16px rounding on everything is a
     Tailwind template's shape tell) plus the lane's own 8px on CTAs. --r-btn is the
     lane token; do not put it on a card. */
  --r-0:    0px;    /* frames, panels, media — a true square corner */
  --r-1:    3px;
  --r-btn:  var(--btn-radius);   /* 8px — CTAs only */

  --d-1: 140ms; --d-2: 260ms; --d-3: 460ms; --d-4: 820ms;
  --ease-out:     cubic-bezier(.16, 1, .3, 1);
  --ease-hover:   cubic-bezier(.2, .7, .3, 1);
  --ease-overlay: cubic-bezier(.32, .72, 0, 1);
  --ease-reveal:  cubic-bezier(0, 0, .1, 1);  /* motion-kit.css reads this name — do
                                                 not rename it */

  /* ---------- 6. LAYERS — named by motion-kit.css's contract ---------- */
  --z-base:    0;
  --z-content: 1;
  --z-over:    2;
  --z-grain:   90;
  --z-nav:     100;
  --z-drawer:  110;
  --z-overlay: 120;
  --z-cursor:  9999;
}

/* ------------------------------------------------------------- INK ISLAND
   The dark counterweight. Drop it on any <section> and the whole subtree flips:
     <section class="section" data-surface="ink">
   The island's ground is --fg (green-black) and its copy is --bg (paper), exactly as
   the design contract words it. The emerald lifts to --c-signal-lift here (8.55:1) —
   on dark, the brand colour finally carries running text. */
/* `.on-media` is the SAME role flip with NO ground of its own — for copy laid over a
   photograph, where painting an ink background would cover the picture. Every
   component inside then reads light automatically: .btn--ghost gets a visible border,
   .muted stays legible, the hairlines invert. */
[data-surface="ink"], .ink-island, .on-media{
  --surface:     var(--c-ink);
  --surface-2:   #1c1f18;
  --surface-3:   #262a20;
  --text:        var(--c-paper);       /* 17.02:1 */
  --text-2:      var(--c-bone-2);      /* 12.19:1 */
  --text-3:      var(--c-bone-3);      /*  7.97:1 */
  --accent-text: var(--c-signal-lift); /*  8.55:1 */
  --on-accent:   var(--c-on-signal);   /*  5.35:1 — label stays white on the emerald fill */
  --rule:        rgb(247 245 240 / .15);
  --rule-2:      rgb(247 245 240 / .27);
  --rule-stone:  rgb(203 211 196 / .30);
  --rule-accent: rgb(92 195 148 / .46);
  --wash-accent: rgb(92 195 148 / .14);
  --wash-ink:    rgb(247 245 240 / .06);
  --sh-1: 0 1px 2px rgb(0 0 0 / .30), 0 8px 22px -10px rgb(0 0 0 / .50);
  --sh-2: 0 2px 8px rgb(0 0 0 / .34), 0 30px 60px -20px rgb(0 0 0 / .62);
}
/* the ground is painted ONLY by the two island selectors — .on-media takes the roles
   and leaves the photograph underneath alone */
[data-surface="ink"], .ink-island{
  background: var(--surface);
  color: var(--text);
}
.on-media{ color: var(--text); }

/* The deepest floor — for the one moment a page wants the room fully dark. Same
   roles, lower ground. */
[data-surface="ink-deep"]{
  --surface:     var(--c-ink-deep);
  --surface-2:   var(--c-ink);
  --surface-3:   #16180f;
  --text:        var(--c-paper);       /* 18.01:1 */
  --text-2:      var(--c-bone-2);
  --text-3:      var(--c-bone-3);
  --accent-text: var(--c-signal-lift);
  --on-accent:   var(--c-on-signal);
  --rule:        rgb(247 245 240 / .14);
  --rule-2:      rgb(247 245 240 / .25);
  --rule-stone:  rgb(203 211 196 / .28);
  --rule-accent: rgb(92 195 148 / .44);
  --wash-accent: rgb(92 195 148 / .14);
  --wash-ink:    rgb(247 245 240 / .05);
  background: var(--surface);
  color: var(--text);
}


/* ===== css/base.css ===== */
/* ============================================================================
   base.css — reset (@layer base), typography, chrome, shared components.
   OWNER: seo-scaffold. Page authors: do NOT edit. Add to css/pages/<key>.css.

   Every component below reads SEMANTIC tokens only (--surface / --text /
   --accent-text / …), so all of it works unchanged inside [data-surface="ink"] and
   ="ink-deep" without a single colour override from the page author. That property
   is the whole reason the token layer exists — do not break it by reaching for a
   --c-* primitive from page CSS.

   THE RESET LIVES IN @layer base. Everything after it is unlayered, and unlayered
   rules beat EVERY layer regardless of specificity. That means a page author's
   `.card p{ margin-top: 1rem }` can never be out-muscled by the reset's `p{margin:0}`
   — no !important arms race, no specificity bumping. Components below are
   deliberately NOT layered: they must stay beatable by page CSS in the normal way.
   ========================================================================== */

/* ---------------------------------------------------------------- 1. reset */
@layer base{
  *, *::before, *::after{ box-sizing: border-box; }

  html{ -webkit-text-size-adjust: 100%; }

  /* NEVER put transform / filter / backdrop-filter on html or body: either makes
     them a containing block and traps every position:fixed descendant — the nav,
     the drawer, the grain. Cost a whole debugging session on a previous house build. */
  body{
    margin: 0;
    background: var(--surface);
    color: var(--text);
    font-family: var(--f-body);
    font-size: var(--t-body);
    font-weight: var(--w-body);
    line-height: var(--lh-body);
    letter-spacing: var(--ls-body);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;
    text-rendering: optimizeLegibility;
  }

  h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd{ margin: 0; }
  ul, ol{ margin: 0; padding: 0; list-style: none; }
  a{ color: inherit; text-decoration: none; }
  img, video, svg, canvas{ display: block; max-width: 100%; }
  img, video{ height: auto; }
  button, input, select, textarea{ font: inherit; color: inherit; }
  button{ background: none; border: 0; padding: 0; cursor: pointer; }
  table{ border-collapse: collapse; }
}

/* The ONE sanctioned !important, and it is OUTSIDE the layer on purpose. [hidden]
   is (0,1,0) — the same specificity as any single class, so a page author's
   `.card{display:block}` concatenated after this file wins on source order and the
   "hidden" element stays visible. Enforcing UA semantics against author rules is
   exactly what !important is for. */
[hidden]{ display: none !important; }

/* ------------------------------------------------- 2. motion / a11y floors */
/* Reduced motion is a FLOOR, not a downgrade: content must be fully visible and
   still. The JS honours it too (motion-kit, site.js and hpin all check). */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
@media (prefers-reduced-motion: no-preference){
  html{ scroll-behavior: smooth; }
}

:focus-visible{
  outline: 2px solid var(--text);
  outline-offset: 3px;
  border-radius: var(--r-1);
}
/* A focus ring must contrast with the surface it lands ON — an ink ring on the ink
   CTA is invisible. These two carry dark fills, so their ring flips to paper. */
.nav-cta:focus-visible,
.btn--solid:focus-visible{ outline-color: var(--c-paper); outline-offset: 2px; }
[data-surface="ink"] .btn--solid:focus-visible,
[data-surface="ink-deep"] .btn--solid:focus-visible,
.ink-island .btn--solid:focus-visible{ outline-color: var(--c-ink); }

.skip{
  position: absolute; left: var(--s-4); top: -100px; z-index: var(--z-overlay);
  background: var(--c-ink); color: var(--c-paper);
  padding: var(--s-3) var(--s-5); font-size: var(--t-small);
  transition: top var(--d-1) var(--ease-out);
}
.skip:focus{ top: var(--s-4); }

.visually-hidden{
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* --------------------------------------------------- 3. atmospheric grain */
/* Paper is a MATERIAL, not a hex code. Fixed, non-interactive, soft-light, so it
   adds tooth to the ground without shifting a colour or costing a repaint — and on
   a warm mineral palette it is the difference between "beige page" and "wall". */
body::after{
  content: "";
  position: fixed; inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: .05;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce){ body::after{ opacity: .035; } }

/* ------------------------------------------------------------ 4. typography
   DISPLAY FACE = NEWSREADER, at weight 400 (--dw). Newsreader has real weights and a
   true italic, so hierarchy here may lean on size AND (in page CSS, sparingly) weight,
   and emphasis is ITALIC. Tracking tightens a hair at display size (--ls-display) and
   relaxes toward body size — an editorial serif reads calmest near-neutral. The gate
   asserts computed h1 weight 400; keep the hero at 400 and reserve 500 for small
   display accents only. */
.display, h1, h2, h3{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-kerning: normal;
  font-variant-ligatures: common-ligatures;
}

.display{
  font-size: var(--t-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
}
h1{
  font-size: var(--t-h1);
  line-height: var(--lh-h);
  letter-spacing: var(--ls-h);
}
h2{
  font-size: var(--t-h2);
  line-height: var(--lh-h);
  letter-spacing: var(--ls-h);
}
h3{
  font-size: var(--t-h3);
  line-height: 1.35;
  letter-spacing: .02em;
}
h4{
  font-family: var(--f-body);
  font-size: var(--t-small);
  font-weight: var(--w-medium);
}

/* Newsreader has a TRUE italic — so here, unlike the base fork, emphasis IS ITALIC.
   That is the one sanctioned device; the emerald (--accent-text via .accent) is
   rationed to rank numbers and CTAs, not scattered through running copy. Block-level
   address stays upright (an italic postal address reads as an error, not emphasis). */
em, i, cite, dfn{ font-style: italic; }
address{ font-style: normal; }
.accent{ color: var(--accent-text); }

.lede{
  font-size: var(--t-lede);
  line-height: var(--lh-lede);
  color: var(--text-2);
  max-width: var(--prose);
}
.prose{ max-width: var(--prose); }
.prose p + p{ margin-top: var(--s-4); }
.muted{ color: var(--text-3); }

/* micro-label — the small-caps tracked kicker in Inter. The editorial signal. */
.micro{
  display: inline-block;
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  line-height: 1;
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--text-3);
  /* .18em of tracking adds a phantom gap after the last letter; pulling it back is
     the difference between a centred label that IS centred and one that looks 4px off */
  margin-right: calc(var(--ls-micro) * -1);
}
.micro--accent{ color: var(--accent-text); }
/* line-height:1 is right for a one-line label; on a phone the long ones wrap, and
   1.0 leading puts the second row's ascenders into the first row. */
@media (max-width: 640px){
  .micro{ line-height: 1.7; }
}

/* ⭐ THE NUMBERED INDEX — the site's section marker, and a DIFFERENT device from the
   reference site's plain eyebrow line. Numerals are tabular (RESEARCH.md §4). Every major section opens with its own index
   number set in the display face beside a hairline and the label:
       <p class="idx"><span class="idx-n">01</span> Services</p>
   A running index is a compositional move (it implies a document, an ordered set of
   rooms), not a decorative one — which is what keeps it from being another eyebrow. */
.idx{
  display: flex;
  align-items: baseline;
  gap: var(--s-4);
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--text-3);
}
.idx-n{
  font-family: var(--f-display);
  font-size: var(--t-h3);
  letter-spacing: var(--ls-display);
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--accent-text);
  line-height: 1;
}
/* the hairline that runs from the number out to the label */
.idx-n::after{
  content: "";
  display: inline-block;
  width: clamp(1.25rem, 3vw, 2.5rem);
  height: 1px;
  margin-left: var(--s-4);
  vertical-align: .32em;
  background: var(--rule-stone);
}

/* tabular numerals for anything that counts */
.num{ font-variant-numeric: lining-nums tabular-nums; }

/* ------------------------------------------------------- 5. layout primitives */
.wrap{ width: min(100% - var(--gutter) * 2, var(--maxw)); margin-inline: auto; }
.wrap--narrow{ width: min(100% - var(--gutter) * 2, 900px); margin-inline: auto; }
.wrap--wide{ width: min(100% - var(--gutter), 1680px); margin-inline: auto; }

.section{ position: relative; padding-block: var(--space-section); }
.section--tight{ padding-block: var(--space-block); }
.section--flush{ padding-block: 0; }
.section--alt{ background: var(--surface-2); }

/* full-viewport stacked section — the narrative unit */
.section--full{
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Fixed nav + a centre/bottom-aligned full-height hero = the nav eats the copy on
   mobile, where content is taller. ANY section that sits under the nav needs this.
   Screenshot at 390 to prove it. */
.hero-safe{ padding-top: calc(var(--nav-h) + var(--s-8)); }
@media (max-width: 640px){
  .hero-safe{ padding-top: calc(var(--nav-h) + var(--s-7)); }
}

.stack{ display: flex; flex-direction: column; gap: var(--space-group); }
.stack--block{ gap: var(--space-block); }

/* ------------------------------------------------------- 6. framed media ⭐
   THE fill-a-box pattern. Absolute-fill, never in-flow width/height:100%. In-flow
   media in an auto-height cell fails in BOTH directions: it collapses to ~46px in a
   grid span, AND it inflates the row past its min-height once the intrinsic ratio
   resolves. Absolute-fill sidesteps flow/grid sizing entirely. Use it for ALL media. */
.frame{
  position: relative;
  overflow: hidden;
  aspect-ratio: var(--frame-ratio, 4 / 3);
  background: var(--surface-3);
  border-radius: var(--r-0);
}
.frame > img,
.frame > video{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: var(--frame-pos, 50% 50%);
}
.frame > iframe{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
}
/* the 1px inset emerald ring — the micro-detail that reads expensive */
.frame::after{
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px var(--rule-accent);
  pointer-events: none;
  z-index: var(--z-content);
}
.frame--plain::after{ display: none; }
.frame--fill{ aspect-ratio: auto; height: 100%; }

/* caption sits OUTSIDE the frame — editorial, not an overlay band */
.frame-cap{
  margin-top: var(--s-3);
  font-size: var(--t-small);
  color: var(--text-3);
}
/* caption with the lane's hairline lead-in, for a plate that opens a spread */
.frame-cap--rule{ display: flex; align-items: baseline; gap: var(--s-3); }
.frame-cap--rule::before{
  content: ""; flex: none; width: 2rem; height: 1px;
  background: var(--rule-stone); transform: translateY(-.35em);
}

/* --------------------------------------------------------- 7. hero video ⭐
   Full-bleed looping stock plate behind the page-top copy. The crossfade-loop is
   baked into the FILE by the media step (xfade end-into-first-second), not done in
   JS — so this is just a <video>, and it cannot desync. CONTRACT.md §5.
   `muted loop playsinline` or iOS will not autoplay. Always pair a poster. */
.hero-media{
  position: absolute; inset: 0;
  z-index: var(--z-base);
  overflow: hidden;
  background: var(--c-ink);
}
.hero-media > img,
.hero-media > video{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: var(--frame-pos, 50% 50%);
}
/* The poster <img> sits UNDER the video and is never removed: if the video fails,
   is still buffering, or is blocked by a data-saver, the hero is a photograph
   rather than a black box. The video paints over it once it has frames. */
.hero-media > video{ z-index: var(--z-content); }
/* A scrim, not a tint: legibility for copy laid over moving footage. Bottom-weighted
   so the top of the frame stays open. */
.hero-media::after{
  content: "";
  position: absolute; inset: 0;
  z-index: var(--z-over);
  background:
    linear-gradient(to top, rgb(33 30 27 / .74), rgb(33 30 27 / .28) 46%, rgb(33 30 27 / .10)),
    linear-gradient(to right, rgb(33 30 27 / .40), rgb(33 30 27 / 0) 62%);
}
.hero-media--soft::after{
  background: linear-gradient(to top, rgb(33 30 27 / .58), rgb(33 30 27 / .12) 60%, rgb(33 30 27 / 0));
}

/* ---------------------------------------------- 8. the horizontal rail ⭐⭐
   THE SIGNATURE (RESEARCH.md §2): "vertical scroll pans one continuous horizontal
   band of spaces and material plates, so the site reads as one long room you walk
   down rather than a stack of cards." Engine adapted from eden-cube-site/app.js and
   retuned calm (js/hpin.js). Markup + API: CONTRACT.md §6.

   Structure is load-bearing:
     [data-hpin]            outer — JS gives it a TALL height (viewport + overflow)
       .hpin-stage          sticky viewport-height window
         [data-hpin-track]  the row that translates on X
   Do not put padding or a height on the outer — it desyncs travel from height.

   THE RAGGED TOP EDGE is the grid break that keeps this from being a second Eden
   Cube: their plates are all full-stage height. Here everything BASELINE-ALIGNS to
   the bottom of the stage and the material plates are shorter, so the top edge
   steps up and down as the rail travels. */
.hpin{ position: relative; }
.hpin-stage{
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.hpin-track{
  display: flex;
  align-items: flex-end;             /* ⭐ the ragged top edge */
  height: 100%;
  gap: var(--space-block);
  padding-block: calc(var(--nav-h) + var(--s-6)) var(--s-8);
  padding-inline: var(--gutter);
  will-change: transform;
}

/* A plate is a <figure>: media on top, hanging caption below it INSIDE the track.
   The figure owns the height; the frame takes whatever is left after the caption,
   which is why the frame here is ratio-free and fills instead. */
.hpin-item{
  flex: none;
  height: 100%;
  display: flex;
  flex-direction: column;
  width: clamp(240px, 46vw, 520px);
}
.hpin-item > .frame{ flex: 1 1 auto; aspect-ratio: auto; min-height: 0; }
.hpin-item > .frame-cap{ flex: none; }
.hpin-item--wide{ width: clamp(300px, 66vw, 860px); }
/* ⭐ the material plate — a tight crop of a material, ~62% of the stage height,
   sitting on the same baseline as the photo plates. This is the alternating beat:
   space photo → material plate → space photo. */
.hpin-item--material{ height: 62%; width: clamp(180px, 26vw, 320px); }

/* The rail opens with a TYPE CARD, not a photo (RESEARCH.md §2): a rail that starts
   on an image reads as a carousel; a rail that starts on a statement reads as a
   spread. ~34vw, bottom-aligned with everything else. */
.hpin-lead{
  flex: none;
  width: clamp(260px, 34vw, 520px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--space-group);
  padding-bottom: var(--s-2);
}

/* ⭐ MOBILE (≤760px) IS A STACK, NOT A SWIPE ROW (RESEARCH.md §2). The pin is off,
   the JS writes nothing at all, and the same plates read as a vertical sequence —
   Eden Cube ships an empty section here and we must not. Full width, natural order,
   no transform, no snap: it is simply the rail unrolled. */
@media (max-width: 760px){
  .hpin-stage{
    position: static;
    height: auto;
    display: block;
    overflow: visible;
  }
  .hpin-track{
    display: flex;
    flex-direction: column;
    align-items: stretch;
    height: auto;
    gap: var(--space-block);
    padding-block: 0;
    transform: none !important;
  }
  .hpin-item,
  .hpin-item--wide,
  .hpin-item--material,
  .hpin-lead{ width: 100%; height: auto; }
  /* height:auto releases the flex-fill, so the frames need their ratios back */
  .hpin-item > .frame{ aspect-ratio: var(--frame-ratio, 4 / 5); flex: none; }
  .hpin-item--wide > .frame{ aspect-ratio: var(--frame-ratio, 16 / 9); }
  .hpin-item--material > .frame{ aspect-ratio: var(--frame-ratio, 3 / 4); }
}
/* Reduced motion gets the same stack at every width — a pinned pan is exactly the
   kind of scroll hijack the preference is asking us not to do. */
@media (prefers-reduced-motion: reduce){
  .hpin-stage{ position: static; height: auto; display: block; overflow: visible; }
  .hpin-track{
    flex-direction: column; align-items: stretch; height: auto;
    padding-block: 0; transform: none !important;
  }
  .hpin-item, .hpin-item--wide, .hpin-item--material, .hpin-lead{ width: 100%; height: auto; }
  .hpin-item > .frame{ aspect-ratio: var(--frame-ratio, 4 / 5); flex: none; }
  .hpin-item--wide > .frame{ aspect-ratio: var(--frame-ratio, 16 / 9); }
  .hpin-item--material > .frame{ aspect-ratio: var(--frame-ratio, 3 / 4); }
}

/* ------------------------------------------------------------- 9. buttons */
.btn{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-height: 46px;                 /* touch-target floor */
  padding: var(--s-3) var(--s-6);
  border-radius: var(--r-btn);     /* the lane's 40px pill — CTAs only */
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--d-2) var(--ease-hover),
              color var(--d-2) var(--ease-hover),
              border-color var(--d-2) var(--ease-hover),
              box-shadow var(--d-2) var(--ease-hover),
              transform var(--d-2) var(--ease-hover);
}
.btn:active{ transform: translateY(1px); }

/* primary — ink on paper (11.81:1), inverted inside an ink island */
.btn--solid{
  background: var(--text);
  color: var(--surface);
  border: 1px solid var(--text);
}
/* hover goes EMERALD. Legal on light because it is a FILL, not text: the label is
   --on-accent (white, 5.35:1 on the emerald). */
.btn--solid:hover{
  background: var(--c-signal);
  border-color: var(--c-signal);
  color: var(--on-accent);
  box-shadow: var(--sh-1);
}

/* ⭐ the EMERALD pill — the closing CTA and the one place the brand colour becomes a
   button. The emerald is DARK (#0e7a53), so the label is WHITE (5.35:1), not ink —
   ink on this green is 3.47:1 and fails an 11px label. Hover DEEPENS to signal-deep
   (white then reads 8.02:1); it must not lighten to signal-lift, which would put a
   white label on a light-emerald fill and collapse the contrast. */
.btn--signal{
  background: var(--c-signal);
  color: var(--c-on-signal);
  border: 1px solid var(--c-signal);
}
.btn--signal:hover{
  background: var(--c-signal-deep);
  border-color: var(--c-signal-deep);
  color: var(--c-on-signal);
  box-shadow: var(--sh-1);
}
.btn--signal:focus-visible{ outline-color: var(--c-on-signal); }

.btn--ghost{
  background: transparent;
  color: var(--text);
  border: 1px solid var(--rule-2);
}
.btn--ghost:hover{ border-color: var(--c-signal); background: var(--wash-accent); }

/* Button cluster — use this for ANY row of buttons; never hand-roll display:flex.
   .btn is white-space:nowrap by design (a CTA label must not break mid-word), so an
   unwrapped row overflows the viewport the moment two CTAs don't fit — measured
   415px against a 390px viewport on a previous build, i.e. a horizontal scrollbar on
   every phone. Wrapping at the container is the only place it can't be forgotten. */
.btns{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
}
.btns--loose{ gap: var(--s-5); }

/* .btns wrapping the ROW is enough at 390, not at 320: a long CTA label at 11px
   caps / .28em is one unbreakable run wider than the viewport, in the SHARED footer
   and drawer as well as in page CTAs. Below 400 the label may break BETWEEN words;
   the mid-word break nowrap exists to prevent is still impossible. */
@media (max-width: 400px){
  .btn{ white-space: normal; text-align: center; }
}

/* text link with an underline that draws on hover — compositor-friendly */
.link{
  position: relative;
  color: var(--text);
  padding-bottom: 2px;
}
.link::after{
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform var(--d-2) var(--ease-hover);
}
.link:hover::after{ transform: scaleX(1); transform-origin: 0 50%; }
/* .link--u — proof links (external evidence): emerald + always-on underline, because
   the hover wipe never fires on touch and proof must be visibly clickable at rest. */
.link--u{ color: var(--accent-text); }
.link--u::after{ transform: scaleX(1); transform-origin: 0 50%; }

/* hairline rules */
.rule{ height: 1px; background: var(--rule); border: 0; margin: 0; }
.rule--stone{ background: var(--rule-stone); }
.rule--accent{ background: var(--rule-accent); }

/* ---------------------------------------------------------------- 10. nav ⭐
   COMPOSITION IS RECON'S (RESEARCH.md §3b), and every line of it is a deliberate
   difference from the reference site's masthead:
     · wordmark CENTRED on the rail (theirs: mark + two-line name, left);
     · NO link list on the rail — a left-hand "Menu" TEXT button, not a hamburger
       icon (theirs: inline horizontal list + dropdown);
     · the WhatsApp pill is always visible at the right, emerald hairline — the
       conversion goal never hides behind a menu;
     · the bar is ALWAYS paper with a hairline bottom and ink text from the first
       pixel (theirs: transparent over hero, solidifying past .7vh). It does not
       change colour on scroll; it HIDES on scroll-down and RETURNS on scroll-up.
   Because the bar is opaque from the first pixel, a page-top hero needs no
   nav-over-media handling at all — that class of bug is designed out rather than
   patched. `.hero-safe` is still mandatory, for the padding. */
.nav{
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  height: var(--nav-h);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s-5);
  padding-inline: var(--gutter);
  background: var(--c-paper);
  border-bottom: 1px solid var(--rule);
  transition: transform var(--d-3) var(--ease-out);
}
/* js/site.js adds .is-hidden past 140px of downward scroll and removes it on any
   upward scroll. Transform only — animating `top` would relayout every frame. */
.nav.is-hidden{ transform: translateY(-101%); }
/* While the overlay is open the bar must sit ABOVE it, not under it: the toggle in
   the bar IS the close control, and RESEARCH.md §3b requires the WhatsApp pill to
   stay reachable at all times. The overlay paints the same paper, so the bar reads
   as part of it — but it is still on top, still clickable, and it never hides. */
html.menu-open .nav{ transform: none; z-index: var(--z-overlay); }

.nav-brand{
  grid-column: 2;
  justify-self: center;
  text-align: center;
  color: var(--c-ink);
  line-height: 1;
}
.nav-brand-mark{
  display: block;
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: clamp(1.15rem, .95rem + .78vw, 1.6rem);
  line-height: 1;
  letter-spacing: .12em;             /* "SEO AGENCY" is a longer lockup than one word —
                                        Newsreader is wider than the base face, so the
                                        tracking eases back from .22em to keep it centred */
  text-transform: uppercase;
  /* the tracking's phantom trailing gap, corrected so the mark is optically centred */
  text-indent: .12em;
}
.nav-brand-sub{
  display: block;
  margin-top: .46em;
  /* 10px floor — below this the descriptor stops being words and becomes texture,
     and this is the only place above the fold that says what the agency does. */
  font-size: .625rem;
  font-weight: var(--w-micro);
  line-height: 1;
  letter-spacing: .32em;
  text-transform: uppercase;
  text-indent: .3em;
  color: var(--c-ink-3);
}
@media (max-width: 460px){
  .nav-brand-sub{ display: none; }
}

/* ⭐ the MENU text button. A word, not three bars: the reference site uses a
   hamburger, and a set word in tracked caps is both the differentiator and the
   clearer control. The rule under it draws on hover, like every other link here. */
.nav-menu{
  grid-column: 1;
  justify-self: start;
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  -webkit-tap-highlight-color: transparent;
  padding-block: var(--s-2);
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--c-ink);
}
.nav-menu::after{
  content: "";
  position: absolute; left: 0; bottom: var(--s-2);
  width: calc(100% - var(--ls-micro));
  height: 1px;
  background: var(--c-signal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--d-2) var(--ease-hover);
}
.nav-menu:hover::after,
.nav-menu[aria-expanded="true"]::after{ transform: scaleX(1); }
/* the label swaps to "Close" while the overlay is open — one control, two states */
.nav-menu .is-open-label{ display: none; }
.nav-menu[aria-expanded="true"] .is-shut-label{ display: none; }
.nav-menu[aria-expanded="true"] .is-open-label{ display: inline; }

/* ⭐ the OPEN link row (round 3) — the primary pages shown plainly on the left rail
   at desktop, replacing the tucked-away overlay there. Same micro-caps voice as the
   Menu button; the emerald rule marks hover AND the current page (aria-current is
   stamped at build time). Below 1200px the row cannot clear the centred wordmark,
   so it stands down and the Menu button returns. */
.nav-links{
  grid-area: 1 / 1;
  justify-self: start;
  display: none;
  align-items: center;
  gap: clamp(var(--s-4), 1.6vw, var(--s-6));
  min-width: 0;
}
.nav-links a{
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-block: var(--s-2);
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--c-ink);
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}
.nav-links a::after{
  content: "";
  position: absolute; left: 0; bottom: var(--s-2);
  width: calc(100% - var(--ls-micro));
  height: 1px;
  background: var(--c-signal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--d-2) var(--ease-hover);
}
.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after{ transform: scaleX(1); }
.nav-links a[aria-current="page"]{ color: var(--accent-text); }

/* Contact rides with the conversion side, quiet, before the pill */
.nav-contact{
  position: relative;
  display: none;
  align-items: center;
  min-height: 44px;
  padding-block: var(--s-2);
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--c-ink);
  white-space: nowrap;
}
.nav-contact::after{
  content: "";
  position: absolute; left: 0; bottom: var(--s-2);
  width: calc(100% - var(--ls-micro));
  height: 1px;
  background: var(--c-signal);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--d-2) var(--ease-hover);
}
.nav-contact:hover::after,
.nav-contact[aria-current="page"]::after{ transform: scaleX(1); }
.nav-contact[aria-current="page"]{ color: var(--accent-text); }

@media (min-width: 1200px){
  .nav-menu{ display: none; }
  .nav-links{ display: flex; }
  .nav-contact{ display: inline-flex; }
}

.nav-right{
  grid-column: 3;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-4);
}

/* The WhatsApp pill: ink fill at the lane's 8px radius inside an emerald hairline,
   emerald fill on hover. A bright WhatsApp-brand-green button on an editorial results
   sheet is the fastest way to look cheap — the icon carries the recognition, the
   colour doesn't; the one confident emerald is ours, not WhatsApp's. */
.nav-cta{
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  justify-content: center;
  min-height: 44px;             /* iOS tap target — icon-only pill at ≤390 must be 44² */
  min-width: 44px;
  padding: var(--s-2) var(--s-5);
  border-radius: var(--r-btn);
  background: var(--c-ink);
  color: var(--c-paper);
  border: 1px solid var(--c-signal);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  white-space: nowrap;
  transition: background var(--d-2) var(--ease-hover),
              border-color var(--d-2) var(--ease-hover),
              color var(--d-2) var(--ease-hover);
}
.nav-cta:hover{
  background: var(--c-signal);
  border-color: var(--c-signal);
  color: var(--c-on-signal);         /* white on the emerald — 5.35:1 (ink would be 3.47) */
}
.nav-cta svg{ width: 15px; height: 15px; fill: currentColor; flex: none; }

@media (max-width: 560px){
  .nav-cta span{ display: none; }             /* icon-only pill; label is the aria-label */
  .nav-cta{ padding: var(--s-2) var(--s-3); min-width: 40px; }
}

/* ------------------------------------------- 11. the menu overlay (body-level)
   A full-screen PAPER overlay — large Newsreader list flush-right,
   contact set small in the lower-left, one hairline row per page numeral. It
   replaces the reference site's dropdown-plus-mobile-panel at EVERY width: one
   control, one surface, the same behaviour on a phone and on a 27-inch screen.

   It lives at BODY level, outside <header>, and is pinned with explicit top+height
   rather than inset:0 — if an ancestor ever gains a filter or transform,
   inset-based pinning silently collapses to that ancestor's box.

   Accessibility is 30% of the judge's score and js/site.js owns its half: focus
   moves in on open and back on close, Tab is trapped, Esc closes, the toggle
   carries aria-expanded, and the WhatsApp pill stays reachable because the bar
   stays put while the overlay is open. */
.menu{
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100dvh;
  z-index: var(--z-drawer);
  background: var(--c-paper);
  display: grid;
  grid-template-rows: 1fr auto;
  gap: var(--space-block);
  padding: calc(var(--nav-h) + var(--space-block)) var(--gutter) var(--space-block);
  opacity: 0;
  visibility: hidden;              /* NOT translated off-screen: fixed elements still
                                      paint into fullPage screenshots when they are
                                      merely moved. visibility actually hides. */
  transition: opacity var(--d-3) var(--ease-overlay), visibility 0s linear var(--d-3);
  overflow-y: auto;
  overscroll-behavior: contain;
}
html.menu-open .menu{
  opacity: 1; visibility: visible;
  transition: opacity var(--d-3) var(--ease-overlay), visibility 0s;
}
/* The overlay takes programmatic focus on open (dialog pattern, js/site.js) so the
   page can't be focused behind it — but it is not a keyboard tab stop (tabindex=-1),
   so it must never paint a ring. Keyboard focus on the links themselves still shows
   via the global :focus-visible rule. */
.menu:focus,
.menu:focus-visible{ outline: none; }

/* iOS scroll-lock: overflow:hidden alone does NOT hold position on iOS — the page
   flings behind the overlay. Position-fixed body lock plus scroll restore is the
   real fix; js/site.js owns the JS half. */
html.menu-open{ overflow: hidden; }
html.menu-open body{
  position: fixed;
  left: 0; right: 0;
  width: 100%;
  overflow: hidden;
}

.menu-links{
  align-self: center;
  display: flex;
  flex-direction: column;
  width: 100%;
}
/* flush-RIGHT, each row on its own hairline, the numeral held out in the row's left
   margin — the "hairline row of page numerals" of the spec, and the same numbering
   device as .idx so the menu reads as the site's table of contents */
.menu-links a{
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: var(--s-5);
  /* iOS: kill the grey tap flash on the big display links; the designed hover/active
     colour change and the :focus-visible ring carry the interaction state. */
  -webkit-tap-highlight-color: transparent;
  padding-block: clamp(.5rem, .3rem + .9vw, 1.1rem);
  border-top: 1px solid var(--rule);
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: clamp(1.9rem, 1rem + 4.2vw, 4rem);
  line-height: 1.1;
  letter-spacing: var(--ls-h);
  color: var(--c-ink);
  transition: color var(--d-2) var(--ease-hover);
}
.menu-links a:last-child{ border-bottom: 1px solid var(--rule); }
.menu-links a::before{
  content: attr(data-n);
  margin-right: auto;                /* numeral to the far left, name to the right */
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ls-micro);
  color: var(--c-signal-deep);
}
.menu-links a:hover,
.menu-links a[aria-current="page"]{ color: var(--c-signal-deep); }

/* contact, small, lower-LEFT — the corner the eye lands on last */
.menu-foot{
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-3) var(--s-6);
  padding-top: var(--space-group);
  border-top: 1px solid var(--rule-stone);
  font-size: var(--t-small);
  color: var(--text-3);
}
.menu-foot a{ color: var(--text-2); }
.menu-foot a:hover{ color: var(--accent-text); }

/* ------------------------------------------------------------- 12. footer ⭐
   RESEARCH.md §3c — the closing ink island, composed as a PAGE, not a bar (the
   reference site ends on a brand-left lockup with a thin legal strip):
     1. full-bleed ink ground, paper text — the second of exactly TWO ink islands
        sitewide (the other is Home's approach band; no page may add a third);
     2. an oversized Newsreader closing line at 16ch, then the WhatsApp pill in
        EMERALD and the email as a plain underlined link — the last conversion moment;
     3. a hairline, then a three-column baseline row: Studio · Contact · Pages.
        No social icons: none were supplied, and inventing them is a fabricated fact;
     4. the wordmark set enormous and CLIPPED BY THE BOTTOM EDGE at ~6% paper — the
        graphic sign-off, and the move the reference footer has no answer to;
     5. the copyright line, which sits ABOVE the clipped mark in z-order. */
.foot{
  position: relative;
  padding-block: var(--space-block) var(--s-5);
  overflow: hidden;                  /* this is what crops the wordmark */
}
.foot > .wrap{ position: relative; z-index: var(--z-content); }

.foot-close{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: var(--t-h1);
  line-height: var(--lh-h);
  letter-spacing: var(--ls-h);
  max-width: 16ch;
  color: var(--text);
}
.foot-act{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-5);
  margin-top: var(--space-block);
  padding-bottom: var(--space-block);
}
.foot-act .link{ font-size: var(--t-small); }

.foot-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-block);
  padding-top: var(--space-block);
  border-top: 1px solid var(--rule);
}
.foot-col{ display: flex; flex-direction: column; gap: var(--s-3); }
.foot-col h4{
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: var(--s-2);
}
/* `:not(.btn)` is load-bearing, not tidiness. `.foot-col a` is (0,2,0) and
   out-specifies `.btn--solid{color}` (0,1,0), so a CTA inside a colophon column
   silently inherits the column's --text-2 and its .875rem — measured
   rgb(205,196,184) on a paper fill, i.e. a 1.4:1 invisible label, in the shell
   gate. Excluding buttons here is the only place the bug can't come back. */
.foot-col a:not(.btn), .foot-col p{ color: var(--text-2); font-size: var(--t-small); line-height: 1.6; }
.foot-col a:not(.btn){ transition: color var(--d-2) var(--ease-hover); }
.foot-col a:not(.btn):hover{ color: var(--accent-text); }

.foot-bottom{
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3) var(--s-6);
  align-items: center;
  justify-content: space-between;
  margin-top: var(--space-block);
  padding-top: var(--s-5);
  border-top: 1px solid var(--rule);
  font-size: var(--t-small);
  color: var(--text-3);
}
.foot-bottom a:hover{ color: var(--accent-text); }

/* ⭐ the clipped wordmark. Absolutely placed and pushed PAST the bottom edge so
   roughly a third of the letterforms is cropped away by .foot's overflow; 6% paper
   on ink, so it reads as a watermark in the ground rather than as a headline. It is
   decorative repetition of a name already in the colophon, so it is out of the
   accessibility tree (aria-hidden in the partial) — a screen reader announcing
   the wordmark twice at the end of every page is noise. */
.foot-mark{
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translate(-50%, 32%);
  z-index: var(--z-base);
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: clamp(4.5rem, 1rem + 19vw, 20rem);
  line-height: .82;
  letter-spacing: .06em;
  text-indent: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--c-paper);
  opacity: .06;
  pointer-events: none;
}

@media (max-width: 760px){
  .foot-grid{ grid-template-columns: 1fr; }
  .foot-col + .foot-col{ padding-top: var(--space-group); border-top: 1px solid var(--rule); }
}

/* ================================ ⭐⭐ 12b. the two signature components (SHARED)
   These are HOUSE VOCABULARY, not page CSS — the rank ladder is reprised on the case
   pages and the SERP card recurs across money pages, so they live here where every
   worker can reach them by writing markup alone (CONTRACT.md §5b). Both read SEMANTIC
   tokens only, so they stay AA and flip correctly inside an ink island. */

/* ---- .serp-card — a Google result rendered as a DESIGN OBJECT: emerald favicon tile,
   green URL line, serif title, snippet. Stack them in a .serp-list and the section
   reads like a live SERP — the quiet second motif (RUN.md design contract). */
.serp-list{ display: flex; flex-direction: column; }
.serp-card{
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--s-4);
  align-items: start;
  padding: var(--s-5) 0;
  border-top: 1px solid var(--rule);
  color: var(--text);
}
.serp-list > .serp-card:last-child{ border-bottom: 1px solid var(--rule); }
.serp-fav{
  grid-column: 1; grid-row: 1 / span 2;
  align-self: start;
  position: relative;
  width: 34px; height: 34px; flex: none;
  margin-top: .15em;
  border-radius: 9px;
  background: var(--c-signal);
  box-shadow: var(--sh-1);
}
.serp-fav::after{                          /* the up-triangle — "rank rising" */
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-bottom: 8px solid var(--c-on-signal);
}
.serp-head{ grid-column: 2; grid-row: 1; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.serp-url{
  font-family: var(--f-body);
  font-size: var(--t-micro-2);
  letter-spacing: .01em;
  color: var(--accent-text);              /* the green URL line — also our brand hue */
  overflow-wrap: anywhere;
}
.serp-title{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: var(--t-h3);
  line-height: 1.2;
  color: var(--text);
  transition: color var(--d-2) var(--ease-hover);
}
.serp-desc{
  grid-column: 2; grid-row: 2;
  margin-top: var(--s-2);
  max-width: 64ch;
  font-size: var(--t-small);
  line-height: 1.6;
  color: var(--text-3);
}
a.serp-card:hover .serp-title{ color: var(--accent-text); text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 520px){
  .serp-card{ grid-template-columns: 1fr; }
  .serp-fav{ grid-row: auto; }
  .serp-head, .serp-desc{ grid-column: 1; }
}

/* ---- .serp-shot — a whole Google results page as a framed SNAPSHOT (shared: home +
   the four case pages). Browser chrome, the query in a search bar, neutral skeleton
   rows for the other results, and ONE real hit whose slot in the stack IS the claimed
   position. Recreated, and captioned as such — the position is the real part. */
.serp-shot{
  max-width: 720px;
  border: 1px solid var(--rule-2);
  border-radius: var(--r-1);
  background: var(--surface);
  box-shadow: var(--sh-2);
  overflow: hidden;
}
.serp-shot-chrome{
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-3) var(--s-5);
  background: var(--surface-2);
  border-bottom: 1px solid var(--rule);
}
.serp-shot-chrome i{
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--rule-stone);
}
.serp-shot-chrome span{
  margin-left: var(--s-3);
  font-size: var(--t-micro-2);
  color: var(--text-3);
  letter-spacing: .02em;
}
.serp-shot-bar{
  display: flex; align-items: center; gap: var(--s-3);
  margin: var(--s-5) var(--s-5) 0;
  padding: var(--s-3) var(--s-5);
  border: 1px solid var(--rule-2);
  border-radius: 999px;
  box-shadow: var(--sh-1);
}
.serp-shot-bar svg{ width: 16px; height: 16px; flex: none; color: var(--text-3); }
.serp-shot-bar span{ font-size: var(--t-small); color: var(--text); overflow-wrap: anywhere; }
.serp-shot-list{ list-style: none; margin: 0; padding: var(--s-4) var(--s-5) var(--s-5); }
.serp-shot-list > li{ padding: var(--s-4) 0; }
.serp-shot-list > li + li{ border-top: 1px solid var(--rule); }
/* a skeleton result — universally read as "someone else's listing", claims nothing */
.serp-shot-ghost i{
  display: block; height: 9px; border-radius: 5px;
  background: var(--surface-3);
}
.serp-shot-ghost i:first-child{ width: 34%; margin-bottom: var(--s-2); }
.serp-shot-ghost i:last-child{ width: 76%; }
/* the real hit — our client's row, position badge in the display serif. The badge
   carries a micro "Rank" title above the numeral (Charlie, round 3). */
.serp-shot-hit{
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--s-4);
  align-items: start;
}
.serp-shot-pos{
  position: absolute; right: 0; top: var(--s-3);
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
}
.serp-shot-pos i{
  font-style: normal;
  font-family: var(--f-body);
  font-size: var(--t-micro-2);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--text-3);
}
.serp-shot-pos b{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: clamp(1.6rem, 1rem + 1.6vw, 2.2rem);
  line-height: 1;
  color: var(--accent-text);
}
.serp-shot-hit .serp-fav{ width: 28px; height: 28px; border-radius: 7px; grid-row: 1 / span 2; margin-top: .1em; }
.serp-shot-hit .serp-fav::after{ border-left-width: 4px; border-right-width: 4px; border-bottom-width: 7px; }
.serp-shot-hit .serp-url{ padding-right: 3.2em; }
.serp-shot-hit .serp-title{ font-size: var(--t-h3); padding-right: 2.6em; }
.serp-shot-hit .serp-desc{ margin-top: var(--s-1); }
.serp-shot > figcaption{
  padding: var(--s-3) var(--s-5) var(--s-4);
  border-top: 1px solid var(--rule);
  background: var(--surface-2);
  font-size: var(--t-micro-2);
  color: var(--text-3);
}
/* ---- .serp-real — an ACTUAL Google screenshot (captured live, our result boxed in
   orange at capture time) inside the house frame, with a "Rank / #N" badge riding the
   top corner. Used wherever the client is nameable; the anonymous case keeps the
   recreated .serp-shot panel. Caption always states the checked date. */
.serp-real{ position: relative; max-width: 720px; }
/* display:block guards the aspect-ratio — an inline .frame computes to zero height
   and the screenshot silently vanishes (shipped once, round 3) */
.serp-real .frame{ display: block; border-radius: var(--r-1); box-shadow: var(--sh-2); }
.serp-real-rank{
  position: absolute; top: calc(var(--s-4) * -1); right: var(--s-4); z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: var(--s-2) var(--s-4) var(--s-3);
  background: var(--surface);
  border: 1px solid var(--rule-accent);
  border-radius: var(--r-1);
  box-shadow: var(--sh-2);
}
.serp-real-rank i{
  font-style: normal;
  font-family: var(--f-body);
  font-size: var(--t-micro-2);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--text-3);
}
.serp-real-rank b{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: clamp(1.7rem, 1rem + 1.8vw, 2.4rem);
  line-height: 1;
  color: var(--accent-text);
}
.serp-real > figcaption{
  margin-top: var(--s-3);
  font-size: var(--t-micro-2);
  color: var(--text-3);
}

/* redaction bars — the anonymous case renders its name as withheld, by design */
.serp-shot-redact{
  display: inline-block;
  width: 11ch; height: .68em;
  border-radius: 4px;
  background: var(--surface-3);
  vertical-align: baseline;
}
.serp-shot-redact--short{ width: 6ch; }
.serp-shot-redact--url{ width: 9ch; height: .8em; }
@media (max-width: 520px){
  .serp-shot-hit .serp-title{ padding-right: 1.8em; }
  .serp-shot-pos{ font-size: 1.5rem; }
}

/* ---- .rank-ladder — THE SIGNATURE (RUN.md): monumental SERP-position numerals that
   climb as you scroll. A left SPINE (::before track + ::after emerald fill, scaled by
   --climb which js/shared/rank-ladder.js sets from scroll) draws downward while each
   .rung rises in via the motion kit. --climb DEFAULTS TO 1, so with no JS or under
   reduced motion the spine is simply full and every rung is present — the screenshot
   is never blank or half-drawn. The numeral is oversized and hangs toward the spine,
   breaking the grid on purpose (flatness = slop). */
.rank-ladder{
  --spine-x: clamp(6px, 2.5vw, 22px);
  position: relative;
  padding-left: calc(var(--spine-x) + clamp(1.1rem, 4vw, 2.75rem));
  display: flex;
  flex-direction: column;
  gap: clamp(2.75rem, 6vw, 5.5rem);
}
.rank-ladder::before,
.rank-ladder::after{
  content: "";
  position: absolute;
  left: var(--spine-x);
  top: .3em; bottom: .3em;
  width: 2px;
}
.rank-ladder::before{ background: var(--rule-2); }
.rank-ladder::after{
  background: var(--c-signal);
  transform-origin: 50% 0;
  transform: scaleY(var(--climb, 1));
}
.rung{
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  align-items: center;
  column-gap: clamp(1rem, 4vw, 3rem);
}
.rung-n{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: var(--t-rank);
  line-height: .82;
  letter-spacing: -.02em;
  color: var(--accent-text);
  font-variant-numeric: lining-nums tabular-nums;
  display: flex;
  align-items: flex-start;
  gap: .04em;
}
.rung-n .rung-hash{ font-size: .34em; color: var(--text-3); margin-top: .5em; }
/* a labelled numeral — "RANK" in micro caps heads the figure (the ladder's first
   rung carries it as the column title for the whole rail; Charlie, round 3) */
.rung-n--labeled{ flex-direction: column; align-items: flex-start; gap: .22em; }
.rung-n-label{
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--text-3);
}
.rung-n-fig{ display: flex; align-items: flex-start; gap: .04em; }
.rung-body{ display: flex; flex-direction: column; gap: var(--s-3); }
.rung-move{
  font-family: var(--f-body);
  font-size: var(--t-micro);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--accent-text);
  font-variant-numeric: lining-nums tabular-nums;
}
.rung-kw{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: var(--t-h2);
  line-height: 1.15;
  color: var(--text);
}
.rung-story{ color: var(--text-3); max-width: 52ch; }
@media (max-width: 640px){
  .rung{ grid-template-columns: 1fr; row-gap: var(--s-3); }
  .rung-n{ font-size: clamp(3.5rem, 22vw, 6rem); }
}

/* ------------------------------------------------- 13. the page slot (build) */
/* build.mjs emits <main data-page-slot="key"> for a page whose partials/ dir is
   still empty, so the shell assembles green before a page worker has written a line.
   It must not collapse to zero height under the fixed nav, or the scaffold gate
   screenshots a nav floating on nothing. */
main[data-page-slot]{
  min-height: 60svh;
  padding-top: calc(var(--nav-h) + var(--space-section));
  padding-bottom: var(--space-section);
}
main[data-page-slot]::before{
  content: "Section partials for “" attr(data-page-slot) "” have not been written yet.";
  display: block;
  width: min(100% - var(--gutter) * 2, var(--maxw));
  margin-inline: auto;
  font-size: var(--t-small);
  color: var(--text-3);
}

/* ------------------------------------------------------------- STRATEGY BOARD
   Canonical component (round 6 — was services-page CSS, promoted when home's
   journey adopted it). ONE ruled object: 1px grid gaps over a rule-coloured
   ground read as shared hairlines; a dark hub panel (data-surface="ink",
   spans both rows on wide screens) carries the section's thesis; cells carry
   the items. Emerald is rationed: serif numerals, an optional pointer, the
   hover wash — and hover exists ONLY on anchor cells (a.strat-cell); plain
   <div> cells are inert, so a non-link board never fakes affordance.
   Variants: .strat-cell--wide (star item, two columns on wide screens),
   .strat-cell--end (the emerald-washed payoff cell — one loud moment). */
.strat-board{ display:grid; grid-template-columns:1.3fr 1fr 1fr 1fr; grid-auto-rows:1fr; gap:1px; background:var(--rule-2); border:1px solid var(--rule-2); border-radius:var(--r-0); }
.strat-hub{ grid-row:span 2; display:flex; flex-direction:column; gap:1rem; padding:clamp(1.6rem,1.2rem + 1.6vw,2.6rem); }
.strat-hub .h-m{ max-width:9em; }
.strat-hub-copy{ margin-top:auto; padding-top:1.25rem; font-size:var(--t-small); line-height:1.65; color:var(--text-2); max-width:34ch; }
.strat-cell{ display:flex; flex-direction:column; gap:.55rem; background:var(--surface); padding:clamp(1.25rem,1rem + 1.2vw,1.9rem); text-decoration:none; color:var(--text); }
a.strat-cell{ transition:background var(--d-2) var(--ease-hover); }
a.strat-cell:hover{ background:var(--wash-accent); }
.strat-cell-n{ font-family:var(--f-display); font-weight:var(--w-display); font-variant-ligatures:none; font-size:clamp(1.7rem,1.4rem + 1vw,2.5rem); line-height:.9; letter-spacing:-.02em; color:var(--accent-text); margin:0 0 .35rem; }
.strat-cell-t{ font-family:var(--f-body); font-weight:var(--w-semibold); font-size:1.02rem; letter-spacing:-.01em; line-height:1.3; margin:0; color:var(--text); }
.strat-cell-d{ font-size:.9rem; line-height:1.55; color:var(--text-3); margin:0; }
.strat-cell-go{ margin-top:auto; padding-top:.9rem; display:inline-flex; align-items:center; gap:.45rem; }
.strat-cell-go svg{ width:11px; height:6px; transition:transform var(--d-2) var(--ease-hover); }
a.strat-cell:hover .strat-cell-go svg{ transform:translateY(2px); }
.strat-cell--end{ background:var(--wash-accent); }
.strat-cell--end .strat-cell-t{ color:var(--accent-text); }
/* taller boards: the hub rail spans 3 or 4 cell rows (round 7 — both boards
   grew to the full step set). Mobile reset below carries board+hub specificity
   so these spans can never leak past 1020px. */
.strat-board--r3 .strat-hub{ grid-row:span 3; }
.strat-board--r4 .strat-hub{ grid-row:span 4; }
@media (min-width:1021px){
  .strat-cell--wide{ grid-column:span 2; }
}
@media (max-width:1020px){
  .strat-board{ grid-template-columns:1fr 1fr; grid-auto-rows:auto; }
  .strat-board .strat-hub{ grid-column:1 / -1; grid-row:auto; }
  .strat-board .strat-hub-copy{ margin-top:0; padding-top:0; }
}
@media (max-width:600px){
  .strat-board{ grid-template-columns:1fr; }
}


/* ===== js/motion-kit.css ===== */
/* ============================================================================
   motion-kit.css — VENDORED from skills/make-website/assets/motion-kit/kit.css
   Vendored 2026-07-17 by imperial-scaffold. Pairs with js/motion-kit.js (verbatim).

   RE-VENDORED 2026-07-22 by zenith-scaffold, from imperial-arowana-site/ rather than
   from the skill bundle directly. The skill's kit.css is NOT drop-in safe (see the
   extraction note below — it black-outs the body, overrides the display serif, and
   claims a dozen classnames both page workers will reach for), and imperial's copy
   is exactly the namespace-hardened extraction this brief needs a second time.

   RE-VENDORED AGAIN 2026-07-27 by seo-scaffold, forked from levora-site/. Mechanics
   UNTOUCHED; the only delta is that the colour references here read this repo's
   renamed primitives (tokens.css): --c-signal (the emerald) and --c-paper. The
   mk-line descender fix (pad/pull on the CLIPPING element, §reveal below) is present
   and must not be regressed — fleet-wide fix.

   ⚠ THIS IS NOT A COPY — it is a deliberate extraction. Read before re-vendoring.
   The upstream kit.css ships motion-lab's DARK STUDIO DEMO PAGES alongside the
   primitives. Dropping it in raw would have:
     · turned the site black — `body{background:var(--bg)}` with a near-black --bg, on
       a brief whose design contract says the SITE reads LIGHT;
     · overridden the display serif on every heading — `h1,h2,h3{font-family:var(--f-disp)}`
       with a grotesque. An element-level base reset beating our component type is a
       logged footgun, and shipping a wrecked type hierarchy is a teardown offence;
     · painted acid-green #D8FF3E focus rings and progress bars;
     · claimed the classnames five parallel page-builders will reach for first —
       .wrap .row .cell .cap .eyebrow .meta .chip .layer .on .scene, and the
       single-letter .a .b .k .n .t. One shared site.css = one shared namespace.

   WHAT WAS KEPT: the primitive MECHANICS only, re-pointed at house tokens.
   WHAT WAS DROPPED: the :root dark tokens, the base reset (css/base.css owns that),
   STUDIO/LAB + FLAGSHIP demo chrome, the WebGL/forge/chrome/glass-card 3D lane
   (wrong register for this brief), and all demo CARD DRESSING (.hcard/.focus-card/
   .seq-cap/.pinvid-cap). Dressing is page CSS — the kit supplies structure.

   The JS custom-property contract is fixed by kit.js and must not be renamed:
     --si (stagger index) · --ci (char index) · --rd (reveal delay) ·
     --g (grow progress) · --p (progress) · --mx/--my (spotlight cursor)
   ========================================================================== */

/* ---------------------------------------------------------- reveal / enter */
/* Gated on html.js so a no-JS visitor gets content, not a blank page. site.js
   sets .js on <html> before first paint. */
html.js [data-reveal]{
  opacity: 0;
  transform: translateY(28px);
  transition: opacity var(--d-4) var(--ease-reveal) var(--rd, 0ms),
              transform var(--d-4) var(--ease-reveal) var(--rd, 0ms);
}
/* The hide rule above is html-gated, so the reveal must be too: `html.js` costs a
   type selector, and (0,2,0) loses to (0,2,1) — .is-in landed on every element and
   nothing ever became visible. Every page photographed blank. */
html.js [data-reveal].is-in{ opacity: 1; transform: none; }

/* mask line reveal — [data-reveal="mask"]; kit.js wraps each line itself */
.mk-mask{ opacity: 1; transform: none; }
/* Descenders (g/y/j) clip against overflow:hidden on a mask line. The escape
   hatch must live on the CLIPPING element: pad the outer so the clip edge sits
   below the descender, pull the outer back so the box is unchanged (design.md §4).
   Padding on the inner is a no-op — the outer still clips at the same edge. */
.mk-line{
  display: block;
  overflow: hidden;
  padding-bottom: .2em;
  margin-bottom: -.2em;
}
.mk-line-i{
  display: block;
  transform: translateY(115%);
  transition: transform 1s var(--ease-reveal);
}
.mk-mask.is-in .mk-line-i{ transform: none; }
.mk-mask.is-in .mk-line:nth-child(2) .mk-line-i{ transition-delay: .08s; }
.mk-mask.is-in .mk-line:nth-child(3) .mk-line-i{ transition-delay: .16s; }
.mk-mask.is-in .mk-line:nth-child(4) .mk-line-i{ transition-delay: .24s; }

/* ------------------------------------------------------------- stagger */
html.js .mk-stag{
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s var(--ease-reveal), transform .7s var(--ease-reveal);
  transition-delay: calc(var(--si) * 70ms);
}
[data-stagger].is-in .mk-stag{ opacity: 1; transform: none; }

/* ------------------------------------------------------------- marquee */
.mk-marquee{
  overflow: hidden;
  white-space: nowrap;
  -webkit-mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.mk-marquee > *{
  display: inline-flex;
  white-space: nowrap;
  animation: mk-march linear infinite;
  will-change: transform;
}
.mk-marquee:hover > *{ animation-play-state: paused; }
@keyframes mk-march{ to{ transform: translateX(-50%); } }

/* ------------------------------------------------- scroll progress bar */
.mk-progress{
  position: fixed; top: 0; left: 0;
  height: 2px; width: 100%;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: var(--c-signal);
  z-index: var(--z-overlay);
}

/* --------------------------------------------------------- custom cursor */
.mk-cursor, .mk-cursor-ring{
  position: fixed; top: 0; left: 0;
  pointer-events: none;
  z-index: var(--z-cursor);
  border-radius: 50%;
  mix-blend-mode: difference;
  will-change: transform;
}
.mk-cursor{ width: 7px; height: 7px; margin: -3.5px; background: #fff; }
.mk-cursor-ring{
  width: 38px; height: 38px; margin: -19px;
  border: 1px solid #fff;
  transition: width .25s var(--ease-out), height .25s var(--ease-out),
              margin .25s var(--ease-out), opacity .25s;
}
body.mk-cursor-hover .mk-cursor-ring{ width: 62px; height: 62px; margin: -31px; }
@media (pointer: fine){
  body[data-cursor]{ cursor: none; }
  body[data-cursor] a, body[data-cursor] button{ cursor: none; }
}

/* ------------------------------------------- horizontal pinned rail ⭐
   BRIEF §3 signature move 3 (the traverse mechanic). Structure only — style your
   own cards in css/pages/<key>.css. Needs generous travel + enough items or it
   "feels broken" even when the math is right (design.md §9). */
[data-hscroll]{ position: relative; }
.hscroll-sticky{
  position: sticky; top: 0;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: center;
}
[data-hscroll-track]{
  display: flex;
  gap: clamp(1rem, 2vw, 2rem);
  padding-inline: var(--gutter);
  will-change: transform;
}

/* ------------------------------------------------- canvas image-sequence */
.seq-wrap{ position: relative; height: 420vh; }
.seq-sticky{ position: sticky; top: 0; height: 100svh; overflow: hidden; }
.seq-sticky canvas{ position: absolute; inset: 0; width: 100%; height: 100%; }

/* -------------------------------------------- pinned video + scroll steps
   A pinned element MUST give scroll feedback or it reads as broken — pair with
   [data-steps] and a scroll hint, never a passive pin (design.md §9, Charlie-tested). */
.pinvid{ position: relative; height: 300vh; }
.pinvid-sticky{ position: sticky; top: 0; height: 100svh; overflow: hidden; }
.pinvid-sticky video{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.pinvid-step{
  position: absolute; left: 0; bottom: 0;
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .5s var(--ease-out), transform .5s var(--ease-out);
}
.pinvid-step.on{ opacity: 1; transform: none; }

/* ----------------------------------------------------------- spotlight */
[data-spotlight]{ position: relative; --mx: 50%; --my: 50%; overflow: hidden; }
[data-spotlight]::before{
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: radial-gradient(280px circle at var(--mx) var(--my),
              var(--wash-accent), transparent 70%);
  transition: opacity var(--d-2);
  z-index: var(--z-base);
}

/* ------------------------------------------------------ stacking cards */
[data-stack]{ display: flex; flex-direction: column; gap: 6vh; }
.stack-card{
  position: sticky; top: 14vh;
  height: 64vh;
  transform-origin: 50% 0;
  will-change: transform;
}

/* ------------------------------------------- split — per-char mask reveal */
/* kit.js groups chars into .mk-word so headlines never break mid-word. */
.mk-split .mk-word{
  display: inline-flex;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: .08em;
}
.mk-char{
  display: inline-block;
  transform: translateY(112%);
  opacity: 0;
  transition: transform .8s var(--ease-reveal), opacity .8s var(--ease-reveal);
  transition-delay: calc(var(--ci) * 26ms);
}
.mk-split.is-in .mk-char{ transform: none; opacity: 1; }

/* ------------------------------------------ clip — directional curtain
   ⚠ Never point an IntersectionObserver at a fully-clipped element: Chrome reports
   it 0% intersecting and it never reveals. Observe the unclipped parent — kit.js
   already does this (design.md §9). */
html.js [data-clip]{
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1.1s var(--ease-reveal) var(--rd, 0ms);
  will-change: clip-path;
}
html.js [data-clip="down"]{ clip-path: inset(100% 0 0 0); }
html.js [data-clip="left"]{ clip-path: inset(0 100% 0 0); }
html.js [data-clip="right"]{ clip-path: inset(0 0 0 100%); }
/* Same html-gate as the hide rules — and it must also out-specify the three
   directional variants, which sit at (0,2,1) each. (0,3,1) clears all four. */
html.js [data-clip].is-in{ clip-path: inset(0 0 0 0); }

/* --------------------------------------- highlight — read-along word fill */
[data-highlight]{ --mk-dim: var(--text-3); --mk-bright: var(--text); }
.mk-hl{ color: var(--mk-dim); transition: color .35s var(--ease-reveal); }
.mk-hl.on{ color: var(--mk-bright); }

/* --------------------------------------------------- skew (velocity) */
[data-skew]{ will-change: transform; }

/* ------------------------------------------------------- flip card */
.mk-flip{ perspective: 1400px; position: relative; }
.mk-flip-inner{
  position: relative;
  transform-style: preserve-3d;
  transition: transform .85s var(--ease-reveal);
  will-change: transform;
}
.mk-flip:hover .mk-flip-inner,
.mk-flip.is-flipped .mk-flip-inner{ transform: rotateY(180deg); }
.mk-flip [data-flip-front], .mk-flip [data-flip-back]{
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.mk-flip [data-flip-back]{ position: absolute; inset: 0; transform: rotateY(180deg); }

/* --------------------------------------------- focus carousel [data-focus] */
[data-focus]{
  display: flex;
  gap: clamp(.8rem, 2vw, 1.4rem);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  padding: 1.4rem max(20px, calc(50% - 150px));
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
[data-focus]::-webkit-scrollbar{ display: none; }
[data-focus] > *{
  flex: 0 0 auto;
  scroll-snap-align: center;
  transform-origin: center center;
  will-change: transform, opacity;
}

/* ------------------------------------------- grow to full-bleed [data-grow] */
[data-grow]{ transform-origin: center center; will-change: transform; }

/* ---------------------------------------------- hover peek list ⭐
   design.md §9: the DEFAULT treatment for any service/work index list.
   Charlie-approved live on touchmkt.com. BRIEF §4 services page is the target. */
.mk-peek{
  position: fixed; left: 0; top: 0;
  z-index: var(--z-overlay);
  width: min(25vw, 368px);
  aspect-ratio: 4 / 3;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  background: var(--c-ink-deep);
  outline: 1px solid var(--rule-accent);
  box-shadow: 0 2px 6px rgba(18, 20, 23, .2), 0 34px 90px -22px rgba(18, 20, 23, .5);
  transition: opacity var(--d-2) var(--ease-out);
  will-change: transform, opacity;
}
.mk-peek.on{ opacity: 1; }
/* Match the frame to the media: horizontal films get data-peek-wide (websites.md §11). */
.mk-peek.wide{ aspect-ratio: 16 / 9; width: min(29vw, 440px); }
.mk-peek img, .mk-peek video{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.mk-peek video{ display: none; }
@media (max-width: 900px), (pointer: coarse){ .mk-peek{ display: none !important; } }

/* ="invert": a full-bleed band sweeps behind the hovered row and inverts its text */
[data-peeklist="invert"] [data-peek-img]{ position: relative; isolation: isolate; }
[data-peeklist="invert"] [data-peek-img]::before{
  content: "";
  position: absolute; top: 0; bottom: 0; left: 50%;
  width: 100vw; margin-left: -50vw;
  background: var(--pl-band, var(--c-ink-deep));
  transform: scaleY(0);
  transform-origin: 50% 0;
  transition: transform .5s var(--ease-out);
  z-index: -1;
  pointer-events: none;
}
[data-peeklist="invert"] [data-peek-img]:hover::before{ transform: scaleY(1); }
[data-peeklist="invert"] [data-peek-img]:hover,
[data-peeklist="invert"] [data-peek-img]:hover *{ color: var(--pl-hover-fg, var(--c-paper)); }
@media (pointer: coarse){
  [data-peeklist="invert"] [data-peek-img]::before{ display: none; }
}

/* ---------------------------------------------------------------- floors */
/* Reduced motion: everything is visible and still. No transforms, no clips, no
   opacity gates — the content IS the floor. */
@media (prefers-reduced-motion: reduce){
  html.js [data-reveal],
  html.js .mk-stag,
  .mk-char{ opacity: 1 !important; transform: none !important; }
  html.js [data-clip],
  html.js [data-clip="down"],
  html.js [data-clip="left"],
  html.js [data-clip="right"]{ clip-path: none !important; }
  .mk-line-i{ transform: none !important; }
  .mk-marquee > *{ animation: none !important; }
  .mk-cursor, .mk-cursor-ring, .mk-peek{ display: none !important; }
}


/* ===== css/eden.css ===== */
/* ============================================================================
   eden.css — the Eden Cube format layer (Charlie-directed, round 4).
   OWNER: seo-scaffold. Shared, sitewide, loads after motion-kit.css.

   Ported from eden-cube-site (styles.css + inner.css): the section formats,
   type stanzas and motion grammar of eden-cube-site.vercel.app — RECOLOURED
   through this repo's semantic tokens (tokens.css). No Eden hexes survive:
   every colour below resolves to --surface/--text/--accent-text/--rule roles,
   so the ink island flip keeps working and the palette stays ours.

   Formats: .ehero (full-bleed mask-rise hero) · .phead (centred page head)
   · .intro (statement band) · .feat-grid (rule-left pointer cards) · .atab
   (accordion + crossfade image) · .teaser (photo band + frosted cards)
   · .meet (dark CTA card) · .band / .bleed (full-bleed imagery) · .faq/.pacc
   (sticky-intro accordion) · .founder (portrait split) · .disc (split card)
   · .pullq · .gsweep / .lfade (headline motion) · .link-serif · .eyebrow.

   Engines in js/shared/eden.js. Buttons stay base.css's (.btn--signal etc.).
   ========================================================================== */

:root{
  --ease-inout: cubic-bezier(.77, 0, .175, 1);
  /* gradient-sweep dims, tuned to the warm paper / green-black palette */
  --sweep-mid:  #6b7061;
  --sweep-dim:  #cdc9bc;
  --sweep-mid-d:#b9bfae;
  --sweep-dim-d:#565b4c;
}

/* ---------- type stanzas ---------- */
.h-xl, .h-l, .h-m, .h-s{
  font-family: var(--f-display); font-weight: var(--w-display);
  font-variant-ligatures: none; color: var(--text);
}
.h-xl{ font-size: clamp(2.7rem, 1.5rem + 4.4vw, 6.25rem); line-height: .94; letter-spacing: -.045em; }
.h-l { font-size: clamp(2rem, 1.4rem + 2.2vw, 3.75rem);   line-height: 1;   letter-spacing: -.03em; }
.h-m { font-size: clamp(1.6rem, 1.3rem + 1vw, 2.6rem);    line-height: 1.05; letter-spacing: -.02em; }
.h-s { font-size: clamp(1.15rem, 1.05rem + .4vw, 1.55rem); line-height: 1.14; letter-spacing: -.015em; }

.eyebrow{
  font-family: var(--f-body); font-size: .72rem; letter-spacing: .09em;
  text-transform: uppercase; font-weight: 500; color: var(--text-3);
}
.eyebrow--accent{ color: var(--accent-text); }

.link-serif{
  font-family: var(--f-display); font-weight: var(--w-display); font-variant-ligatures: none;
  font-size: clamp(1.25rem, 1.1rem + .5vw, 1.7rem); letter-spacing: -.01em;
  color: var(--accent-text); text-decoration: underline; text-underline-offset: 6px;
  text-decoration-thickness: 1px; transition: color var(--d-2) var(--ease-hover);
}
.link-serif:hover{ color: var(--text); }

/* ---------- gradient-sweep headlines (scroll-driven --reveal) ---------- */
.gsweep{ --reveal: 0; color: transparent; -webkit-text-fill-color: transparent;
  background-image: linear-gradient(150deg, var(--text) 0%, var(--sweep-mid) 32%, var(--sweep-dim) 62%, var(--sweep-dim) 100%);
  background-size: 130% 520%; background-clip: text; -webkit-background-clip: text;
  background-position: 0% calc(100% - var(--reveal) * 100%);
  padding-bottom: .12em; margin-bottom: -.12em;
}
[data-surface="ink"] .gsweep, [data-surface="ink-deep"] .gsweep, .gsweep--dark{
  background-image: linear-gradient(150deg, var(--c-paper) 0%, var(--sweep-mid-d) 32%, var(--sweep-dim-d) 62%, var(--sweep-dim-d) 100%);
}
@media (prefers-reduced-motion: reduce){ .gsweep{ --reveal: 1 !important; } }

/* letter/word fade for big titles (js/shared/eden.js data-lfade-scroll) */
.lfade span{ display: inline-block; opacity: 0; transform: translateY(.35em);
  transition: opacity .7s var(--ease-reveal), transform .7s var(--ease-reveal); }
.lfade.in span{ opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce){ .lfade span{ opacity: 1; transform: none; transition: none; } }

/* ---------- full-bleed hero (mask-rise lines + sub + scroll hint) ---------- */
.ehero{ position: relative; height: 100svh; min-height: 560px; }
.ehero-media, .ehero-media video, .ehero-media img{
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ehero-shade{ position: absolute; inset: 0; background:
  radial-gradient(120% 78% at 50% 47%, rgb(11 12 8 / .50) 0%, rgb(11 12 8 / .18) 56%, rgb(11 12 8 / 0) 100%),
  linear-gradient(180deg, rgb(11 12 8 / .62) 0%, rgb(11 12 8 / .30) 27%, rgb(11 12 8 / .32) 60%, rgb(11 12 8 / .60) 100%); }
.ehero-in{
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(1.5rem, 3.4vh, 2.4rem); text-align: center;
  padding: calc(var(--nav-h) + 1rem) clamp(1.25rem, 6vw, 6rem) 4.5rem;
}
.ehero-in .btns{ justify-content: center; flex-wrap: wrap; }
/* the registered-entity line above the headline */
.ehero-firm{
  font-size: .7rem; letter-spacing: .2em; text-transform: uppercase; font-weight: 500;
  color: rgb(247 245 240 / .85); text-shadow: 0 1px 14px rgb(11 12 8 / .5);
  margin-bottom: calc(-1 * clamp(.5rem, 1.8vh, 1.1rem));
}
@media (max-width: 760px){ .ehero-firm{ font-size: .6rem; letter-spacing: .16em; padding-inline: .5rem; } }
.ehero-h{
  display: flex; flex-direction: column; align-items: center;
  text-transform: uppercase; pointer-events: none;
  font-family: var(--f-display); font-weight: var(--w-display);
  font-size: clamp(1.7rem, .8rem + 2.9vw, 3.4rem); line-height: .98; letter-spacing: -.005em;
}
/* translucent proof strip over the footage */
.ehero-stats{
  display: flex; align-items: stretch; margin: 0;
  background: rgb(11 12 8 / .42); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-radius: var(--r-btn); padding: 1rem clamp(.4rem, 1.4vw, 1rem);
}
.estat{
  display: flex; flex-direction: column; gap: .25rem;
  padding-inline: clamp(1.1rem, 2.4vw, 2.2rem); text-align: center;
}
.estat + .estat{ border-left: 1px solid rgb(247 245 240 / .18); }
.estat dt{
  font-family: var(--f-display); font-weight: var(--w-display); font-variant-ligatures: none;
  font-size: clamp(1.35rem, 1rem + 1.2vw, 2.1rem); line-height: 1; color: var(--text);
}
.estat dd{
  margin: 0; font-size: .64rem; letter-spacing: .12em; text-transform: uppercase;
  font-weight: 500; color: var(--text-3);
}
@media (max-width: 700px){
  .ehero-stats{ flex-direction: column; padding: .5rem 1.6rem; }
  .estat{ padding: .75rem 0; }
  .estat + .estat{ border-left: 0; border-top: 1px solid rgb(247 245 240 / .18); }
}
.hl{ display: block; overflow: hidden; padding-bottom: .08em; margin-bottom: -.08em; }
.hl-in{ display: block;
  background: linear-gradient(125.75deg, #f6f4ee 9.27%, #c8ccbe 95.35%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: 0 2px 30px rgb(11 12 8 / .55);
  transform: translateY(108%); transition: transform 1.15s var(--ease-reveal);
}
.ehero.loaded .hl:nth-child(1) .hl-in{ transition-delay: .15s; }
.ehero.loaded .hl:nth-child(2) .hl-in{ transition-delay: .3s; }
.ehero.loaded .hl:nth-child(3) .hl-in{ transition-delay: .45s; }
.ehero.loaded .hl-in{ transform: none; }
@media (prefers-reduced-motion: reduce){ .hl-in{ transform: none; transition: none; } }
.ehero-sub{ position: absolute; left: 0; right: 0; bottom: clamp(4.2rem, 10vh, 6.5rem); z-index: 3;
  text-align: center; font-size: .8rem; letter-spacing: .24em; text-transform: uppercase;
  font-weight: 500; color: rgb(247 245 240 / .82); pointer-events: none; }
.ehero-scroll{ position: absolute; bottom: 1.25rem; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: .65rem;
  font-size: .6875rem; letter-spacing: .05em; text-transform: uppercase; font-weight: 500;
  color: rgb(247 245 240 / .8); }
.ehero-scroll-line{ width: 1px; height: 2.5rem; background: rgb(247 245 240 / .35);
  position: relative; overflow: hidden; display: block; }
.ehero-scroll-line b{ position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  background: var(--c-paper); animation: eden-scrollhint 2.2s var(--ease-inout) infinite; }
@keyframes eden-scrollhint{
  0%{ transform: translateY(-100%); } 45%{ transform: translateY(0); }
  55%{ transform: translateY(0); } 100%{ transform: translateY(100%); } }
@media (max-width: 760px){ .ehero-h{ font-size: clamp(1.55rem, 6.6vw, 2.2rem); }
  .ehero-sub{ bottom: 7.6rem; font-size: .72rem; letter-spacing: .2em; padding-inline: 1rem; } }

/* ---------- centred page head (inner pages) ---------- */
.phead{ position: relative; padding: calc(var(--nav-h) + clamp(3rem, 8vh, 6rem)) var(--gutter) 0;
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 1.2rem; }
.phead h1{ max-width: 16em; font-size: clamp(2.7rem, 1.5rem + 4.4vw, 6.25rem);
  line-height: .94; letter-spacing: -.045em; }
.phead-body{ max-width: 34rem; font-size: var(--t-body); line-height: 1.6; color: var(--text-2); }
.phead .btns{ justify-content: center; }
.phead-note{ color: var(--text-3); max-width: 44ch; font-size: var(--t-micro-2); line-height: 1.55; }
.phead-brush{ position: absolute; top: 8%; left: 50%; transform: translate(-38%, 0) rotate(-14deg);
  width: clamp(220px, 32vw, 460px); aspect-ratio: 1 / 1.15; pointer-events: none; z-index: -1;
  background:
    radial-gradient(42% 30% at 40% 30%, rgb(203 211 196 / .45), transparent 70%),
    radial-gradient(34% 26% at 62% 52%, rgb(125 132 115 / .22), transparent 70%),
    radial-gradient(30% 22% at 46% 72%, rgb(229 224 213 / .55), transparent 70%);
  filter: blur(6px); }

/* ---------- statement band ---------- */
.intro{ padding: var(--space-section) var(--gutter) 0; }
.intro-in{ max-width: 1080px; margin: 0 auto; display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: clamp(1.6rem, 4vw, 4rem); align-items: start; }
/* the claim sits centred on the side column's PARAGRAPHS (Charlie 2026-07-29) —
   not bottom-aligned to the whole column, whose CTAs would drag it low; the
   margin-top below carries that offset, so re-measure it if the claim reflows */
.intro-claim{ display: flex; align-items: center; gap: clamp(1rem, 1.8vw, 1.5rem);
  margin-top: 1.6rem; }
.intro-mark{ width: clamp(48px, 5vw, 72px); height: auto; flex: none; }
.intro-in h2{ font-family: var(--f-display); font-weight: var(--w-display);
  font-variant-ligatures: none; font-size: clamp(1.7rem, 1rem + 2.4vw, 2.9rem);
  line-height: 1.14; letter-spacing: -.015em; color: var(--text); }
.intro-side p{ font-size: var(--t-body); line-height: 1.6; color: var(--text-2); margin-bottom: 1.1rem; }
@media (max-width: 760px){ .intro-in{ grid-template-columns: 1fr; }
  .intro-claim{ margin-top: 0; flex-direction: column; align-items: flex-start; gap: .95rem; }
  .intro-mark{ width: 46px; } }

/* ---------- rule-left pointer cards ---------- */
.feat-grid{ list-style: none; display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(2rem, 4vh, 3.2rem) clamp(1.2rem, 2vw, 2rem); margin-top: clamp(3rem, 8vh, 5rem); }
.feat-grid--5{ grid-template-columns: repeat(5, 1fr); }
.feat-grid--3{ grid-template-columns: repeat(3, 1fr); }
.feat-grid li{ border-left: 1px solid var(--rule-stone); padding-left: clamp(1rem, 1.6vw, 1.6rem);
  display: flex; flex-direction: column; gap: .7rem; }
.feat-grid small{ font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-3); font-weight: 500; }
.feat-grid .h-s{ max-width: 12em; }
.feat-grid p{ font-size: var(--t-body); line-height: 1.55; color: var(--text-2); }
.feat-grid .feat-n{ font-family: var(--f-display); font-variant-ligatures: none;
  font-weight: var(--w-display); font-size: clamp(2.6rem, 2rem + 2vw, 4.4rem);
  line-height: .9; letter-spacing: -.03em; color: var(--accent-text); }
@media (max-width: 1100px){ .feat-grid, .feat-grid--5{ grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px){ .feat-grid, .feat-grid--5{ grid-template-columns: 1fr; } }

/* ---------- accordion tabs + crossfade image (dark boxed card) ---------- */
.atab{ position: relative; margin-top: var(--space-section); overflow: hidden; }
.atab--boxed{ margin-inline: clamp(16px, 2.4vw, 34px); border-radius: var(--r-btn);
  background:
    radial-gradient(120% 90% at 80% 10%, rgb(92 195 148 / .10), transparent 55%),
    linear-gradient(150deg, #1c1f18, var(--c-ink-deep)); }
.atab-in{ position: relative; width: 100%; max-width: var(--maxw); margin: 0 auto;
  padding: clamp(3.4rem, 9vh, 7rem) var(--gutter); }
.atab-head{ display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 1.15rem; margin-bottom: clamp(2.6rem, 7vh, 4.5rem); }
.atab-head .h-l{ max-width: 24em; }
.atab-grid{ display: grid; grid-template-columns: minmax(0, 38%) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.atab-item{ cursor: pointer; padding-block: .8rem; outline: none; }
.atab-item .h-s{ color: var(--accent-text); display: flex; align-items: center; gap: .7rem;
  transition: color .35s var(--ease-hover); }
.atab-item:hover .h-s{ color: var(--text-2); }
.atab-item.is-on .h-s{ color: var(--text); }
.atab-item:focus-visible .h-s{ text-decoration: underline; text-underline-offset: 5px; }
.atab-arr{ width: 8px; height: 14px; opacity: 0; transform: translateX(-6px);
  transition: opacity .35s var(--ease-hover), transform .35s var(--ease-hover); }
.atab-item.is-on .atab-arr{ opacity: .9; transform: none; }
.atab-body{ max-height: 0; overflow: hidden; transition: max-height .5s var(--ease-inout); }
.atab-item.is-on .atab-body{ max-height: 11rem; }
.atab-body p{ font-size: var(--t-body); line-height: 1.5; padding-top: .55rem; max-width: 26rem; color: var(--text-2); }
.atab-imgs{ position: relative; border-radius: var(--r-btn); overflow: hidden; aspect-ratio: 16 / 9.6; }
.atab-imgs::before{ content: ""; position: absolute; inset: 0; border-radius: var(--r-btn);
  box-shadow: inset 0 0 0 1px var(--rule-accent); pointer-events: none; z-index: 2; }
.atab-img{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; pointer-events: none; }
.atab-img.is-on{ opacity: 1; animation: eden-atab-in .8s cubic-bezier(.3, 0, 0, 1); }
.atab-img.is-out{ opacity: 1; animation: eden-atab-out .8s cubic-bezier(.3, 0, 0, 1) forwards; }
@keyframes eden-atab-in{ from{ opacity: 0; transform: translate(28px); } to{ opacity: 1; transform: translate(0); } }
@keyframes eden-atab-out{ from{ opacity: 1; transform: translate(0); } to{ opacity: 0; transform: translate(-28px); } }
.atab-cta{ margin-top: clamp(2.6rem, 7vh, 4.2rem); display: flex; flex-direction: column;
  align-items: center; gap: .7rem; }
.atab-cta small{ font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.atab-cards{ display: none; }
@media (max-width: 900px){
  .atab-grid{ display: none; }
  .atab-cards{ display: flex; flex-direction: column; gap: 2rem; }
  .atab-card .atab-card-img{ border-radius: var(--r-btn); overflow: hidden; margin-bottom: 1rem; }
  .atab-card .atab-card-img img{ width: 100%; aspect-ratio: 16 / 9.6; object-fit: cover; }
  .atab-card .h-s{ color: var(--text); margin-bottom: .5rem; }
  .atab-card p{ font-size: var(--t-body); line-height: 1.55; color: var(--text-2); max-width: 34rem; }
}

/* ---------- full-bleed teaser band + frosted cards ---------- */
.teaser{ position: relative; margin-top: var(--space-section); min-height: 92svh;
  display: flex; align-items: flex-end; overflow: hidden; }
.teaser > img{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.teaser-shade{ position: absolute; inset: 0; background:
  linear-gradient(180deg, rgb(11 12 8 / .50), rgb(11 12 8 / .28) 42%, rgb(11 12 8 / .62)); }
.teaser-in{ position: relative; width: 100%; padding: clamp(3rem, 8vh, 5.5rem) var(--gutter); }
/* frosted panel behind the head copy (Charlie 2026-07-30) — same glass as the
   tier cards below, so the lede stays readable over the skyline */
.teaser-head{ max-width: 36rem; margin-bottom: clamp(2rem, 6vh, 3.6rem);
  background: rgb(11 12 8 / .42); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-radius: var(--r-btn); padding: 1.5rem 1.7rem 1.6rem; }
.teaser-head .eyebrow{ margin-bottom: 1rem; }
.teaser-head .h-l{ text-shadow: 0 2px 22px rgb(11 12 8 / .5); }
.teaser-cards{ display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .9rem; max-width: 980px; }
.teaser-cards--4{ grid-template-columns: repeat(4, minmax(0, 1fr)); max-width: 1240px; }
.tcard{ background: rgb(11 12 8 / .42); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-radius: var(--r-btn); padding: 1.15rem 1.3rem 1.3rem;
  display: flex; flex-direction: column; gap: .55rem; }
.tcard small{ font-size: .62rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-3); font-weight: 500; }
.tcard .h-s{ color: var(--text); }
.tcard p{ font-size: var(--t-body); line-height: 1.5; color: var(--text-2); }
.tcard--link .link-serif{ font-size: clamp(1.25rem, 1.1rem + .5vw, 1.6rem); }
@media (max-width: 1100px){ .teaser-cards, .teaser-cards--4{ grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px){ .teaser-cards, .teaser-cards--4{ grid-template-columns: 1fr; } }

/* ---------- dark CTA card ---------- */
/* bottom padding matters here — .meet is the last section on every page, and with
   0 the card sat flush against the dark footer band (Charlie 2026-07-29) */
.meet{ padding: var(--space-section) var(--gutter) var(--space-section); }
.meet-card{ max-width: 960px; margin: 0 auto; display: grid; grid-template-columns: 1.05fr 1fr;
  border-radius: var(--r-btn); overflow: hidden;
  background:
    radial-gradient(110% 80% at 85% 0%, rgb(92 195 148 / .10), transparent 55%),
    linear-gradient(150deg, #1c1f18, var(--c-ink-deep)); }
.meet-txt{ padding: clamp(2rem, 4.5vw, 3.6rem) clamp(1.6rem, 3.2vw, 3rem);
  display: flex; flex-direction: column; gap: 1.15rem; justify-content: center; }
.meet-txt .h-m{ color: var(--text); }
.meet-txt p{ font-size: var(--t-body); line-height: 1.5; max-width: 24rem; color: var(--text-2); }
.meet-txt .btns{ margin-top: .4rem; }
.meet-img img{ width: 100%; height: 100%; object-fit: cover; min-height: 340px; }
.meet-note{ color: var(--text-3); }
@media (max-width: 760px){ .meet-card{ grid-template-columns: 1fr; } }

/* ---------- full-bleed framed image band ---------- */
.band{ padding: var(--space-section) clamp(16px, 2.4vw, 34px) 0; }
.band-frame{ overflow: hidden; border-radius: 2px; }
.band-frame img{ width: 100%; height: clamp(380px, 78vh, 720px); object-fit: cover; }
.band-cap{ display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  padding: .8rem .2rem 0; }

/* ---------- edge-bleed image row ---------- */
.bleed{ display: flex; gap: clamp(.9rem, 1.6vw, 1.5rem); margin-top: var(--space-section);
  align-items: stretch; }
.bleed figure{ border-radius: var(--r-btn); overflow: hidden; flex-grow: 1; min-width: 0; }
.bleed figure:first-child{ border-top-left-radius: 0; border-bottom-left-radius: 0; }
.bleed figure:last-child{ border-top-right-radius: 0; border-bottom-right-radius: 0; }
.bleed img{ width: 100%; height: clamp(340px, 70vh, 640px); object-fit: cover; }

/* ---------- FAQ: sticky intro + accordion rows ---------- */
.faq{ padding: var(--space-section) var(--gutter) 0; }
.faq-in{ max-width: var(--maxw); margin: 0 auto; display: grid;
  grid-template-columns: minmax(240px, 380px) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem); align-items: start; }
.faq-head{ position: sticky; top: calc(var(--nav-h) + 1.6rem); }
.faq-head .eyebrow{ margin-bottom: 1.2rem; }
.faq-body{ margin-top: 1.2rem; font-size: var(--t-body); line-height: 1.6; color: var(--text-2); max-width: 26rem; }
.pacc{ border-bottom: 1px solid var(--rule); }
.pacc:first-of-type{ border-top: 1px solid var(--rule); }
.pacc-head{ width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 1.25rem .1rem; text-align: left;
  font-family: var(--f-display); font-variant-ligatures: none; font-weight: var(--w-display);
  font-size: clamp(1.05rem, 1.5vw, 1.3rem); letter-spacing: -.01em; color: var(--text);
  transition: color var(--d-2) var(--ease-hover); }
.pacc-head:hover{ color: var(--accent-text); }
.pacc-head svg{ width: 11px; height: 11px; flex-shrink: 0; transition: transform .4s var(--ease-inout); }
.pacc.open .pacc-head svg{ transform: rotate(45deg); }
.pacc-body{ max-height: 0; overflow: hidden; transition: max-height .5s var(--ease-inout); }
.pacc-body p{ padding: .2rem .1rem 1.1rem; padding-left: 2.05rem; font-size: var(--t-body);
  line-height: 1.6; max-width: 44rem; color: var(--text-2); }
.faq-q{ display: flex; align-items: baseline; gap: 1rem; }
.faq-q em{ font-style: normal; font-family: var(--f-body); font-size: .68rem;
  letter-spacing: .1em; color: var(--text-3); flex-shrink: 0; }
@media (max-width: 900px){
  .faq-in{ grid-template-columns: 1fr; gap: 1.6rem; }
  .faq-head{ position: static; }
  .pacc-body p{ padding-left: .1rem; } }

/* ---------- founder / portrait split ---------- */
.founder{ padding: var(--space-section) var(--gutter) 0; }
.founder-in{ max-width: 1180px; margin: 0 auto; display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(1.6rem, 4vw, 4rem); align-items: center; }
.founder-fig{ border-radius: var(--r-btn); overflow: hidden; aspect-ratio: 4 / 5; }
.founder-fig img{ width: 100%; height: 100%; object-fit: cover; }
.founder-txt .eyebrow{ margin-bottom: .8rem; }
.founder-txt h2{ font-family: var(--f-display); font-weight: var(--w-display);
  font-variant-ligatures: none; font-size: clamp(1.9rem, 1rem + 2.6vw, 3rem);
  line-height: 1.08; letter-spacing: -.02em; color: var(--text); margin-bottom: .3rem; }
/* NOTE: no font-size here — .founder-txt p (higher specificity, below) owns it at 1rem;
   a size declared here is dead code and has been twice already */
.founder-role{ letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-text); font-weight: 500; margin-bottom: 1.3rem; }
.founder-txt blockquote{ font-family: var(--f-display); font-style: italic;
  font-size: clamp(1.15rem, 1rem + .8vw, 1.6rem); line-height: 1.3; letter-spacing: -.01em;
  color: var(--text); margin-bottom: 1.2rem; }
.founder-txt p{ font-size: 1rem; line-height: 1.65; max-width: 40rem; color: var(--text-2); }
.founder-creds{ list-style: none; margin-top: 1.3rem; display: flex; flex-direction: column; gap: .7rem; }
.founder-creds li{ font-size: var(--t-body); line-height: 1.55; color: var(--text-2);
  padding-left: 1.2rem; position: relative; }
.founder-creds li::before{ content: ""; position: absolute; left: 0; top: .58em;
  width: .35rem; height: 1px; background: var(--accent-text); }
.founder-txt .link-serif{ display: inline-block; margin-top: 1.4rem; }
@media (max-width: 820px){
  .founder-in{ grid-template-columns: 1fr; }
  .founder-fig{ max-width: 22rem; }
}

/* ---------- split discover card ---------- */
.disc{ padding: var(--space-section) clamp(16px, 2.4vw, 34px) 0; }
/* card is capped, not monitor-wide — at 2300px viewports an uncapped panel
   stranded the copy in dead space (Charlie 2026-07-29) */
.disc-card{ display: grid; grid-template-columns: minmax(0, 1fr) 1px minmax(0, 36%);
  gap: clamp(2rem, 4vw, 4.5rem); align-items: center;
  max-width: 1360px; margin: 0 auto;
  background: linear-gradient(140deg, var(--surface) 20%, var(--surface-3));
  border-radius: var(--r-btn);
  padding: clamp(2.4rem, 6vw, 5rem) clamp(1.6rem, 4vw, 4.5rem); }
.disc-txt .eyebrow{ margin-bottom: 1.2rem; }
.disc-lede{ margin-top: 1rem; font-size: var(--t-body); line-height: 1.6;
  color: var(--text-2); max-width: 54ch; }
.disc-rule{ background: var(--rule-2); opacity: .5; height: 70%; min-height: 120px; }
.disc-side{ display: flex; flex-direction: column; gap: 1rem; }
.disc-side p{ font-size: var(--t-body); line-height: 1.55; color: var(--text-2); }
.disc-card small{ display: block; font-size: var(--t-micro-2); letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-3); font-weight: 500; }
.disc-txt small{ margin: 1.8rem 0 .9rem; }
.disc-list{ list-style: none; display: flex; flex-direction: column; gap: .7rem; }
.disc-list li{ font-size: var(--t-body); line-height: 1.55; color: var(--text-2);
  padding-left: 1.2rem; position: relative; }
.disc-list li::before{ content: ""; position: absolute; left: 0; top: .58em;
  width: .35rem; height: 1px; background: var(--text-3); }
.disc-list--on li::before{ background: var(--accent-text); }
@media (max-width: 900px){
  .disc-card{ grid-template-columns: 1fr; gap: 1.8rem; }
  .disc-rule{ width: 70%; height: 1px; min-height: 0; } }

/* ---------- big serif pull-quote ---------- */
.pullq{ padding: var(--space-section) var(--gutter) 0; }
.pullq-in{ max-width: 1000px; margin: 0 auto; text-align: center; }
.pullq blockquote{ font-family: var(--f-display); font-weight: var(--w-display); font-style: italic;
  font-size: clamp(1.7rem, 1rem + 3vw, 3.3rem); line-height: 1.18; letter-spacing: -.015em;
  color: var(--text); }
.pullq cite{ display: block; margin-top: 1.4rem; font-style: normal; font-size: .72rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--text-3); font-weight: 500; }


/* ===== css/pages/about.css ===== */
/* ===== about — scoped .p-about ===== */

/* ---- open: lead | founder portrait ---- */
.p-about .about-open-grid{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
  align-items: center;
}
@media (min-width: 900px){
  .p-about .about-open-grid{
    grid-template-columns: 1.1fr 0.9fr;
    column-gap: clamp(2rem, 5vw, 5rem);
  }
}
.p-about .about-open-lead{ display: flex; flex-direction: column; gap: var(--s-4); }
.p-about .about-open-lead h1{ margin: 0; }
/* round 9 (Charlie: "add padding") — the display headline needs real air at
   its two boundaries; the idx label stays tight to the h1 it captions. */
.p-about .about-open-lead .lede{ margin-top: clamp(.5rem, .4rem + .8vw, 1.25rem); }
.p-about .about-open-lead .btns{ margin-top: clamp(.75rem, .5rem + 1vw, 1.5rem); }
.p-about .about-open-portrait{ margin: 0; }
.p-about .about-open-portrait .frame{ max-width: 30rem; margin-inline: auto; }
.p-about .about-open-portrait .frame-cap{ margin-top: var(--s-3); }

/* ---- thesis: the ink island, the E-E-A-T argument ---- */
.p-about .about-thesis-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-5); }
@media (min-width: 900px){
  .p-about .about-thesis-grid{ grid-template-columns: 1.1fr 0.9fr; column-gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
}
.p-about .about-thesis-grid .statement{ margin: 0; max-width: 20ch; }
.p-about .about-thesis-body{ display: flex; flex-direction: column; gap: var(--s-4); }

/* ---- credentials: four E-E-A-T pillars, editorial not boxed ---- */
.p-about .about-cred-head{ margin-bottom: clamp(2rem, 5vw, 4rem); }
.p-about .about-cred-head h2{ margin: var(--s-3) 0 0; max-width: 24ch; }
.p-about .about-cred-list{ display: grid; grid-template-columns: 1fr; }
@media (min-width: 760px){ .p-about .about-cred-list{ grid-template-columns: 1fr 1fr; column-gap: clamp(2rem, 5vw, 4.5rem); } }
.p-about .cred{ padding: var(--s-5) 0; border-top: 1px solid var(--rule); }
.p-about .cred-tag{ display: block; margin-bottom: var(--s-2); }
.p-about .cred h3{ margin: 0 0 var(--s-3); max-width: 20ch; }
.p-about .cred p{ color: var(--text-3); max-width: 52ch; }

/* ---- proof: compact rank row linking the four cases ---- */
.p-about .about-proof-head{ margin-bottom: clamp(2rem, 5vw, 3.5rem); }
.p-about .about-proof-head .statement{ margin: var(--s-3) 0 var(--s-4); }
.p-about .about-proof-head .lede{ max-width: 52ch; }
.p-about .about-mini{ display: grid; grid-template-columns: 1fr; gap: 0; }
@media (min-width: 720px){ .p-about .about-mini{ grid-template-columns: repeat(2, 1fr); column-gap: clamp(2rem, 5vw, 4rem); } }
.p-about .about-mini-item{ border-top: 1px solid var(--rule); }
.p-about .about-mini-link{ display: flex; align-items: baseline; gap: var(--s-4); padding: var(--s-4) 0; transition: color var(--d-2) var(--ease-hover); }
.p-about .about-mini-link:hover .about-mini-kw{ color: var(--accent-text); }
.p-about .about-mini-n{ font-size: clamp(2.5rem, 6vw, 3.75rem); flex: none; }
.p-about .about-mini-meta{ display: flex; flex-direction: column; gap: 2px; }
.p-about .about-mini-kw{ font-family: var(--f-display); font-size: var(--t-h3); color: var(--text); line-height: 1.2; transition: color var(--d-2) var(--ease-hover); }
.p-about .about-mini-from{ color: var(--text-3); }
.p-about .about-proof-cta{ margin-top: var(--s-5); }

/* ---- close ---- */
.p-about .about-cta h2{ max-width: 22ch; }
.p-about .about-cta-foot{ margin-top: var(--s-5); color: var(--text-3); }


/* ===== css/pages/blog.css ===== */
/* ===== css/pages/blog.css — Journal hub (key "blog", scoped .p-blog) =====
   Owner: seo-longtail. Binds only to the shared semantic tokens (values come from
   scaffold's tokens.css lane), so this re-skins automatically. Signature motif:
   the index is a vertical column of SERP-result cards — the on-brand read for an
   SEO firm, and a deliberate rejection of the banned uniform card-grid. */

/* ---- hero header: editorial two-part (title left, lede right) ---- */
.p-blog .blog-head .wrap{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
}
.p-blog .blog-head-title{
  font-family: var(--f-display);
  font-size: var(--t-display);
  line-height: var(--lh-display);
  letter-spacing: -0.01em;
  max-width: 16ch;
  margin: var(--s-4) 0 0;
}
.p-blog .blog-head-side{ max-width: var(--prose); }
.p-blog .blog-head-meta{ margin-top: var(--s-4); color: var(--text-3); }

@media (min-width: 900px){
  .p-blog .blog-head .wrap{
    grid-template-columns: 1.1fr 0.9fr;
    align-items: end;
    gap: var(--s-7);
  }
  .p-blog .blog-head-title{ margin-top: var(--s-5); }
}

/* ---- the results column ---- */
.p-blog .jindex{
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  max-width: 760px;      /* a real search column is narrow — reads as a SERP */
}
.p-blog .jitem{ margin: 0; }

/* ---- SERP-result card ---- */
.p-blog .serp-card{
  display: block;
  padding: var(--s-5);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 8px;   /* squarer than a boutique — a results firm */
  transition: border-color var(--d-2) var(--ease-hover),
              transform var(--d-2) var(--ease-hover),
              box-shadow var(--d-2) var(--ease-hover);
}
.p-blog .serp-card:hover{
  border-color: var(--accent-text);
  transform: translateY(-2px);
  box-shadow: 0 12px 30px -22px var(--text);
}
.p-blog .serp-card:focus-visible{
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
}

.p-blog .serp-url{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 var(--s-2);
  font-family: var(--f-body);
  font-size: var(--t-micro-2);
  line-height: 1.4;
}
.p-blog .serp-fav{
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent-text);
  flex: 0 0 auto;
}
.p-blog .serp-site{ color: var(--text-2); font-weight: var(--w-medium); }
.p-blog .serp-path{
  color: var(--accent-text);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.p-blog .serp-title{
  font-family: var(--f-display);
  font-size: var(--t-h2);
  line-height: var(--lh-h);
  color: var(--text);
  margin: var(--s-3) 0 0;
  transition: color var(--d-1) var(--ease-hover);
}
.p-blog .serp-card:hover .serp-title{ color: var(--accent-text); }

.p-blog .serp-dek{
  color: var(--text-2);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  margin: var(--s-2) 0 0;
  max-width: 64ch;
}

.p-blog .jitem-meta{
  display: flex;
  align-items: center;
  gap: var(--s-2) var(--s-4);
  flex-wrap: wrap;
  margin: var(--s-4) 0 0;
}
.p-blog .jitem-more{
  margin-left: auto;
  font-family: var(--f-body);
  font-size: var(--t-micro-2);
  font-weight: var(--w-medium);
  color: var(--accent-text);
  position: relative;
}
.p-blog .jitem-more::after{
  content: "→";
  margin-left: var(--s-2);
  display: inline-block;
  transition: transform var(--d-2) var(--ease-hover);
}
.p-blog .serp-card:hover .jitem-more::after{ transform: translateX(4px); }

/* ---- closing CTA ---- */
.p-blog .blog-cta-in{
  display: grid;
  gap: var(--s-5);
  margin-top: var(--s-6);
}
.p-blog .blog-cta-line{
  font-family: var(--f-display);
  font-size: var(--t-h1);
  line-height: var(--lh-h);
  letter-spacing: -0.01em;
  max-width: 20ch;
}
.p-blog .blog-cta-act{ max-width: var(--prose); display: grid; gap: var(--s-4); }

@media (min-width: 900px){
  .p-blog .blog-cta-in{ grid-template-columns: 1fr 1fr; align-items: start; gap: var(--s-7); }
}


/* ===== css/pages/blogpost.css ===== */
/* ===== css/pages/blogpost.css — Journal post (key "blogpost", scoped .p-blogpost)
   Owner: seo-longtail. Binds only to shared semantic tokens. Editorial long-read
   rhythm + a quiet SERP-card preview as the hero visual (typographic, S$0). The
   in-copy link styling here is load-bearing: base.css strips link decoration, so
   prose links must be made visibly clickable or the internal mesh reads as plain
   text to a human. ===== */

/* ---- header ---- */
.p-blogpost .post-title{
  font-family: var(--f-display);
  font-size: var(--t-display);
  line-height: var(--lh-display);
  letter-spacing: -0.01em;
  max-width: 20ch;
  margin: var(--s-4) 0 0;
}
.p-blogpost .post-lede{ margin-top: var(--s-4); }
.p-blogpost .post-meta{
  display: flex;
  align-items: center;
  gap: var(--s-2) var(--s-4);
  flex-wrap: wrap;
  margin-top: var(--s-5);
}

/* ---- SERP-card preview (hero) ---- */
.p-blogpost .post-serp-wrap .wrap{ max-width: 760px; }
.p-blogpost .serp-card--post{
  padding: var(--s-5);
  background: var(--surface-2);
  border: 1px solid var(--rule);
  border-radius: 8px;
  max-width: 100%;
  overflow: hidden;
}
.p-blogpost .serp-card--post .serp-url{
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 var(--s-2);
  max-width: 100%;
  font-family: var(--f-body);
  font-size: var(--t-micro-2);
  line-height: 1.4;
}
.p-blogpost .serp-card--post .serp-fav{
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent-text); flex: 0 0 auto;
}
.p-blogpost .serp-card--post .serp-site{ color: var(--text-2); font-weight: var(--w-medium); }
.p-blogpost .serp-card--post .serp-path{
  color: var(--accent-text);
  flex: 1 1 100%; min-width: 0; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.p-blogpost .serp-card--post .serp-title{
  font-family: var(--f-display);
  font-size: var(--t-h3);
  line-height: var(--lh-h);
  color: var(--text);
  margin: var(--s-3) 0 0;
}
.p-blogpost .serp-card--post .serp-dek{
  color: var(--text-2);
  font-size: var(--t-small);
  line-height: var(--lh-body);
  margin: var(--s-2) 0 0;
}

/* ---- prose ---- */
.p-blogpost .post-prose{ margin-top: var(--s-4); }
.p-blogpost .post-prose > .lede:first-child{ margin-bottom: var(--s-5); }

.p-blogpost .post-prose h2{
  font-family: var(--f-display);
  font-size: var(--t-h1);
  line-height: var(--lh-h);
  letter-spacing: -0.01em;
  color: var(--text);
  margin: var(--s-7) 0 var(--s-3);
  max-width: 26ch;
}
.p-blogpost .post-prose h3{
  font-family: var(--f-display);
  font-size: var(--t-h3);
  line-height: var(--lh-h);
  color: var(--text);
  margin: var(--s-6) 0 var(--s-2);
}
.p-blogpost .post-prose p{
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--text-2);
}
.p-blogpost .post-prose p + p{ margin-top: var(--s-4); }

/* in-copy links — visibly clickable (the internal mesh) */
.p-blogpost .post-prose a{
  color: var(--accent-text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  text-decoration-color: var(--rule-stone);
  transition: text-decoration-color var(--d-1) var(--ease-hover),
              color var(--d-1) var(--ease-hover);
}
.p-blogpost .post-prose a:hover{ text-decoration-color: var(--accent-text); }
.p-blogpost .post-prose a:focus-visible{
  outline: 2px solid var(--accent-text);
  outline-offset: 2px;
  border-radius: 2px;
}
.p-blogpost .post-prose strong{ color: var(--text); font-weight: var(--w-medium); }
.p-blogpost .post-prose em{ color: var(--accent-text); font-style: italic; }

/* ordered lists */
.p-blogpost .post-prose .prose-ol{
  margin: var(--s-4) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: seo-ol;
}
.p-blogpost .post-prose .prose-ol li{
  position: relative;
  padding-left: var(--s-7);
  margin-top: var(--s-4);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--text-2);
}
.p-blogpost .post-prose .prose-ol li::before{
  counter-increment: seo-ol;
  content: counter(seo-ol);
  position: absolute;
  left: 0;
  top: 0.1em;
  font-family: var(--f-display);
  font-size: var(--t-h3);
  line-height: 1;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}

/* pullquote */
.p-blogpost .post-prose .pullquote{
  margin: var(--s-7) 0;
  padding: 0 0 0 var(--s-5);
  border-left: 3px solid var(--accent-text);
  max-width: 100%;
}
.p-blogpost .post-prose .pullquote p{
  font-family: var(--f-display);
  font-size: var(--t-h2);
  line-height: var(--lh-h);
  color: var(--text);
  letter-spacing: -0.005em;
}

/* ---- foot ---- */
.p-blogpost .post-foot{ margin-top: var(--s-7); max-width: var(--prose); }
.p-blogpost .post-foot .rule{ margin-bottom: var(--s-5); }
.p-blogpost .post-note{
  font-size: var(--t-small);
  line-height: var(--lh-body);
  margin-bottom: var(--s-5);
}

/* ---- post-to-post nav ---- */
.p-blogpost .post-nav-row{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  margin-top: var(--s-5);
}
.p-blogpost .post-nav-item{
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-4);
  border: 1px solid var(--rule);
  border-radius: 8px;
  transition: border-color var(--d-2) var(--ease-hover);
}
.p-blogpost .post-nav-item:hover{ border-color: var(--accent-text); }
.p-blogpost .post-nav-item--next{ text-align: right; align-items: flex-end; }
.p-blogpost .post-nav-title{
  font-family: var(--f-display);
  font-size: var(--t-h3);
  line-height: var(--lh-h);
  color: var(--text);
}
.p-blogpost .post-nav-all{ margin-top: var(--s-5); }

@media (min-width: 760px){
  .p-blogpost .post-nav-row{ grid-template-columns: 1fr 1fr; }
}


/* ===== css/pages/case-arowana.css ===== */
/* ===== case study page — scoped .p-case-arowana ===== */

/* ---- hero: the rank number as the subject, the story alongside ---- */
.p-case-arowana .case-hero-grid{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  align-items: center;
}
@media (min-width: 820px){
  .p-case-arowana .case-hero-grid{
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.5fr);
    column-gap: clamp(2rem, 5vw, 4.5rem);
  }
}
.p-case-arowana .case-hero-figure{ display: flex; flex-direction: column; gap: var(--s-2); }
.p-case-arowana .case-hero-from{ display: inline-flex; align-items: baseline; gap: .4em; color: var(--text-3); }
.p-case-arowana .case-hero-from .num{ font-family: var(--f-display); font-size: var(--t-h2); text-decoration: line-through; text-decoration-thickness: 1px; }
.p-case-arowana .case-hero-n{ font-size: clamp(4.5rem, 3rem + 10vw, 9.5rem); }
.p-case-arowana .case-hero-figure--peak .case-hero-n{ color: var(--accent-text); }
.p-case-arowana .case-hero-kw{ display: block; margin-top: var(--s-1); }
.p-case-arowana .case-hero-lead{ display: flex; flex-direction: column; gap: var(--s-4); }
.p-case-arowana .case-hero-lead h1{ margin: 0; }
.p-case-arowana .case-hero-client{ color: var(--text-3); }
.p-case-arowana .case-hero-lead .btns{ margin-top: var(--s-2); }

/* ---- serp: the live result as a design object (base .serp-card) + a query bar ---- */
.p-case-arowana .case-serp-bar{
  display: inline-flex; align-items: center; gap: var(--s-3);
  margin-bottom: var(--s-4);
  padding: var(--s-3) var(--s-5);
  border: 1px solid var(--rule-2); border-radius: 999px;
  background: var(--surface); box-shadow: var(--sh-1); max-width: 100%;
}
.p-case-arowana .case-serp-ic{ width: 18px; height: 18px; flex: none; color: var(--text-3); }
.p-case-arowana .case-serp-q{ font-size: var(--t-small); color: var(--text-2); overflow-wrap: anywhere; }
.p-case-arowana .serp-cap{ margin-top: var(--s-4); color: var(--text-3); }

/* rankline — for the withheld / no-URL cases (jxc, claw); harmless where unused */
.p-case-arowana .case-rankline{ display: flex; align-items: center; gap: var(--s-4); padding: var(--s-5) 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.p-case-arowana .case-rankline-badge{ font-family: var(--f-display); font-weight: var(--w-display); font-size: clamp(2.5rem, 7vw, 4rem); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; display: inline-flex; align-items: flex-start; }
.p-case-arowana .case-rankline-badge .rung-hash{ font-size: .4em; color: var(--text-3); margin-top: .4em; }
.p-case-arowana .case-rankline-text{ font-size: var(--t-h3); font-family: var(--f-display); color: var(--text); line-height: 1.25; }
.p-case-arowana .case-rankline--withheld{ border-style: dashed; }

/* ---- context: head | body, editorial two-column ---- */
.p-case-arowana .case-context-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-5); }
@media (min-width: 860px){
  .p-case-arowana .case-context-grid{ grid-template-columns: 0.8fr 1.2fr; column-gap: clamp(2rem, 5vw, 4.5rem); }
}
.p-case-arowana .case-context-head h2{ margin: var(--s-3) 0 0; max-width: 14ch; }
.p-case-arowana .case-context-body p + p{ margin-top: var(--s-4); }

/* ---- work: numbered steps, big index numerals ---- */
.p-case-arowana .case-work-head{ margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.p-case-arowana .case-work-head h2{ margin: var(--s-3) 0 0; }
.p-case-arowana .case-steps{ display: flex; flex-direction: column; gap: 0; }
.p-case-arowana .case-step{ display: grid; grid-template-columns: auto 1fr; column-gap: clamp(1.25rem, 4vw, 3rem); align-items: start; padding: var(--s-5) 0; border-top: 1px solid var(--rule); }
.p-case-arowana .case-step:last-child{ border-bottom: 1px solid var(--rule); }
.p-case-arowana .case-step-n{ font-family: var(--f-display); font-weight: var(--w-display); font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; }
.p-case-arowana .case-step-body h3{ margin: 0 0 var(--s-2); }
.p-case-arowana .case-step-body p{ color: var(--text-3); max-width: 62ch; }

/* ---- result: the ink island — final position + the payoff ---- */
.p-case-arowana .case-result-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-6); align-items: center; }
@media (min-width: 860px){
  .p-case-arowana .case-result-grid{ grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.4fr); column-gap: clamp(2rem, 5vw, 4.5rem); }
}
.p-case-arowana .case-result-figure{ display: flex; flex-direction: column; gap: var(--s-2); }
.p-case-arowana .case-result-label{ display: block; }
.p-case-arowana .case-result-n{ font-size: clamp(4rem, 3rem + 9vw, 8.5rem); }
.p-case-arowana .case-result-delta{ color: var(--text-3); }
.p-case-arowana .case-result-body{ display: flex; flex-direction: column; gap: var(--s-3); }
.p-case-arowana .case-result-body h2{ margin: 0; max-width: var(--m-state); }
.p-case-arowana .case-result-stat{ margin-top: var(--s-2); font-family: var(--f-display); font-size: var(--t-h3); color: var(--text); }
.p-case-arowana .case-result-stat .num{ color: var(--accent-text); }

/* ---- closing cta + sibling case nav ---- */
.p-case-arowana .case-cta h2{ max-width: 22ch; }
.p-case-arowana .case-more{ margin-top: clamp(2.5rem, 6vw, 4.5rem); }
.p-case-arowana .case-more-h{ color: var(--text-3); margin: var(--s-4) 0 var(--s-3); }
.p-case-arowana .case-more-row{ display: grid; grid-template-columns: 1fr; gap: var(--s-3); }
@media (min-width: 720px){ .p-case-arowana .case-more-row{ grid-template-columns: repeat(3, 1fr); } }
.p-case-arowana .case-more-item{ display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-4); border: 1px solid var(--rule); border-radius: 10px; transition: border-color var(--d-2) var(--ease-hover), transform var(--d-2) var(--ease-hover); }
.p-case-arowana .case-more-item:hover{ border-color: var(--accent-text); transform: translateY(-2px); }
.p-case-arowana .case-more-rank{ font-family: var(--f-display); font-weight: var(--w-display); font-size: var(--t-h2); color: var(--accent-text); font-variant-numeric: tabular-nums; }
.p-case-arowana .case-more-t{ color: var(--text-2); font-size: var(--t-small); }
.p-case-arowana .case-more-all{ margin-top: var(--s-4); }


/* ===== css/pages/case-claw.css ===== */
/* ===== case study page — scoped .p-case-claw ===== */

/* ---- hero: the rank number as the subject, the story alongside ---- */
.p-case-claw .case-hero-grid{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  align-items: center;
}
@media (min-width: 820px){
  .p-case-claw .case-hero-grid{
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.5fr);
    column-gap: clamp(2rem, 5vw, 4.5rem);
  }
}
.p-case-claw .case-hero-figure{ display: flex; flex-direction: column; gap: var(--s-2); }
.p-case-claw .case-hero-from{ display: inline-flex; align-items: baseline; gap: .4em; color: var(--text-3); }
.p-case-claw .case-hero-from .num{ font-family: var(--f-display); font-size: var(--t-h2); text-decoration: line-through; text-decoration-thickness: 1px; }
.p-case-claw .case-hero-n{ font-size: clamp(4.5rem, 3rem + 10vw, 9.5rem); }
.p-case-claw .case-hero-figure--peak .case-hero-n{ color: var(--accent-text); }
.p-case-claw .case-hero-kw{ display: block; margin-top: var(--s-1); }
.p-case-claw .case-hero-lead{ display: flex; flex-direction: column; gap: var(--s-4); }
.p-case-claw .case-hero-lead h1{ margin: 0; }
.p-case-claw .case-hero-client{ color: var(--text-3); }
.p-case-claw .case-hero-lead .btns{ margin-top: var(--s-2); }

/* ---- serp: the live result as a design object (base .serp-card) + a query bar ---- */
.p-case-claw .case-serp-bar{
  display: inline-flex; align-items: center; gap: var(--s-3);
  margin-bottom: var(--s-4);
  padding: var(--s-3) var(--s-5);
  border: 1px solid var(--rule-2); border-radius: 999px;
  background: var(--surface); box-shadow: var(--sh-1); max-width: 100%;
}
.p-case-claw .case-serp-ic{ width: 18px; height: 18px; flex: none; color: var(--text-3); }
.p-case-claw .case-serp-q{ font-size: var(--t-small); color: var(--text-2); overflow-wrap: anywhere; }
.p-case-claw .serp-cap{ margin-top: var(--s-4); color: var(--text-3); }

/* rankline — for the withheld / no-URL cases (jxc, claw); harmless where unused */
.p-case-claw .case-rankline{ display: flex; align-items: center; gap: var(--s-4); padding: var(--s-5) 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.p-case-claw .case-rankline-badge{ font-family: var(--f-display); font-weight: var(--w-display); font-size: clamp(2.5rem, 7vw, 4rem); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; display: inline-flex; align-items: flex-start; }
.p-case-claw .case-rankline-badge .rung-hash{ font-size: .4em; color: var(--text-3); margin-top: .4em; }
.p-case-claw .case-rankline-text{ font-size: var(--t-h3); font-family: var(--f-display); color: var(--text); line-height: 1.25; }
.p-case-claw .case-rankline--withheld{ border-style: dashed; }

/* ---- context: head | body, editorial two-column ---- */
.p-case-claw .case-context-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-5); }
@media (min-width: 860px){
  .p-case-claw .case-context-grid{ grid-template-columns: 0.8fr 1.2fr; column-gap: clamp(2rem, 5vw, 4.5rem); }
}
.p-case-claw .case-context-head h2{ margin: var(--s-3) 0 0; max-width: 14ch; }
.p-case-claw .case-context-body p + p{ margin-top: var(--s-4); }

/* ---- work: numbered steps, big index numerals ---- */
.p-case-claw .case-work-head{ margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.p-case-claw .case-work-head h2{ margin: var(--s-3) 0 0; }
.p-case-claw .case-steps{ display: flex; flex-direction: column; gap: 0; }
.p-case-claw .case-step{ display: grid; grid-template-columns: auto 1fr; column-gap: clamp(1.25rem, 4vw, 3rem); align-items: start; padding: var(--s-5) 0; border-top: 1px solid var(--rule); }
.p-case-claw .case-step:last-child{ border-bottom: 1px solid var(--rule); }
.p-case-claw .case-step-n{ font-family: var(--f-display); font-weight: var(--w-display); font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; }
.p-case-claw .case-step-body h3{ margin: 0 0 var(--s-2); }
.p-case-claw .case-step-body p{ color: var(--text-3); max-width: 62ch; }

/* ---- result: the ink island — final position + the payoff ---- */
.p-case-claw .case-result-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-6); align-items: center; }
@media (min-width: 860px){
  .p-case-claw .case-result-grid{ grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.4fr); column-gap: clamp(2rem, 5vw, 4.5rem); }
}
.p-case-claw .case-result-figure{ display: flex; flex-direction: column; gap: var(--s-2); }
.p-case-claw .case-result-label{ display: block; }
.p-case-claw .case-result-n{ font-size: clamp(4rem, 3rem + 9vw, 8.5rem); }
.p-case-claw .case-result-delta{ color: var(--text-3); }
.p-case-claw .case-result-body{ display: flex; flex-direction: column; gap: var(--s-3); }
.p-case-claw .case-result-body h2{ margin: 0; max-width: var(--m-state); }
.p-case-claw .case-result-stat{ margin-top: var(--s-2); font-family: var(--f-display); font-size: var(--t-h3); color: var(--text); }
.p-case-claw .case-result-stat .num{ color: var(--accent-text); }

/* ---- closing cta + sibling case nav ---- */
.p-case-claw .case-cta h2{ max-width: 22ch; }
.p-case-claw .case-more{ margin-top: clamp(2.5rem, 6vw, 4.5rem); }
.p-case-claw .case-more-h{ color: var(--text-3); margin: var(--s-4) 0 var(--s-3); }
.p-case-claw .case-more-row{ display: grid; grid-template-columns: 1fr; gap: var(--s-3); }
@media (min-width: 720px){ .p-case-claw .case-more-row{ grid-template-columns: repeat(3, 1fr); } }
.p-case-claw .case-more-item{ display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-4); border: 1px solid var(--rule); border-radius: 10px; transition: border-color var(--d-2) var(--ease-hover), transform var(--d-2) var(--ease-hover); }
.p-case-claw .case-more-item:hover{ border-color: var(--accent-text); transform: translateY(-2px); }
.p-case-claw .case-more-rank{ font-family: var(--f-display); font-weight: var(--w-display); font-size: var(--t-h2); color: var(--accent-text); font-variant-numeric: tabular-nums; }
.p-case-claw .case-more-t{ color: var(--text-2); font-size: var(--t-small); }
.p-case-claw .case-more-all{ margin-top: var(--s-4); }


/* ===== css/pages/case-fuelinc.css ===== */
/* ===== case study page — scoped .p-case-fuelinc ===== */

/* ---- hero: the rank number as the subject, the story alongside ---- */
.p-case-fuelinc .case-hero-grid{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  align-items: center;
}
@media (min-width: 820px){
  .p-case-fuelinc .case-hero-grid{
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.5fr);
    column-gap: clamp(2rem, 5vw, 4.5rem);
  }
}
.p-case-fuelinc .case-hero-figure{ display: flex; flex-direction: column; gap: var(--s-2); }
.p-case-fuelinc .case-hero-from{ display: inline-flex; align-items: baseline; gap: .4em; color: var(--text-3); }
.p-case-fuelinc .case-hero-from .num{ font-family: var(--f-display); font-size: var(--t-h2); text-decoration: line-through; text-decoration-thickness: 1px; }
.p-case-fuelinc .case-hero-n{ font-size: clamp(4.5rem, 3rem + 10vw, 9.5rem); }
.p-case-fuelinc .case-hero-figure--peak .case-hero-n{ color: var(--accent-text); }
.p-case-fuelinc .case-hero-kw{ display: block; margin-top: var(--s-1); }
.p-case-fuelinc .case-hero-lead{ display: flex; flex-direction: column; gap: var(--s-4); }
.p-case-fuelinc .case-hero-lead h1{ margin: 0; }
.p-case-fuelinc .case-hero-client{ color: var(--text-3); }
.p-case-fuelinc .case-hero-lead .btns{ margin-top: var(--s-2); }

/* ---- serp: the live result as a design object (base .serp-card) + a query bar ---- */
.p-case-fuelinc .case-serp-bar{
  display: inline-flex; align-items: center; gap: var(--s-3);
  margin-bottom: var(--s-4);
  padding: var(--s-3) var(--s-5);
  border: 1px solid var(--rule-2); border-radius: 999px;
  background: var(--surface); box-shadow: var(--sh-1); max-width: 100%;
}
.p-case-fuelinc .case-serp-ic{ width: 18px; height: 18px; flex: none; color: var(--text-3); }
.p-case-fuelinc .case-serp-q{ font-size: var(--t-small); color: var(--text-2); overflow-wrap: anywhere; }
.p-case-fuelinc .serp-cap{ margin-top: var(--s-4); color: var(--text-3); }

/* rankline — for the withheld / no-URL cases (jxc, claw); harmless where unused */
.p-case-fuelinc .case-rankline{ display: flex; align-items: center; gap: var(--s-4); padding: var(--s-5) 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.p-case-fuelinc .case-rankline-badge{ font-family: var(--f-display); font-weight: var(--w-display); font-size: clamp(2.5rem, 7vw, 4rem); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; display: inline-flex; align-items: flex-start; }
.p-case-fuelinc .case-rankline-badge .rung-hash{ font-size: .4em; color: var(--text-3); margin-top: .4em; }
.p-case-fuelinc .case-rankline-text{ font-size: var(--t-h3); font-family: var(--f-display); color: var(--text); line-height: 1.25; }
.p-case-fuelinc .case-rankline--withheld{ border-style: dashed; }

/* ---- context: head | body, editorial two-column ---- */
.p-case-fuelinc .case-context-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-5); }
@media (min-width: 860px){
  .p-case-fuelinc .case-context-grid{ grid-template-columns: 0.8fr 1.2fr; column-gap: clamp(2rem, 5vw, 4.5rem); }
}
.p-case-fuelinc .case-context-head h2{ margin: var(--s-3) 0 0; max-width: 14ch; }
.p-case-fuelinc .case-context-body p + p{ margin-top: var(--s-4); }

/* ---- work: numbered steps, big index numerals ---- */
.p-case-fuelinc .case-work-head{ margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.p-case-fuelinc .case-work-head h2{ margin: var(--s-3) 0 0; }
.p-case-fuelinc .case-steps{ display: flex; flex-direction: column; gap: 0; }
.p-case-fuelinc .case-step{ display: grid; grid-template-columns: auto 1fr; column-gap: clamp(1.25rem, 4vw, 3rem); align-items: start; padding: var(--s-5) 0; border-top: 1px solid var(--rule); }
.p-case-fuelinc .case-step:last-child{ border-bottom: 1px solid var(--rule); }
.p-case-fuelinc .case-step-n{ font-family: var(--f-display); font-weight: var(--w-display); font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; }
.p-case-fuelinc .case-step-body h3{ margin: 0 0 var(--s-2); }
.p-case-fuelinc .case-step-body p{ color: var(--text-3); max-width: 62ch; }

/* ---- result: the ink island — final position + the payoff ---- */
.p-case-fuelinc .case-result-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-6); align-items: center; }
@media (min-width: 860px){
  .p-case-fuelinc .case-result-grid{ grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.4fr); column-gap: clamp(2rem, 5vw, 4.5rem); }
}
.p-case-fuelinc .case-result-figure{ display: flex; flex-direction: column; gap: var(--s-2); }
.p-case-fuelinc .case-result-label{ display: block; }
.p-case-fuelinc .case-result-n{ font-size: clamp(4rem, 3rem + 9vw, 8.5rem); }
.p-case-fuelinc .case-result-delta{ color: var(--text-3); }
.p-case-fuelinc .case-result-body{ display: flex; flex-direction: column; gap: var(--s-3); }
.p-case-fuelinc .case-result-body h2{ margin: 0; max-width: var(--m-state); }
.p-case-fuelinc .case-result-stat{ margin-top: var(--s-2); font-family: var(--f-display); font-size: var(--t-h3); color: var(--text); }
.p-case-fuelinc .case-result-stat .num{ color: var(--accent-text); }

/* ---- closing cta + sibling case nav ---- */
.p-case-fuelinc .case-cta h2{ max-width: 22ch; }
.p-case-fuelinc .case-more{ margin-top: clamp(2.5rem, 6vw, 4.5rem); }
.p-case-fuelinc .case-more-h{ color: var(--text-3); margin: var(--s-4) 0 var(--s-3); }
.p-case-fuelinc .case-more-row{ display: grid; grid-template-columns: 1fr; gap: var(--s-3); }
@media (min-width: 720px){ .p-case-fuelinc .case-more-row{ grid-template-columns: repeat(3, 1fr); } }
.p-case-fuelinc .case-more-item{ display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-4); border: 1px solid var(--rule); border-radius: 10px; transition: border-color var(--d-2) var(--ease-hover), transform var(--d-2) var(--ease-hover); }
.p-case-fuelinc .case-more-item:hover{ border-color: var(--accent-text); transform: translateY(-2px); }
.p-case-fuelinc .case-more-rank{ font-family: var(--f-display); font-weight: var(--w-display); font-size: var(--t-h2); color: var(--accent-text); font-variant-numeric: tabular-nums; }
.p-case-fuelinc .case-more-t{ color: var(--text-2); font-size: var(--t-small); }
.p-case-fuelinc .case-more-all{ margin-top: var(--s-4); }


/* ===== css/pages/case-jxc.css ===== */
/* ===== case study page — scoped .p-case-jxc ===== */

/* ---- hero: the rank number as the subject, the story alongside ---- */
.p-case-jxc .case-hero-grid{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-5);
  align-items: center;
}
@media (min-width: 820px){
  .p-case-jxc .case-hero-grid{
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.5fr);
    column-gap: clamp(2rem, 5vw, 4.5rem);
  }
}
.p-case-jxc .case-hero-figure{ display: flex; flex-direction: column; gap: var(--s-2); }
.p-case-jxc .case-hero-from{ display: inline-flex; align-items: baseline; gap: .4em; color: var(--text-3); }
.p-case-jxc .case-hero-from .num{ font-family: var(--f-display); font-size: var(--t-h2); text-decoration: line-through; text-decoration-thickness: 1px; }
.p-case-jxc .case-hero-n{ font-size: clamp(4.5rem, 3rem + 10vw, 9.5rem); }
.p-case-jxc .case-hero-figure--peak .case-hero-n{ color: var(--accent-text); }
.p-case-jxc .case-hero-kw{ display: block; margin-top: var(--s-1); }
.p-case-jxc .case-hero-lead{ display: flex; flex-direction: column; gap: var(--s-4); }
.p-case-jxc .case-hero-lead h1{ margin: 0; }
.p-case-jxc .case-hero-client{ color: var(--text-3); }
.p-case-jxc .case-hero-lead .btns{ margin-top: var(--s-2); }

/* ---- serp: the live result as a design object (base .serp-card) + a query bar ---- */
.p-case-jxc .case-serp-bar{
  display: inline-flex; align-items: center; gap: var(--s-3);
  margin-bottom: var(--s-4);
  padding: var(--s-3) var(--s-5);
  border: 1px solid var(--rule-2); border-radius: 999px;
  background: var(--surface); box-shadow: var(--sh-1); max-width: 100%;
}
.p-case-jxc .case-serp-ic{ width: 18px; height: 18px; flex: none; color: var(--text-3); }
.p-case-jxc .case-serp-q{ font-size: var(--t-small); color: var(--text-2); overflow-wrap: anywhere; }
.p-case-jxc .serp-cap{ margin-top: var(--s-4); color: var(--text-3); }

/* rankline — for the withheld / no-URL cases (jxc, claw); harmless where unused */
.p-case-jxc .case-rankline{ display: flex; align-items: center; gap: var(--s-4); padding: var(--s-5) 0; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.p-case-jxc .case-rankline-badge{ font-family: var(--f-display); font-weight: var(--w-display); font-size: clamp(2.5rem, 7vw, 4rem); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; display: inline-flex; align-items: flex-start; }
.p-case-jxc .case-rankline-badge .rung-hash{ font-size: .4em; color: var(--text-3); margin-top: .4em; }
.p-case-jxc .case-rankline-text{ font-size: var(--t-h3); font-family: var(--f-display); color: var(--text); line-height: 1.25; }
.p-case-jxc .case-rankline--withheld{ border-style: dashed; }

/* ---- context: head | body, editorial two-column ---- */
.p-case-jxc .case-context-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-5); }
@media (min-width: 860px){
  .p-case-jxc .case-context-grid{ grid-template-columns: 0.8fr 1.2fr; column-gap: clamp(2rem, 5vw, 4.5rem); }
}
.p-case-jxc .case-context-head h2{ margin: var(--s-3) 0 0; max-width: 14ch; }
.p-case-jxc .case-context-body p + p{ margin-top: var(--s-4); }

/* ---- work: numbered steps, big index numerals ---- */
.p-case-jxc .case-work-head{ margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.p-case-jxc .case-work-head h2{ margin: var(--s-3) 0 0; }
.p-case-jxc .case-steps{ display: flex; flex-direction: column; gap: 0; }
.p-case-jxc .case-step{ display: grid; grid-template-columns: auto 1fr; column-gap: clamp(1.25rem, 4vw, 3rem); align-items: start; padding: var(--s-5) 0; border-top: 1px solid var(--rule); }
.p-case-jxc .case-step:last-child{ border-bottom: 1px solid var(--rule); }
.p-case-jxc .case-step-n{ font-family: var(--f-display); font-weight: var(--w-display); font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1; color: var(--accent-text); font-variant-numeric: tabular-nums; }
.p-case-jxc .case-step-body h3{ margin: 0 0 var(--s-2); }
.p-case-jxc .case-step-body p{ color: var(--text-3); max-width: 62ch; }

/* ---- result: the ink island — final position + the payoff ---- */
.p-case-jxc .case-result-grid{ display: grid; grid-template-columns: 1fr; gap: var(--s-6); align-items: center; }
@media (min-width: 860px){
  .p-case-jxc .case-result-grid{ grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.4fr); column-gap: clamp(2rem, 5vw, 4.5rem); }
}
.p-case-jxc .case-result-figure{ display: flex; flex-direction: column; gap: var(--s-2); }
.p-case-jxc .case-result-label{ display: block; }
.p-case-jxc .case-result-n{ font-size: clamp(4rem, 3rem + 9vw, 8.5rem); }
.p-case-jxc .case-result-delta{ color: var(--text-3); }
.p-case-jxc .case-result-body{ display: flex; flex-direction: column; gap: var(--s-3); }
.p-case-jxc .case-result-body h2{ margin: 0; max-width: var(--m-state); }
.p-case-jxc .case-result-stat{ margin-top: var(--s-2); font-family: var(--f-display); font-size: var(--t-h3); color: var(--text); }
.p-case-jxc .case-result-stat .num{ color: var(--accent-text); }

/* ---- closing cta + sibling case nav ---- */
.p-case-jxc .case-cta h2{ max-width: 22ch; }
.p-case-jxc .case-more{ margin-top: clamp(2.5rem, 6vw, 4.5rem); }
.p-case-jxc .case-more-h{ color: var(--text-3); margin: var(--s-4) 0 var(--s-3); }
.p-case-jxc .case-more-row{ display: grid; grid-template-columns: 1fr; gap: var(--s-3); }
@media (min-width: 720px){ .p-case-jxc .case-more-row{ grid-template-columns: repeat(3, 1fr); } }
.p-case-jxc .case-more-item{ display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-4); border: 1px solid var(--rule); border-radius: 10px; transition: border-color var(--d-2) var(--ease-hover), transform var(--d-2) var(--ease-hover); }
.p-case-jxc .case-more-item:hover{ border-color: var(--accent-text); transform: translateY(-2px); }
.p-case-jxc .case-more-rank{ font-family: var(--f-display); font-weight: var(--w-display); font-size: var(--t-h2); color: var(--accent-text); font-variant-numeric: tabular-nums; }
.p-case-jxc .case-more-t{ color: var(--text-2); font-size: var(--t-small); }
.p-case-jxc .case-more-all{ margin-top: var(--s-4); }


/* ===== css/pages/cases.css ===== */
/* ===== cases (hub) — scoped .p-cases ===== */

/* hero: oversized statement left, the argument right. Not centred. */
.p-cases .cases-hero-grid{
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
}
@media (min-width: 900px){
  .p-cases .cases-hero-grid{
    grid-template-columns: 1.15fr 0.85fr;
    align-items: end;
    column-gap: clamp(2rem, 5vw, 5rem);
  }
}
.p-cases .cases-hero-grid h1{ margin: 0; }
.p-cases .cases-hero-aside{ display: flex; flex-direction: column; gap: var(--s-4); max-width: 46ch; }
.p-cases .cases-hero-aside .btns{ margin-top: var(--s-2); }

/* the ladder is the centrepiece — give it room and let base .rank-ladder/.rung carry it */
.p-cases .cases-ladder{ padding-top: var(--s-6); padding-bottom: var(--space-section); }
.p-cases .cases-ladder-head{ margin-bottom: clamp(2.5rem, 6vw, 5rem); }
.p-cases .cases-ladder-head .statement{ max-width: var(--m-state); }
/* hub numerals a touch grander than the home proof strip — this is the monument */
.p-cases .cases-ladder .rung-n{ font-size: clamp(4.5rem, 3rem + 12vw, 13rem); }
.p-cases .cases-ladder .rung--peak .rung-n{ color: var(--accent-text); }
.p-cases .cases-ladder .rung--peak .rung-kw{ color: var(--text); }

/* aggregate — the one ink island, the total as a monument */
.p-cases .cases-agg-inner{ text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--s-3); }
.p-cases .cases-agg-big{ display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: var(--s-2) var(--s-3); margin: 0; max-width: 100%; }
.p-cases .cases-agg-over{ color: var(--text-3); }
.p-cases .cases-agg-num{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: clamp(2.5rem, 1rem + 9vw, 9rem);
  line-height: .9;
  letter-spacing: -.02em;
  color: var(--accent-text);
  font-variant-numeric: lining-nums tabular-nums;
}
.p-cases .cases-agg-line{ max-width: 22ch; margin: 0; }
.p-cases .cases-agg-note{ max-width: 60ch; margin-top: var(--s-3); color: var(--text-3); }

/* closing cta */
.p-cases .cases-cta-foot{ margin-top: var(--s-5); color: var(--text-3); }


/* ===== css/pages/consultant.css ===== */
/* css/pages/consultant.css — seo-money. Scoped under .p-consultant (CONTRACT §4). Semantic-role tokens only.
   Signature serp-card + rank-ladder are canonical (base.css) — no component CSS here. */
.p-consultant .cn-hero-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3.5rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:900px){
.p-consultant .cn-hero-grid{ grid-template-columns:1.5fr .9fr; align-items:end; }
 
}
.p-consultant .cn-hero-note{ border-left:2px solid var(--accent-text); padding-left:1.25rem; align-self:end; }
.p-consultant .cn-hero-note p:not(.micro){ color:var(--text-2); font-size:1rem; line-height:1.6; margin-top:.5rem; max-width:32ch; }
.p-consultant .cn-why-head{ max-width:40ch; }
.p-consultant .cn-why-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:820px){
.p-consultant .cn-why-grid{ grid-template-columns:1fr 1fr; }
 
}
.p-consultant .cn-why-col p:not(.micro){ color:var(--text-2); max-width:52ch; margin-top:.5rem; }
.p-consultant .cn-why-l{ margin-bottom:.5rem; }
.p-consultant .cn-why-mode{ margin-top:clamp(1.5rem,1rem + 2vw,3rem); border-top:1px solid var(--rule); padding-top:clamp(1.5rem,1rem + 2vw,2.5rem); }
.p-consultant .cn-why-mode p:not(.micro){ color:var(--text-2); max-width:64ch; margin-top:.5rem; }
.p-consultant .wd-cta-grid{ display:grid; gap:clamp(2rem,1rem + 4vw,4rem); grid-template-columns:1fr; align-items:start; }
.p-consultant .wd-cta-proof-h{ margin-bottom:.75rem; color:var(--text-3); }
.p-consultant .svc-cta-line{ margin:0 0 clamp(1rem,.5rem + 2vw,2rem); }
.p-consultant .svc-cta-foot{ margin-top:1.25rem; color:var(--text-3); }
@media (min-width:900px){
.p-consultant .wd-cta-grid{ grid-template-columns:1.3fr .7fr; }
 
}


/* ===== css/pages/contact.css ===== */
/* css/pages/contact.css — seo-money. Scoped under .p-contact (CONTRACT §4). Semantic-role tokens only.
   Signature serp-card + rank-ladder are canonical (base.css) — no component CSS here. */
.p-contact .ct-form-grid{ display:grid; gap:clamp(2rem,1rem + 4vw,4rem); grid-template-columns:1fr; align-items:start; }
@media (min-width:900px){
.p-contact .ct-form-grid{ grid-template-columns:1.3fr .7fr; }
 
}
.p-contact .ct-form-head{ margin:.5rem 0 1.5rem; max-width:26ch; }
.p-contact .cform{ display:flex; flex-direction:column; gap:1.1rem; }
.p-contact .cfield{ display:flex; flex-direction:column; gap:.4rem; }
.p-contact .cfield-label{ color:var(--text-2); }
.p-contact .cfield-input{ font:inherit; color:var(--text); background:var(--surface); border:1px solid var(--rule); border-radius:8px; padding:.75rem .9rem; width:100%; }
.p-contact .cfield-input:focus-visible{ outline:2px solid var(--accent-text); outline-offset:1px; border-color:var(--accent-text); }
.p-contact .cfield-area{ resize:vertical; min-height:8rem; }
.p-contact .cfield-err{ color:var(--text-3); font-size:.85rem; }
.p-contact .cfield--trap{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
.p-contact .cform-status{ margin-top:.5rem; }
.p-contact .ct-side{ border-left:1px solid var(--rule); padding-left:clamp(1.25rem,1rem + 2vw,2.5rem); }
@media (max-width:900px){
.p-contact .ct-side{ border-left:0; padding-left:0; border-top:1px solid var(--rule); padding-top:2rem; }
 
}
.p-contact .ct-facts{ margin:1rem 0; }
.p-contact .ct-fact{ padding:.6rem 0; border-top:1px solid var(--rule); }
.p-contact .ct-fact dt{ color:var(--text-3); margin-bottom:.15rem; }
.p-contact .ct-fact dd{ color:var(--text); }
.p-contact .ct-side-next{ margin:1.5rem 0; }
.p-contact .ct-side-next p:not(.micro){ color:var(--text-2); font-size:.95rem; line-height:1.6; margin-top:.5rem; }
.p-contact .ct-side-proof{ margin:1.25rem 0; }


/* ===== css/pages/ecommerce.css ===== */
/* css/pages/ecommerce.css — seo-money. Scoped under .p-ecommerce (CONTRACT §4). Semantic-role tokens only.
   Signature serp-card + rank-ladder are canonical (base.css) — no component CSS here. */
.p-ecommerce .ec-hero-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3.5rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:900px){
.p-ecommerce .ec-hero-grid{ grid-template-columns:1.5fr .9fr; align-items:end; }
 
}
.p-ecommerce .ec-hero-note{ border-left:2px solid var(--accent-text); padding-left:1.25rem; align-self:end; }
.p-ecommerce .ec-hero-note p:not(.micro){ color:var(--text-2); font-size:1rem; line-height:1.6; margin-top:.5rem; max-width:32ch; }
.p-ecommerce .ls-list{ display:flex; flex-direction:column; }
.p-ecommerce .ls-item{ display:grid; grid-template-columns:1fr; gap:.5rem 2rem; padding:clamp(2rem,1.5rem + 3vw,4rem) 0; border-top:1px solid var(--rule); }
.p-ecommerce .ls-item:first-child{ border-top:0; }
.p-ecommerce .ls-n{ color:var(--accent-text); font-size:1rem; margin:0 0 .5rem; }
.p-ecommerce .ls-t{ margin:0 0 .75rem; }
.p-ecommerce .ls-body p{ color:var(--text-2); max-width:var(--prose,62ch); }
@media (min-width:820px){
.p-ecommerce .ls-item{ grid-template-columns:auto 1fr; gap:0 clamp(1.5rem,1rem + 3vw,4rem); }
 
}
.p-ecommerce .wd-cta-grid{ display:grid; gap:clamp(2rem,1rem + 4vw,4rem); grid-template-columns:1fr; align-items:start; }
.p-ecommerce .wd-cta-proof-h{ margin-bottom:.75rem; color:var(--text-3); }
.p-ecommerce .svc-cta-line{ margin:0 0 clamp(1rem,.5rem + 2vw,2rem); }
.p-ecommerce .svc-cta-foot{ margin-top:1.25rem; color:var(--text-3); }
@media (min-width:900px){
.p-ecommerce .wd-cta-grid{ grid-template-columns:1.3fr .7fr; }
 
}


/* ===== css/pages/home.css ===== */
/* css/pages/home.css — round 4 (eden-cube format layer). Scoped under .p-home
   (CONTRACT §4). The shared formats live in css/eden.css; this file keeps only
   the page glue plus the surviving proof components' layout: the serpshot grid,
   the process ledger and the six-month phases strip. Rank ladder + serp-card
   component CSS is canonical in base.css. */

/* ------------------------------------------------- stanza heads (eden) */
.p-home .home-proof-head{ max-width: 52rem; margin-bottom: clamp(2.6rem, 6vh, 4.5rem); }
.p-home .home-proof-head .eyebrow{ margin-bottom: 1.1rem; }
.p-home .home-proof-lede{ margin-top: 1.2rem; font-size: .9375rem; line-height: 1.6;
  color: var(--text-2); max-width: 40rem; }

/* the dimmed word inside a serif headline */
.p-home .h-l .dim{ color: var(--sweep-dim); }

/* ------------------------------------------------- manifesto (ink band) */
.p-home .home-manifesto{ padding-block: var(--space-section); }
.p-home .home-manifesto .eyebrow{ margin-bottom: 1.2rem; }
.p-home .home-manifesto-body{ margin-top: clamp(1.6rem, 4vh, 2.6rem); }
.p-home .home-manifesto-body p{ color: var(--text-2); line-height: 1.7; }
.p-home .home-manifesto-body p + p{ margin-top: 1.1rem; }
.p-home .home-manifesto .link-serif{ display: inline-block; margin-top: 1.6rem; }

/* ------------------------------------------------- SEO explainer (round 5) */
.p-home .home-explain .eyebrow{ margin-bottom: 1.1rem; }
.p-home .home-explain .h-m{ margin-bottom: 1.2rem; }
.p-home .home-explain-body{ font-size: var(--t-lede); line-height: 1.6;
  color: var(--text-2); max-width: 60ch; }

/* the also-links line under the services atab */
.p-home .home-services-more{ margin-top: 1.6rem; font-size: .9375rem; color: var(--text-3);
  text-align: center; }

/* ------------------------------------------- the Google snapshot (proof) */
.p-home .home-serpshot{
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2rem, 4.5vw, 4.5rem);
  align-items: center;
  margin-top: var(--space-section);
  padding-top: var(--space-block);
  border-top: 1px solid var(--rule);
}
.p-home .home-serpshot-copy h3{ max-width: 16ch; }
.p-home .home-serpshot-copy p{
  margin-top: var(--s-4);
  color: var(--text-3);
  line-height: 1.65;
  max-width: 44ch;
}
.p-home .home-serpshot-copy .link{ display: inline-block; margin-top: var(--s-5); }
.p-home .home-serpshot .serp-shot{ justify-self: end; width: 100%; }
@media (max-width: 900px){
  .p-home .home-serpshot{ grid-template-columns: 1fr; }
  .p-home .home-serpshot .serp-shot{ justify-self: start; }
}

/* --------------------------------------------------- process — the system */
.p-home .home-process-head{ max-width: 44ch; margin-bottom: var(--space-block); }
.p-home .home-process-head .eyebrow{ margin-bottom: 1.1rem; }
.p-home .home-process-head .lede{ margin-top: var(--s-5); }
.p-home .home-process-grid{
  display: grid;
  /* media gets the larger share (Charlie: bigger) — steps copy wraps at 56ch anyway */
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2.5rem, 5vw, 5.5rem);
  align-items: start;
}
.p-home .home-steps{ list-style: none; margin: 0; padding: 0; }
.p-home .home-step{
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: clamp(1.25rem, 2.6vw, 2.25rem);
  align-items: start;
  padding-block: var(--space-block);
  border-top: 1px solid var(--rule);
}
.p-home .home-steps .home-step:first-child{ border-top: 0; padding-top: 0; }
/* the step numeral — same family as the rank ladder, quieter register */
.p-home .home-step-n{
  font-family: var(--f-display);
  font-weight: var(--w-display);
  font-size: clamp(2.2rem, 1rem + 3vw, 3.2rem);
  line-height: 1;
  color: var(--accent-text);
  min-width: 2.1ch;
}
.p-home .home-step-body p{
  margin-top: var(--s-3);
  color: var(--text-3);
  line-height: 1.65;
  max-width: 56ch;
}
.p-home .home-step-body em{ color: var(--accent-text); }
.p-home .home-process-media{
  position: sticky;
  top: calc(var(--nav-h) + var(--s-6));
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  /* stays INSIDE the wrap — the viewport-edge bleed read as broken on wide
     monitors (Charlie 2026-07-30: too big, unaesthetic); 7fr is the size lever */
}
.p-home .home-process-media-note{ color: var(--text-3); max-width: 30ch; }
.p-home .home-proofshot{ display: block; }
.p-home .home-proofshot-cap{
  margin-top: var(--s-2);
  color: var(--text-3);
  transition: color var(--d-2) var(--ease-hover);
}
.p-home .home-proofshot:hover .home-proofshot-cap{ color: var(--accent-text); }
@media (max-width: 900px){
  .p-home .home-process-grid{ grid-template-columns: 1fr; }
  /* stacked full-width below the steps — two-up would shrink the receipts back
     into illegibility, which is the exact bug this block exists to fix */
  .p-home .home-process-media{ position: static; }
}

/* the six-month strip — three phases on one rule, honest by design */
.p-home .home-phases-block{
  margin-top: var(--space-section);
  padding-top: var(--space-block);
  border-top: 1px solid var(--rule);
}
.p-home .home-phases-h{ margin-bottom: var(--space-block); }
.p-home .home-phases{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3.4vw, 3rem);
}
.p-home .home-phase{
  padding-left: var(--s-5);
  border-left: 2px solid var(--rule-accent);
}
.p-home .home-phase-tag{
  font-size: var(--t-micro-2);
  font-weight: var(--w-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--accent-text);
}
.p-home .home-phase-list{ list-style: none; margin: var(--s-4) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-3); }
.p-home .home-phase-list li{
  position: relative;
  padding-left: var(--s-6);
  color: var(--text-2);
  font-size: var(--t-body);
  line-height: 1.55;
}
.p-home .home-phase-list li::before{
  content: "✓";
  position: absolute; left: 0; top: 0;
  color: var(--accent-text);
  font-weight: var(--w-semibold);
}
.p-home .home-phases-note{ margin-top: var(--space-block); color: var(--text-3); font-size: var(--t-small); }
@media (max-width: 720px){
  .p-home .home-phases{ grid-template-columns: 1fr; }
}

/* ------------------------------------------------- the journey (round 6)
   Recast in the canonical strategy-board object — component CSS in base.css;
   nothing page-specific left here. */

/* ------------------------------------------------- teaser + meet details */
/* full --text + weight 500, not --text-2/400 — dimmed thin strokes go murky over
   the skyline photo ("can't see" — Charlie 2026-07-29); armor (scrim/shadow) stays
   banned, legibility comes from colour + stroke weight */
.p-home .teaser-lede{ margin-top: 1.1rem; font-size: var(--t-body); line-height: 1.55;
  color: var(--text); font-weight: 500; max-width: 34rem; }
.p-home .teaser-guarantee{ margin-top: var(--s-4); font-size: var(--t-body);
  line-height: 1.5; color: var(--accent-text); }
.p-home .teaser-guarantee b{ font-weight: 600; }
.p-home .teaser-credit{ margin-top: 1.2rem; color: var(--text-3); }
.p-home .tcard-per{ font-size: .55em; color: var(--text-3); margin-left: .15em; }
.p-home .meet-note{ color: var(--text-3); }

/* ------------------------------------------------- answer engines (round 8)
   Citation-drivers grid — feat-grid--3 (eden); only head measure and the
   footer link margin are page business. */
.p-home .home-ai-head{ max-width: 52ch; }
.p-home .home-ai-head .lede{ margin-top: 1rem; }
.p-home .home-ai-more{ margin-top: clamp(1.75rem, 1.25rem + 1.5vw, 2.75rem); color: var(--text-3); }


/* ===== css/pages/localseo.css ===== */
/* css/pages/localseo.css — seo-money. Scoped under .p-localseo (CONTRACT §4). Semantic-role tokens only.
   Signature serp-card + rank-ladder are canonical (base.css) — no component CSS here. */
.p-localseo .ls-hero-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3.5rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:900px){
.p-localseo .ls-hero-grid{ grid-template-columns:1.5fr .9fr; align-items:end; }
 
}
.p-localseo .ls-hero-note{ border-left:2px solid var(--accent-text); padding-left:1.25rem; align-self:end; }
.p-localseo .ls-hero-note p:not(.micro){ color:var(--text-2); font-size:1rem; line-height:1.6; margin-top:.5rem; max-width:32ch; }
.p-localseo .ls-list{ display:flex; flex-direction:column; }
.p-localseo .ls-item{ display:grid; grid-template-columns:1fr; gap:.5rem 2rem; padding:clamp(2rem,1.5rem + 3vw,4rem) 0; border-top:1px solid var(--rule); }
.p-localseo .ls-item:first-child{ border-top:0; }
.p-localseo .ls-n{ color:var(--accent-text); font-size:1rem; margin:0 0 .5rem; }
.p-localseo .ls-t{ margin:0 0 .75rem; }
.p-localseo .ls-body p{ color:var(--text-2); max-width:var(--prose,62ch); }
@media (min-width:820px){
.p-localseo .ls-item{ grid-template-columns:auto 1fr; gap:0 clamp(1.5rem,1rem + 3vw,4rem); }
 
}
.p-localseo .ls-cta .wd-cta-lead .lede{ margin-bottom:1.5rem; }
.p-localseo .wd-cta-grid{ display:grid; gap:clamp(2rem,1rem + 4vw,4rem); grid-template-columns:1fr; align-items:start; }
.p-localseo .wd-cta-proof-h{ margin-bottom:.75rem; color:var(--text-3); }
.p-localseo .svc-cta-line{ margin:0 0 clamp(1rem,.5rem + 2vw,2rem); }
.p-localseo .svc-cta-foot{ margin-top:1.25rem; color:var(--text-3); }
@media (min-width:900px){
.p-localseo .wd-cta-grid{ grid-template-columns:1.3fr .7fr; }
 
}


/* ===== css/pages/packages.css ===== */
/* css/pages/packages.css — seo-money, round 4 (eden formats). Scoped under
   .p-packages (CONTRACT §4). Semantic-role tokens only. Shared eden formats
   (phead/faq/meet) live in css/eden.css; tier cards + the compare table here. */

/* phead sizing — the packages H1 is long; keep it elegant, not enormous */
.p-packages .phead h1{ font-size: clamp(2.3rem, 1.2rem + 3.4vw, 4.5rem); max-width: 18em; }
.p-packages .phead-note{ color: var(--text-3); max-width: 44ch; }

/* ------------------------------------------------------------- tier cards */
.p-packages .pkg-tiers{ display:grid; gap:1.25rem; grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:960px){
.p-packages .pkg-tiers{ grid-template-columns:1fr 1.15fr 1fr; align-items:start; }
}
.p-packages .pkg-tier{ border:1px solid var(--rule); border-radius:var(--r-btn); padding:clamp(1.5rem,1rem + 2vw,2.25rem); background:var(--surface); display:flex; flex-direction:column; gap:1.1rem; }
.p-packages .pkg-tier--anchor{ border-color:var(--accent-text); box-shadow:var(--sh-2); background:var(--wash-accent, var(--surface)); }
@media (min-width:960px){
.p-packages .pkg-tier--anchor{ transform:translateY(-1rem); }
}
.p-packages .pkg-tier-flag{ color:var(--accent-text); margin-bottom:-.25rem; }
.p-packages .pkg-tier-name{ font-family:var(--f-display); font-variant-ligatures:none; font-size:1.35rem; letter-spacing:-.01em; color:var(--text); }
.p-packages .pkg-price{ display:flex; align-items:baseline; gap:.15rem; color:var(--text); }
.p-packages .pkg-price-cur{ font-size:1.25rem; color:var(--text-2); }
.p-packages .pkg-price-n{ font-family:var(--f-display); font-size:clamp(2.75rem,2rem + 4vw,4.5rem); line-height:.95; font-variant-numeric:tabular-nums; }
.p-packages .pkg-price-per{ font-size:.95rem; color:var(--text-3); }
.p-packages .pkg-tier-for{ color:var(--text-2); font-size:.95rem; line-height:1.55; }
.p-packages .pkg-plus{ font-size:var(--t-micro-2); font-weight:var(--w-micro); letter-spacing:var(--ls-micro); text-transform:uppercase; color:var(--accent-text); border-top:1px solid var(--rule); padding-top:1rem; }

/* grouped deliverables — the clarity layer */
.p-packages .pkg-groups{ display:flex; flex-direction:column; gap:1.15rem; flex:1; }
.p-packages .pkg-group-t{ font-size:.66rem; letter-spacing:.12em; text-transform:uppercase; font-weight:500; color:var(--text-3); margin-bottom:.5rem; }
.p-packages .pkg-inc{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:.55rem; }
.p-packages .pkg-inc li{ padding-left:1.4rem; position:relative; color:var(--text-2); font-size:.92rem; line-height:1.5; }
.p-packages .pkg-inc li::before{ content:""; position:absolute; left:0; top:.62em; width:.55rem; height:1px; background:var(--accent-text); }
.p-packages .pkg-inc b{ font-weight:var(--w-semibold); color:var(--text); }
.p-packages .pkg-guarantee{ margin-top:var(--s-4); font-size:var(--t-body);
  color:var(--accent-text); font-weight:600; }
.p-packages .pkg-tier-foot{ color:var(--text-3); }
.p-packages .pkg-tiers-note{ margin-top:1.5rem; color:var(--text-3); max-width:70ch; }

/* ------------------------------------------------- every-plan feat strip */
.p-packages .pkg-every-head{ max-width:44rem; margin-bottom:.4rem; }
.p-packages .pkg-every-head .eyebrow{ margin-bottom:1.1rem; }
.p-packages .pkg-every-head p{ margin-top:1.1rem; color:var(--text-2); font-size:.9375rem; line-height:1.6; max-width:40rem; }

/* ------------------------------------------------------ compare table */
.p-packages .pkg-cmp-head{ max-width:44rem; margin-bottom:clamp(1.6rem,4vh,2.6rem); }
.p-packages .pkg-cmp-head .eyebrow{ margin-bottom:1.1rem; }
.p-packages .pkg-cmp-head p{ margin-top:1.1rem; color:var(--text-2); font-size:.9375rem; line-height:1.6; max-width:40rem; }
.p-packages .pkg-cmp-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
.p-packages .pkg-cmp{ width:100%; min-width:720px; border-collapse:collapse; }
.p-packages .pkg-cmp th, .p-packages .pkg-cmp td{ text-align:left; vertical-align:top; padding:1rem .9rem; border-bottom:1px solid var(--rule); font-size:.92rem; line-height:1.5; }
.p-packages .pkg-cmp thead th{ font-size:.66rem; letter-spacing:.12em; text-transform:uppercase; font-weight:500; color:var(--text-3); border-bottom:1px solid var(--rule-2); padding-top:0; }
.p-packages .pkg-cmp td:first-child, .p-packages .pkg-cmp th:first-child{ padding-left:0; color:var(--text); font-weight:var(--w-medium); }
.p-packages .pkg-cmp td{ color:var(--text-2); }
.p-packages .pkg-cmp .cmp-us{ color:var(--text); }
.p-packages .pkg-cmp .cmp-us::before{ content:"✓ "; color:var(--accent-text); font-weight:var(--w-semibold); }
.p-packages .pkg-cmp .cmp-dim{ color:var(--text-3); }
.p-packages .pkg-cmp-note{ margin-top:1.2rem; color:var(--text-3); }

/* ------------------------------------------------------------- usp band */
.p-packages .pkg-usp-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3.5rem); grid-template-columns:1fr; align-items:start; }
@media (min-width:900px){
.p-packages .pkg-usp-grid{ grid-template-columns:.9fr 1.1fr; }
}
.p-packages .pkg-usp-lead{ max-width:40ch; }
.p-packages .pkg-usp-lead .eyebrow{ margin-bottom:1.1rem; }
.p-packages .pkg-usp-body p{ color:var(--text-2); max-width:var(--prose,62ch); margin-bottom:1rem; }


/* ===== css/pages/services.css ===== */
/* css/pages/services.css — seo-money. Scoped under .p-services (CONTRACT §4). Semantic-role tokens only.
   Signature serp-card + rank-ladder are canonical (base.css) — no component CSS here. */
.p-services .svc-hero-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3.5rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:900px){
.p-services .svc-hero-grid{ grid-template-columns:1.5fr .9fr; align-items:end; }
 
}
/* round 5: THE STRATEGY BOARD sits under the phead (component canonical in
   base.css since round 6 — home's journey reuses it); only the placement
   margin is page business. */
.p-services .strat{ margin-top:clamp(2.75rem,6vh,4.25rem); }
.p-services .svc-list{ display:flex; flex-direction:column; }
.p-services .svc{ display:grid; grid-template-columns:1fr; gap:.5rem 2rem; padding:clamp(2rem,1.5rem + 3vw,4rem) 0; border-top:1px solid var(--rule); }
.p-services .svc:first-child{ border-top:0; }
.p-services .svc-n{ color:var(--accent-text); font-size:1rem; margin:0 0 .5rem; }
.p-services .svc-t{ margin:0 0 .75rem; }
.p-services .svc-scope{ color:var(--text-2); max-width:var(--prose,62ch); }
.p-services .svc-inc{ list-style:none; margin:1rem 0 0; padding:0; display:flex; flex-wrap:wrap; gap:.5rem .75rem; }
.p-services .svc-inc li{ padding:.3rem .7rem; border:1px solid var(--rule); border-radius:100px; color:var(--text-3); }
/* round 5: THE 32-POINT WORKING CHECKLIST — four ruled ledgers, 2×2. The quiet
   counterpart to the strategy board: no boxes, no washes — hairline rows and
   ink ticks; emerald only on the four group numerals. */
.p-services .svc-check-head{ max-width:52ch; }
.p-services .svc-check-head .lede{ margin-top:1rem; }
.p-services .svc-check-grid{ display:grid; grid-template-columns:1fr; gap:clamp(2.25rem,1.5rem + 2.5vw,3.5rem) clamp(2.5rem,2rem + 3vw,5rem); margin-top:clamp(2.5rem,2rem + 2.5vw,4.5rem); }
@media (min-width:640px){ .p-services .svc-check-grid{ grid-template-columns:1fr 1fr; } }
.p-services .svc-check-ghead{ display:flex; align-items:baseline; gap:.9rem; padding-bottom:.8rem; border-bottom:1px solid var(--rule-2); }
.p-services .svc-check-gn{ font-family:var(--f-display); font-weight:var(--w-display); font-variant-ligatures:none; font-size:clamp(1.35rem,1.2rem + .5vw,1.8rem); line-height:.9; letter-spacing:-.02em; color:var(--accent-text); margin:0; }
.p-services .svc-check-list{ list-style:none; margin:0; padding:0; }
.p-services .svc-check-list li{ display:flex; align-items:baseline; gap:.7rem; padding:.55rem 0; border-bottom:1px solid var(--rule); font-size:.94rem; line-height:1.45; color:var(--text-2); }
.p-services .svc-check-list svg{ width:11px; height:9px; flex:none; color:var(--text-3); transform:translateY(.5px); }
.p-services .svc-check-note{ margin-top:clamp(1.75rem,1.25rem + 1.5vw,2.75rem); color:var(--text-3); }

/* round 5: AI SEARCH / ANSWER ENGINES — editorial argument (prose → pull
   statement → feat-grid of citation drivers). The pull line borrows the
   pullq type register at section scale, left-set; the driver grid is eden's
   feat-grid at 3-up on wide screens (eden's own ≤1100/≤560 breakpoints
   handle the rest — the override lives above them, min-width only). */
.p-services .svc-ai-head{ max-width:52ch; }
.p-services .svc-ai-head .lede{ margin-top:1rem; }
.p-services .svc-ai-prose{ max-width:var(--prose); margin-top:clamp(1.75rem,1.25rem + 1.5vw,2.75rem); }
.p-services .svc-ai-prose p{ color:var(--text-2); }
.p-services .svc-ai-prose p + p{ margin-top:1.1rem; }
.p-services .svc-ai-pull{ margin:clamp(2.75rem,2rem + 2.5vw,4.5rem) 0; }
.p-services .svc-ai-pull blockquote{ font-family:var(--f-display); font-weight:var(--w-display); font-style:italic; font-variant-ligatures:none; font-size:clamp(1.45rem,1.1rem + 1.4vw,2.4rem); line-height:1.25; letter-spacing:-.015em; color:var(--text); max-width:26ch; margin:0; }
.p-services .svc-ai-gh{ margin-top:clamp(2.5rem,2rem + 2vw,4rem); }
.p-services .svc-ai-grid{ margin-top:clamp(1.5rem,1.25rem + 1vw,2.25rem); }

.p-services .svc-next-head, .p-services .svc-proof-head{ max-width:40ch; }
.p-services .svc-proof-head .lede{ margin-top:1rem; }
.p-services .svc-next-list{ list-style:none; margin:clamp(1.5rem,1rem + 2vw,3rem) 0 0; padding:0; }
.p-services .svc-next-row{ border-top:1px solid var(--rule); }
.p-services .svc-next-link{ display:grid; grid-template-columns:auto 1fr; gap:.3rem 1.25rem; align-items:baseline; padding:clamp(1rem,.75rem + 1vw,1.75rem) 0; text-decoration:none; color:var(--text); transition:padding-left var(--duration-normal,300ms) var(--ease-out-expo,cubic-bezier(.16,1,.3,1)); }
.p-services .svc-next-link:hover{ padding-left:.75rem; }
.p-services .svc-next-n{ color:var(--accent-text); grid-row:span 2; font-size:.9rem; }
.p-services .svc-next-t{ font-size:clamp(1.15rem,1rem + .7vw,1.6rem); }
.p-services .svc-next-d{ color:var(--text-3); font-size:.95rem; grid-column:2; }
.p-services .svc-cta-inner{ max-width:var(--prose, 62ch); }
.p-services .svc-cta-line{ margin:0 0 clamp(1rem,.5rem + 2vw,2rem); }
.p-services .svc-cta-act .lede{ margin-bottom:1.5rem; }
.p-services .svc-cta-foot{ margin-top:1.25rem; color:var(--text-3); }


/* ===== css/pages/smallbiz.css ===== */
/* css/pages/smallbiz.css — seo-money. Scoped under .p-smallbiz (CONTRACT §4). Semantic-role tokens only.
   Signature serp-card + rank-ladder are canonical (base.css) — no component CSS here. */
.p-smallbiz .sb-hero-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3.5rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:900px){
.p-smallbiz .sb-hero-grid{ grid-template-columns:1.5fr .9fr; align-items:end; }
 
}
.p-smallbiz .sb-hero-note{ border-left:2px solid var(--accent-text); padding-left:1.25rem; align-self:end; }
.p-smallbiz .sb-hero-note p:not(.micro){ color:var(--text-2); font-size:1rem; line-height:1.6; margin-top:.5rem; max-width:32ch; }
.p-smallbiz .sb-value-head{ max-width:40ch; }
.p-smallbiz .sb-value-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:820px){
.p-smallbiz .sb-value-grid{ grid-template-columns:1fr 1fr; }
 
}
.p-smallbiz .sb-value-col p:not(.micro){ color:var(--text-2); max-width:52ch; margin-top:.5rem; }
.p-smallbiz .sb-value-l{ margin-bottom:.5rem; }
.p-smallbiz .sb-value-note{ margin-top:1.5rem; color:var(--text-2); max-width:64ch; }
.p-smallbiz .wd-cta-grid{ display:grid; gap:clamp(2rem,1rem + 4vw,4rem); grid-template-columns:1fr; align-items:start; }
.p-smallbiz .wd-cta-proof-h{ margin-bottom:.75rem; color:var(--text-3); }
.p-smallbiz .svc-cta-line{ margin:0 0 clamp(1rem,.5rem + 2vw,2rem); }
.p-smallbiz .svc-cta-foot{ margin-top:1.25rem; color:var(--text-3); }
@media (min-width:900px){
.p-smallbiz .wd-cta-grid{ grid-template-columns:1.3fr .7fr; }
 
}


/* ===== css/pages/webdesign.css ===== */
/* css/pages/webdesign.css — seo-money. Scoped under .p-webdesign (CONTRACT §4). Semantic-role tokens only.
   Signature serp-card + rank-ladder are canonical (base.css) — no component CSS here. */
.p-webdesign .wd-hero-grid{ display:grid; gap:clamp(1.5rem,1rem + 3vw,3.5rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:900px){
.p-webdesign .wd-hero-grid{ grid-template-columns:1.5fr .9fr; align-items:end; }
 
}
.p-webdesign .wd-hero-note{ border-left:2px solid var(--accent-text); padding-left:1.25rem; align-self:end; }
.p-webdesign .wd-hero-note p:not(.micro){ color:var(--text-2); font-size:1rem; line-height:1.6; margin-top:.5rem; max-width:32ch; }
.p-webdesign .wd-contrast-head, .p-webdesign .wd-how-head{ max-width:40ch; }
.p-webdesign .wd-paths{ display:grid; gap:1.25rem; grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:820px){
.p-webdesign .wd-paths{ grid-template-columns:1fr 1fr; }
 
}
.p-webdesign .wd-path{ border:1px solid var(--rule); border-radius:12px; padding:clamp(1.5rem,1rem + 2vw,2.25rem); }
.p-webdesign .wd-path--retrofit{ background:var(--surface-2); }
.p-webdesign .wd-path--builtin{ border-color:var(--accent-text); background:var(--wash-accent, var(--surface)); }
.p-webdesign .wd-path-t{ margin:.25rem 0 .75rem; }
.p-webdesign .wd-path-lead{ color:var(--text-2); margin-bottom:1rem; }
.p-webdesign .wd-path-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:.7rem; }
.p-webdesign .wd-path-list li{ padding-left:1.4rem; position:relative; color:var(--text-3); font-size:.95rem; line-height:1.5; }
.p-webdesign .wd-path--builtin .wd-path-list li{ color:var(--text-2); }
.p-webdesign .wd-path-list li::before{ content:"—"; position:absolute; left:0; color:var(--text-3); }
.p-webdesign .wd-path--builtin .wd-path-list li::before{ content:"+"; color:var(--accent-text); }
.p-webdesign .wd-contrast-note{ margin-top:1.5rem; color:var(--text-2); max-width:64ch; }
.p-webdesign .wd-how-grid{ display:grid; gap:clamp(1.25rem,1rem + 2vw,2.5rem); grid-template-columns:1fr; margin-top:clamp(1.5rem,1rem + 2vw,3rem); }
@media (min-width:720px){
.p-webdesign .wd-how-grid{ grid-template-columns:1fr 1fr; }
 
}
.p-webdesign .wd-how-n{ color:var(--accent-text); font-size:1.1rem; margin:0 0 .3rem; }
.p-webdesign .wd-how-l{ margin-bottom:.4rem; }
.p-webdesign .wd-how-item p:not(.micro){ color:var(--text-2); font-size:.95rem; line-height:1.6; }
.p-webdesign .wd-cta-lead .lede{ margin-bottom:1.5rem; }
.p-webdesign .wd-cta-grid{ display:grid; gap:clamp(2rem,1rem + 4vw,4rem); grid-template-columns:1fr; align-items:start; }
.p-webdesign .wd-cta-proof-h{ margin-bottom:.75rem; color:var(--text-3); }
.p-webdesign .svc-cta-line{ margin:0 0 clamp(1rem,.5rem + 2vw,2rem); }
.p-webdesign .svc-cta-foot{ margin-top:1.25rem; color:var(--text-3); }
@media (min-width:900px){
.p-webdesign .wd-cta-grid{ grid-template-columns:1.3fr .7fr; }
 
}

/* answer engines (round 8) — citation-drivers grid, build-angled lede */
.p-webdesign .wd-ai-head{ max-width: 56ch; }
.p-webdesign .wd-ai-head .lede{ margin-top: 1rem; }
.p-webdesign .wd-ai-more{ margin-top: clamp(1.75rem, 1.25rem + 1.5vw, 2.75rem); color: var(--text-3); }
