/* ==========================================================================
   CapInteract — design tokens

   TWO SOURCES, and the difference matters.

   1. Website file  M9QEsGg30ogrclfn9EO7Cz
      Consumes a SUBSET of the library: 18 primitives, 23 semantic, 13
      foundations. This is what the page nodes actually bind to.

   2. Brand Elements library  ZfEMeKnC2KGMpmhaTquefu
      The full system: 67 primitives, 38 semantic, 16 foundations — including
      the whole dataviz palette, the brand-navy/orange/purple/sky/teal ramps,
      and the info/success/warning feedback sets. Most of it is NOT published
      as variables into the website file, so nothing there can bind to it and
      no audit run against the website file alone can find it.

   Every value below carries the library variable name it came from. Where a
   name here differs from the library, the comment says why.
   Contrast figures are measured, not estimated.
   ========================================================================== */

:root {

  /* ---- Text ------------------------------------------------------------ */

  /* text/primary -> neutral/900. The website file carried #00274C, which was
     a porting error, not a design decision. Corrected to the library value.
     Every heading and the value statement on the product pages binds here. */
  --text-primary:      #141B22;   /* 17.36:1 on surface-default             */

  --text-secondary:    #54626F;   /* text/secondary -> neutral/600  5.93:1 on sunken */
  --text-on-dark:      #FFFFFF;   /* text/on-dark   -> neutral/0            */
  --text-on-accent:    #00274C;   /* text/on-accent -> brand-navy/100       */

  /* Two teals, deliberately.
     brand/accent -> brand-teal/100 #2BBBB5 is the brand teal. As TYPE it
     measures 2.24:1 on surface-sunken and fails WCAG AA there; on
     surface-brand it measures 6.37:1 and passes. So it is correct for teal
     type on navy — the hero eyebrow — and wrong for teal type on any light
     surface. dataviz/seq-7 is the substitute on light surfaces only. */
  --brand-accent:      #2BBBB5;   /* brand/accent -> brand-teal/100 = dataviz/seq-5
                                     graphics anywhere; type on navy only    */
  --text-accent:       var(--dataviz-seq-7);  /* teal type on light surfaces */

  /* ---- Surfaces -------------------------------------------------------- */
  --surface-default:   #FFFFFF;   /* surface/default -> neutral/0           */
  --surface-sunken:    #F7F9FA;   /* surface/sunken  -> neutral/50          */
  --surface-brand:     #00274C;   /* surface/brand   -> brand-navy/100      */
  --surface-raised:    #FFFFFF;   /* surface/raised  -> neutral/0           */

  /* ---- Lines ----------------------------------------------------------- */
  --border-default:    #DCE3E9;   /* border/default -> neutral/200          */
  --border-strong:     #C2CCD5;   /* border/strong  -> neutral/300          */
  /* border/active-on-* — the nav's open-item indicator. TWO tokens, not one,
     and the split is forced rather than stylistic: no single orange in the
     system clears 3:1 on both nav surfaces. See the note at the foot of this
     file — this is the third instance of that shape. */
  --border-active-on-dark:  var(--brand-orange-100);  /* 5.06:1 on surface-brand */
  --border-active-on-light: var(--brand-orange-050);  /* 3.78:1 on white,
                                                         3.58:1 on sunken       */

  --border-focus:      var(--brand-accent);   /* border/focus — same value as
                                     brand/accent. NOT used by the focus ring:
                                     reset.css needs a two-tone ring because no
                                     single colour clears 3:1 on all four
                                     surfaces, and this one manages 2.24 on
                                     sunken. Declared because Figma names it. */

  /* ---- Action roles — Figma's semantic collection ----------------------
     Read from the library Button set 27:195, which specifies
     State: Default | Hover | Pressed | Disabled. Each of these is the variable
     the corresponding variant actually binds to, not an inference.

     Aliased to the primitives rather than restating hex, so there is one place
     each value lives. The role name is what components should reference. */
  --action-accent:         var(--brand-accent);      /* #2BBBB5             */
  --action-accent-hover:   var(--dataviz-seq-4);     /* #55CAC4 = brand-teal/200 */
  --action-primary:        var(--brand-navy-100);    /* #00274C             */
  --action-primary-hover:  var(--brand-navy-200);    /* #33526F             */

  /* Pressed is NOT a separate value in Figma — both Pressed variants bind to
     the same -hover variables as Hover, so transcribing it literally would give
     a button no press feedback at all. See §11 for what the site does instead. */

  /* ---- Feedback -------------------------------------------------------
     For form validation on Let's Talk and Book a Demo. Nothing uses them yet.

     NOTHING USES THEM YET IS NOW LOAD-BEARING, not incidental. Until 2026-08-07
     `.field__req` painted every required asterisk with --feedback-error-text, so
     the one red on these pages meant BOTH "required" and "awaiting Don". §6's new
     convention reserves red for the second meaning alone; the required marker now
     takes the label colour. Do not re-point .field__req here. */
  --feedback-error:      #D64545;   /* feedback/error                        */
  --feedback-error-text: var(--dataviz-cat-8);   /* #A82F2F = error/strong   */

  /* ---- Form field ------------------------------------------------------
     WHITE FIELD, BRAND-NAVY OUTLINE — Zoran's decision 2026-08-10, applied
     2026-08-11. This RETIRES the 2026-08-07 sky-fill revision entirely: the
     fill is gone, the field renders on --surface-default, and the border does
     the identifying work on its own.

     --border-default is deliberately NOT changed. It draws card edges and
     dividers, where nothing is being identified as a control, so raising it
     would be a site-wide change to satisfy a rule that reaches only inputs.

     Aliased to the PRIMITIVE that resolves to #00274C rather than to a
     same-valued semantic token: --surface-brand and --action-primary both
     resolve here too, and a border is neither a surface nor an action. The
     register's standing rule is to bind by resolved value, not by name.

     MEASURED on white, per this file's rule: 15.06:1, against SC 1.4.11's
     3:1 minimum. C30 ruled the old 1.30:1 border a genuine failure; this is
     the fix, and it clears the bar by a factor of five. */
  --border-field:        var(--brand-navy-100);   /* #00274C, 15.06:1 on white */

  /* ---- Neutral ramp ---------------------------------------------------- */
  --neutral-0:         #FFFFFF;
  --neutral-50:        #F7F9FA;
  --neutral-100:       #EDF1F4;
  --neutral-200:       #DCE3E9;   /* NOTE: the library's neutral/200. The
                                     previous version of this file used the
                                     name --neutral-200 for #B6C0CA, which is
                                     brand-navy/500. Corrected below.       */
  --neutral-300:       #C2CCD5;   /* 9.24:1 on surface-brand                */
  --neutral-400:       #9AA7B4;   /* = text/disabled. 6.14:1 on surface-brand */
  --neutral-500:       #71808F;   /* a real primitive. Appears as a stroke in
                                     gp-hero-diagram-mobile; earlier audits of
                                     the website file alone could not find it
                                     and wrongly called it off-system.      */
  --neutral-600:       #54626F;
  --neutral-700:       #3C4854;   /* the Navy footer divider. Read from the
                                     Divider rect in 249:410, which binds to
                                     neutral/700. 1.53:1 on surface-brand —
                                     correct: it is a hairline, not type, and
                                     SC 1.4.11 exempts purely decorative rules */
  --neutral-900:       #141B22;   /* = library text/primary, Light mode     */

  /* ---- Brand navy ramp ------------------------------------------------- */
  /* brand-orange ramp. Only the two steps the site uses are declared; the
     library carries 100-500. 050 was ADDED to the library 2026-08-05
     (VariableID:235:2) because the ramp had nothing darker than 100 and
     therefore nothing that clears 3:1 on a light surface. Its value is the
     ramp's own 100->200 interval extrapolated one step down (R-8 G-26 B-34),
     not a colour picked by eye. */
  --brand-orange-050:  #CF6531;   /* 3.78:1 white, 3.58:1 sunken, 3.99:1 navy */
  --brand-orange-100:  #D77F53;   /* = dataviz/cat-3 = warning/base           */

  /* brand-sky/500, library VariableID:11:27, key 996c12d3e79c209aa75d68f36b071f3bf321dfd2.
     The FIFTH rung of the sky ramp and the palest — this ramp runs light as the
     number rises, the same direction as brand-navy (500 is #B6C0CA, a hairline
     value). Read from the library, not sampled. Zoran's call 2026-08-07: the form
     field fill on both form pages. */
  --brand-sky-500:     #DAEDF4;

  --brand-navy-100:    #00274C;
  --brand-navy-200:    #33526F;   /* = action/primary-hover. Eyebrows and the
                                     legal line in the Light footer.
                                     7.72:1 on surface-sunken               */
  --brand-navy-400:    #8093A4;   /* 4.75:1 on surface-brand                */
  --brand-navy-500:    #B6C0CA;   /* hairlines and connectors in the artwork */

  /* Hero subcopy on navy. Read from node 249:316, fill bound to neutral/300. */
  --text-on-dark-muted: var(--neutral-300);

  /* ==== dataviz — Brand Elements library, not published as variables
          to this file ====================================================
     The diagram SVGs carry these as raw hex by design (CLAUDE.md §5): the
     files are authored against this palette and nothing in them is styled
     from CSS. Declared here so a build check can assert against the set, and
     so each artwork colour has a name rather than being a loose literal.

     Sequential ramp — pale to dark teal. */
  --dataviz-seq-1:     #E8F7F6;
  --dataviz-seq-2:     #C1EBEA;   /* = brand-teal/500. Pale teal fill       */
  --dataviz-seq-3:     #95DDDA;
  --dataviz-seq-4:     #55CAC4;   /* = brand-teal/200                       */
  --dataviz-seq-5:     #2BBBB5;   /* = brand-teal/100 = brand/accent        */
  --dataviz-seq-6:     #1E8A85;   /* 4.18:1 on white, 3.95:1 on sunken.
                                     GRAPHICS ONLY — never text. Fails AA
                                     for normal text on both surfaces.      */
  --dataviz-seq-7:     #135F5B;   /* 7.46:1 on white, 7.06:1 on sunken.
                                     The teal that is safe as type on light. */

  /* Categorical set. cat-1 and cat-7 are the two that appear in the
     shipped diagrams; the rest are declared for completeness. */
  --dataviz-cat-1:     #00274C;   /* = brand-navy/100                       */
  --dataviz-cat-2:     #2BBBB5;   /* = brand-teal/100                       */
  --dataviz-cat-3:     #D77F53;   /* = brand-orange/100                     */
  --dataviz-cat-4:     #8D84BB;   /* = brand-purple/100                     */
  --dataviz-cat-5:     #85C3DF;   /* = brand-sky/100                        */
  --dataviz-cat-6:     #1F9D6B;   /* = success/base                         */
  --dataviz-cat-7:     #C2CCD5;   /* = neutral/300                          */
  --dataviz-cat-8:     #A82F2F;   /* = error/strong                         */

  /* ---- Type families --------------------------------------------------
     Manrope for product names, section titles and row titles.
     Inter for everything else. Both self-hosted; no numeric-weight
     synthesis — only the four faces actually loaded are referenced. */
  --font-display: "Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:    "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  --weight-body:        400;      /* Inter Regular                          */
  --weight-body-med:    500;      /* Inter Medium — form field labels, Figma
                                     210:219's Label. Added 2026-08-07 (D10)
                                     with the first form; the ramp had 400 and
                                     600 only.                              */
  --weight-body-strong: 600;      /* Inter Semi Bold                        */
  --weight-display-med: 500;      /* Manrope Medium — the manifesto line,
                                     Figma 185:226. Added 2026-08-07 (D9): the
                                     ramp had 600 and 700 only, so the one
                                     designed 500 on the site had nowhere to
                                     live and rendered as body text.         */
  --weight-display:     600;      /* Manrope SemiBold — titles              */
  --weight-display-max: 700;      /* Manrope Bold — product names           */

  /* ---- Type scale -----------------------------------------------------
     size / line-height pairs, read from the Figma nodes. Desktop values;
     the mobile overrides live in the media query below. */
  --fs-eyebrow:        12px;  --lh-eyebrow:        16px;
  /* The 404 numeral, and the ONLY consumer this token has ever had - the name
     was `--fs-display` at 56px and described itself as "the 404 numeral", so it
     is renamed to what it is rather than left as a display role it never played.
     An unused alias is a value someone reaches for by accident later; the same
     argument retired --slate-on-navy.

     170 is deliberately OUTSIDE the ramp rather than its new top step. The scale
     runs 12/14/16/18/22/24/32/48/56 and 170 is 3.04x its top and 3.54x a product
     name - nothing would ever land between 56 and 170, so adding it as a step
     would imply a progression that does not exist. It is one display figure.

     The 22 was added 2026-08-07 with --fs-manifesto (D9); this enumeration read
     12/14/16/18/24/... until then. A ramp comment that lists its own steps goes
     stale the moment one is added, so it is updated in the same edit.

     MEASURED, not assumed: "404" at 170px Manrope 700 renders 283.64px wide, so
     it fits the 343px content column at 375 with 59.36px to spare. No mobile
     step is needed and none is declared - same at both breakpoints, as before. */
  --fs-numeral:       170px;  --lh-numeral:       176px;
  --fs-product-name:   48px;  --lh-product-name:   56px;
  --fs-headline:       24px;  --lh-headline:       32px;
  --fs-page-title:     40px;  --lh-page-title:     48px;   /* Figma 207:214 and
                                     214:214, the Let's Talk and Book a Demo h1.
                                     Added 2026-08-07 (D10). NO mobile step —
                                     Figma sets 40/48 on BOTH artboards, which is
                                     why --fs-product-name could not be reused:
                                     that pair steps 48/56 -> 40/48, so it would
                                     be right on mobile and wrong on desktop.  */
  --fs-hero-sub:       18px;  --lh-hero-sub:       28px;
  --fs-manifesto:      22px;  --lh-manifesto:      34px;   /* Figma 185:226,
                                     the Benefits closing line: Manrope Medium
                                     22/34, three lines at 560. Added 2026-08-07
                                     (D9). A real new step between 18 and 24 —
                                     the ONLY size on the site that sits there,
                                     and it earns it because the line is a
                                     designed treatment rather than body copy.
                                     Mobile steps to 20/30, below.           */
  --fs-section-title:  32px;  --lh-section-title:  40px;
  --fs-row-title:      24px;  --lh-row-title:      32px;
  --fs-body:           16px;  --lh-body:           24px;
  --fs-body-sm:        14px;  --lh-body-sm:        20px;   /* Figma text style
                                     body-sm, read from 607:854: Inter Regular,
                                     size 14, weight 400, lineHeight 20. Footer
                                     links, office entries and legal lines.    */
  --fs-button:         16px;  --lh-button:         24px;

  --tracking-eyebrow:  0.08em;   /* eyebrows are letter-spaced small caps   */

  /* ---- Layout ---------------------------------------------------------
     Every value below maps to a Foundations variable: radius/md 8,
     radius/lg 16, and the spacing steps 4 8 12 16 24 32 48 64 96. */
  --inner-max:         1280px;   /* every section's inner wrapper           */
  --design-max:        1440px;   /* THE DESIGN WIDTH — Zoran's >1440 rule,
                                    2026-08-10: "design >1440 stays as is;
                                    only the background color expands." Figma
                                    draws 375 and 1440 and nothing between or
                                    beyond, so 1440 is where the composition
                                    stops being specified. Cap a full-bleed
                                    band's INNER at this, never its outer box,
                                    or the background stops bleeding. §9, O3. */
  --content-narrow:     640px;   /* value statement, How It Fits            */
  --content-wide:       720px;   /* More Capabilities list                  */
  --feature-col:        616px;   /* capability row copy and visual columns  */

  --section-pad-block:   96px;   /* spacing/96                              */
  --section-pad-inline:  48px;   /* spacing/48. NAV ONLY now, despite the name:
                                    sections and the footer moved to the three
                                    step 16/24/48 ladder in site.css, which this
                                    two step token cannot express. §9.       */
  --feature-gap:         48px;   /* spacing/48 — copy column to visual      */
  --feature-row-gap:     96px;   /* spacing/96 — between capability rows    */
  --more-item-pad:       24px;   /* spacing/24                              */
  --more-icon-gap:       12px;   /* spacing/12 — icon column to text column */

  /* Wrap spacing inside hero and section copy stacks */
  --gap-after-eyebrow:   12px;   /* spacing/12                              */
  --gap-after-headline:  16px;   /* spacing/16                              */
  --gap-after-subhead:   32px;   /* spacing/32                              */
  --gap-after-title:      8px;   /* spacing/8 — a More item's title to its body,
                                    and the 404 section title. Figma's value on
                                    every More item, checked.                 */
  --gap-after-row-title: 12px;   /* spacing/12 — a CAPABILITY ROW's heading to its
                                    body. Figma sets 12 on all 30 feature rows
                                    across the four product pages, at BOTH
                                    breakpoints; the More items really are 8, so
                                    one token could never have served both. D15. */
  /* The STATEMENT hero's wraps. Three of them, and they exist because the
     alternative is the trap D13-D16 documented four times over: reusing a token
     whose NAME describes another role. Figma gives this hero 16/24/32 desktop
     and 12/16/24 mobile (763:965 / 763:1008), where the shared --gap-after-*
     set is 12/16/32 at both breakpoints. Two of the six values coincide and
     four do not. Scoped to .hero--statement so the four product heroes and the
     homepage are untouched — `O10` is the site-wide version of this question
     and stays open. If O10 resolves in Figma's favour, these become the hero
     gaps everywhere and the scoping comes off. D18.                        */
  /* THE HERO GAP TRIO. Named `statement` because About's Statement Hero (D20)
     was its first consumer; since O10's fix on 2026-08-11 EVERY hero uses it,
     which makes the name under-descriptive rather than wrong. Renaming is its
     own decision — O23, the same note D5 left on --fs-product-name. */
  --gap-statement-eyebrow:  16px;   /* spacing/16 — eyebrow to headline       */
  --gap-statement-headline: 24px;   /* spacing/24 — headline to subhead       */
  --gap-statement-sub:      32px;   /* spacing/32 — below the subhead         */

  /* Hero subhead type, and it STEPS where --fs-hero-sub does not. Figma sets
     the hero subhead 18/28 on desktop and 16/24 on mobile — read from 43:209
     (homepage) and About's mobile Statement Hero, which agree.

     ALIASES, NOT NUMBERS: both values already exist in this file, so §4's
     single-source rule is kept and the step is expressed as the relationship
     it actually is — desktop is the site's 18/28 lead step, mobile is body.

     NOT --fs-hero-sub, WHICH IS A DIFFERENT TOKEN DESPITE THE NAME. That one
     is the site's single 18/28 step and is used by the CTA band, the showcase
     intro, Thank You, the 404 and the forms, none of which step at 767. The
     near-identical names are a hazard and are the other half of O23. */
  --fs-hero-subhead:   var(--fs-hero-sub);   /* 18px */
  --lh-hero-subhead:   var(--lh-hero-sub);   /* 28px */

  --gap-after-section-head: 64px; /* spacing/64 — a section header to the content
                                    below it. FLAT at both breakpoints: Figma gives
                                    the Capabilities Section Header paddingBottom 64
                                    on all four product pages AND on both artboards
                                    of each. It was --feature-row-gap, which is 96
                                    desktop and 32 mobile, so the clearance was
                                    wrong in both directions everywhere. D14.    */
  --gap-before-figure:   24px;   /* spacing/24 — the mobile hero-diagram section's
                                    eyebrow to its figure. A real step: the ramp
                                    holds 8/12/16/32 and nothing sits at 24, and
                                    Figma sets 24 on all three pages that have
                                    this section (Ci 461:338, Guardian 514:338,
                                    LP 389:303). Register D13.                */

  --radius-card:          8px;   /* radius/md                               */
  --radius-panel:        16px;   /* radius/lg                               */
}

/* ==========================================================================
   Mobile — the 375 breakpoint from Figma.
   Only the values that actually differ are restated.
   ========================================================================== */

@media (max-width: 767px) {
  :root {
    --fs-product-name:   40px;  --lh-product-name:   48px;
    --fs-manifesto:      20px;  --lh-manifesto:      30px;   /* Figma 185:277 */

    --section-pad-block:  64px;   /* spacing/64                             */
    --section-pad-inline: 16px;   /* spacing/16                             */
    --feature-gap:        24px;   /* spacing/24 — stacked: copy above visual */
    --feature-row-gap:    32px;   /* spacing/32                             */

    --gap-statement-eyebrow:  12px;  /* spacing/12                            */
    --gap-statement-headline: 16px;  /* spacing/16                            */
    --gap-statement-sub:      24px;  /* spacing/24                            */

    /* Figma 43:209 mobile subhead is 16/24, and About's agrees. O10, 2026-08-11 */
    --fs-hero-subhead:   var(--fs-body);   /* 16px */
    --lh-hero-subhead:   var(--lh-body);   /* 24px */
  }
}

/* ==========================================================================
   RESOLVED in this pass

   - neutral/300 = #C2CCD5, read from node 249:316. 9.24:1 on surface-brand,
     not the 8.05:1 previously noted here.
   - The dataviz palette is real and lives in the Brand Elements library
     ZfEMeKnC2KGMpmhaTquefu. Every artwork value now carries its dataviz or
     brand-ramp name. Nothing in the block is unbacked.
   - #EDF1F4 = neutral/100, #8093A4 = brand-navy/400, #B6C0CA =
     brand-navy/500. All three are library primitives; none is published as a
     variable into the website file, which is why an audit of that file alone
     found no source for them.
   - seq-6 #1E8A85 is 4.18:1 on white and 3.95:1 on sunken. Graphics only,
     never text. The previous 4.73:1 figure was wrong.
   - seq-7 #135F5B is 7.46:1 on white and 7.06:1 on sunken. The previous
     single 7.06:1 figure was the sunken number presented as the white one.
   - The old --neutral-200 (#B6C0CA) collided with the library's neutral/200
     (#DCE3E9). #B6C0CA is now --brand-navy-500 and --neutral-200 holds the
     library value. Neither name was referenced by site.css, so nothing broke.

   - --text-primary corrected to #141B22 (library text/primary -> neutral/900).
     The #00274C this file carried was a porting error. 17.36:1 on
     surface-default. Every page inherits it.
   - Footer eyebrows and the legal line now use --neutral-400 #9AA7B4, which
     is what Figma specifies and what icon-linkedin.svg is filled with.
     6.14:1 on surface-brand. They previously used --slate-on-navy #8093A4.
   - #71808F is neutral/500, a real library primitive, now declared. It is a
     stroke colour in gp-hero-diagram-mobile. Earlier audits scoped to the
     website file alone could not see it and wrongly called it off-system;
     that characterisation was incorrect and the artwork needs no change.

   - --slate-on-navy removed. It aliased brand-navy/400 under a role name that
     no rule used once the footer moved to neutral/400, and an unused alias is
     a value someone reaches for by accident later. The primitive itself
     remains as --brand-navy-400, which is the name it has in the library.

   ONE SURFACE IS NOT THE SITE — the same split, three times now

   A Figma token that works on one surface is not evidence that it works on
   this site, because this site puts the same component on more than one
   surface. Three tokens have now had to be split for that reason, and it is
   a shape rather than three unrelated cases:

     A6   text/accent   -> --brand-accent for graphics, --text-accent for type
                          on light. #2BBBB5 is 2.24:1 on sunken.
     B3   border/focus  -> a two-tone ring. No single colour clears 3:1 on all
                          four surfaces the site uses.
     ---  border/active -> -on-dark and -on-light. No single orange clears 3:1
                          on both nav surfaces.

   The nav case is the sharpest of the three, because §8's scroll-return
   INVERSION means both nav surfaces occur on EVERY page. There is no subset
   of pages where one value would have been enough.

   So when porting a library colour: ask which surfaces it lands on here, not
   which surface it was designed against.

   NOT PORTED — available in the library when needed

   feedback: error #D64545, error-strong #A82F2F, error-subtle #FBE9E9,
   error-text-dark #E15A5A, info #3B7DBF, success #1F9D6B, warning #D77F53
   and their -subtle/-strong variants. Needed for form validation on Let's
   Talk and Book a Demo, which are blocked on the form endpoint anyway.

   hover states: action/accent-hover and brand/accent-hover #55CAC4,
   action/primary-hover and brand/primary-hover #33526F. This file declares
   no hover colours at all.

   dark mode: all 38 library semantic variables carry a Dark value. Nothing
   in the brief asks for dark mode, so none of it is ported.
   ========================================================================== */
