/* ============================================================================
   DESIGN TOKENS — semantic contract
   ----------------------------------------------------------------------------
   Generated from Figma "Gulfstar" (PGVSenVRO5Ixmxnxh01c9x), modified 2026-08-07.
   Extracted via REST full-file traversal — 7,628 nodes, 15 colours, 20 text styles.

   NAMING RULE — do not break this:
   Token names are SEMANTIC ROLES, never brand names. `--accent-primary`, not
   `--sky-blue`; `--surface-dark`, not `--gulfstar-navy`. Element and block CSS
   must reference roles only, so a new client ships a new value block and nothing
   else in the library changes. A brand-specific token name welds the library to
   one identity and breaks the template on the second client.

   To theme a new client: replace ONLY the values in [1] BRAND VALUES below.
   Everything under [2] SYSTEM is brand-independent and should not be edited
   per client.
   ============================================================================ */

/* ============================================================================
   [1] BRAND VALUES — Gulfstar
   Swap this whole block per client. Nothing else.
   ============================================================================ */
:root {

  /* --- Palette ------------------------------------------------------------
     9 swatches, documented on labelled swatch layers in Figma "Single Elements".
     Usage weight = number of distinct layers using the colour across the file. */

  --surface-dark:            #122D3C;  /* 128 layers — dark sections, headings   */
  --surface:                 #FFFFFF;  /*  94 layers — default light surface     */
  --surface-tint:            #EFF7FC;  /*  26 layers — tinted light surface      */

  --text-body:               #336887;  /*  35 layers — body copy                 */
  --text-heading:            #122D3C;  /* headings on light surfaces             */
  --text-on-dark:            #FFFFFF;  /* copy on dark surfaces                  */
  --text-body-on-dark:       #EFF7FC;  /*  26 layers — body copy on dark surfaces */
  --text-muted:              #AED5EE;  /*  11 layers — placeholders, de-emphasis */

  --accent-primary:          #336887;  /* Style=Primary button fill — same hex as --text-body (CORRECTED, see INVENTED.md) */
  --surface-accent:          #58AADB;  /* CTA/Single-Button band background + accent text (was mis-tagged --accent-primary) */
  --accent-secondary:        #338783;  /*   7 layers — secondary accent          */
  --accent-secondary-light:  #4BBEB9;  /*   6 layers — secondary accent, light   */
  --accent-tertiary:         #AADB58;  /*   2 layers — tertiary accent           */

  /* Theme-aware component roles — defaults are the LIGHT values; [3] .theme-dark
     remaps them. Blocks reference these so they never branch on theme. */
  --border-divider:  var(--text-muted);       /* section hairline: #AED5EE light / #EFF7FC dark */
  --label-accent:    var(--accent-secondary); /* Section Label eyebrow: #338783 light / #58AADB dark */
  --surface-card:    var(--surface-tint);     /* card surface: #EFF7FC light / #336887 dark (Six Card Grid) */
  /* Comparison Table cards are THEME-IMMUNE (always light on either surface), so these are
     fixed — deliberately NOT remapped in [3]. */
  --surface-con:     #EFF7FC;  /* Comparison "con" card (fixed) */
  --surface-pro:     #FFFFFF;  /* Comparison "pro" card (fixed) */
  --text-on-card:    #122D3C;  /* Comparison card text/headline (fixed) */

  /* --- Typeface -----------------------------------------------------------
     Montserrat throughout. No secondary or mono face in the system. */

  --font-body:    'Montserrat', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: var(--font-body);

  /* --- Type scale ---------------------------------------------------------
     Exact px/line-height pairs extracted from the file. Fluid clamping is
     applied in [2] SYSTEM, not here — the ramp endpoints are brand data,
     the interpolation is system behaviour. */

  --size-display:    48px;  --lh-display:    58px;  --wt-display:    700;
  --size-h1:         38px;  --lh-h1:         42px;  --wt-h1:         700;
  --size-h2:         36px;  --lh-h2:         42px;  --wt-h2:         600;
  --size-h3:         30px;  --lh-h3:         36px;  --wt-h3:         500;
  --size-h4:         24px;  --lh-h4:         30px;  --wt-h4:         500;
  --size-lead:       20px;  --lh-lead:       24px;  --wt-lead:       400;
  --size-body:       17px;  --lh-body:       27px;  --wt-body:       400;
  --size-body-alt:   16px;  --lh-body-alt:   24px;  --wt-body-alt:   400;
  --size-small:      15px;  --lh-small:      24px;  --wt-small:      400;
  --size-caption:    12px;  --lh-caption:    18px;  --wt-caption:    400;

  --wt-body-strong:  700;   /* 15/24 and 17/27 both ship a bold cut */
  --wt-label:        500;   /* button + link labels, 17/27          */

  /* --- Layout -------------------------------------------------------------
     Composition widths taken directly from the Figma frames. */

  --frame-desktop:  1440px;  /* Size=Default component width */
  --frame-mobile:    428px;  /* Size=Mobile component width  */

  /* --- Interactive roles (CORRECTED against "Style=Primary" layer usage) ---
     --accent-primary (in the palette above) IS the primary button fill; it
     shares #336887 with --text-body — the same one-hex-two-roles pattern as
     #EFF7FC (surface-tint + body-on-dark). Only the ink + nav CTA live here. */
  --accent-primary-ink:  #FFFFFF;  /* GS-White — label/icon on a filled primary control */
  --accent-nav-cta:      #4BBEB9;  /* GS-Jazz — nav "Book a Call" CTA fill */

  /* --- Radii, borders, elevation (extracted from element frames) --------- */
  --radius-control:   5px;                       /* buttons, inputs, dropzone, accordion */
  --radius-media:     20px;                      /* hero image container corner radius */
  --border-hairline:  1px;                       /* every 1px stroke in the element set */
  --shadow-control:   0 0 10px rgb(0 0 0 / 0.2); /* GS-Shadow effect — nav CTA */
  --shadow-card:      0 0 5px rgb(0 0 0 / 0.2);  /* Pricing Tier Cards featured-card elevation (107:5473 frame) */
  --disabled-opacity: 0.25;                      /* DESIGNED: pagination arrow + carousel Start/End Disabled */

  /* --- Control metrics (extracted) --------------------------------------- */
  --control-h:      44px;  /* button / input / select / accordion height */
  --control-pad-x:  40px;  /* button horizontal padding */
  --field-pad-x:    15px;  /* input / select / textarea horizontal padding */
  --field-pad-y:    10px;  /* textarea vertical padding */
  --field-gap:      12px;  /* label → control gap */
  --accordion-glyph: 40px; /* +/- glyph size in the accordion toggle */
  --message-h-tall: 150px; /* Message Field Size=Tall inner height  */
  --message-h-short: 75px; /* Message Field Size=Short inner height */
  --footer-logo-w:  129px; /* Footer logotype frame width  */
  --footer-logo-h:  123px; /* Footer logotype frame height */
  /* NOTE: the radii / control-metric / icon tokens above are structural geometry
     and, per the spacing-scale rationale in [2], arguably belong in [2] SYSTEM
     rather than [1] BRAND. Left here pending an explicit reorg decision. */

  /* --- Icon & dot sizes (extracted) -------------------------------------- */
  --icon-sm:  20px;  /* section-label eyebrow arrow */
  --icon:     24px;  /* standard UI icon */
  --icon-lg:  30px;  /* checkmark, carousel arrow, social icon */
  --icon-xl:  48px;  /* dropzone cloud */
  --dot:      14px;  /* carousel dot */

  /* Structural spacing scale now lives in [2] SYSTEM (see the spacing block). */

  /* No gradients exist anywhere in the source file. Flat colour system —
     do not introduce gradients without design sign-off. */
}


/* ============================================================================
   [2] SYSTEM — brand-independent behaviour
   ----------------------------------------------------------------------------
   INVENTED — not specified in Figma. Every value below is a build decision,
   not design data. Flagged here so the reconciliation gate can find it.
   Reviewed against the mobile (428px) and desktop (1440px) compositions, but
   the interpolation between them is ours.
   ============================================================================ */
:root {

  /* Spacing scale — the structural rhythm is a clean 10px multiple across every
     block measured (10/20/30/40/60/100). It lives here in [2] SYSTEM, not [1]
     BRAND: block geometry is structural and shared across clients; only palette
     and typeface swap per client. Numeric names are honest here and would be a
     brand leak in [1].
     BET: that this 10px rhythm generalises. Revisit at the second client. */
  --space-10:   10px;
  --space-20:   20px;
  --space-30:   30px;
  --space-40:   40px;
  --space-50:   50px;
  --space-60:   60px;
  --space-100: 100px;
  --space-200: 200px;  /* CTA/Single-Button band vertical padding */

  /* Off-rhythm element constants (deliberately not on the 10 scale). */
  --nav-link-gap:  24px;  /* Nav link spacing (+ nav mobile inline padding) */
  --text-link-gap:  4px;  /* Text Link CTA label → arrow gap */
  --check-gap:      6px;  /* Check Buttons (4:1310) checkbox → label gap */

  /* Shared block geometry (structural; generalise-first per CLAUDE.md). */
  --media-aspect:  590 / 584;  /* image slot aspect — Hero + Image + Text Split */
  --measure-prose: 922px;      /* readable left-column measure for text blocks */
  --measure-cta:   1025px;     /* centred CTA content measure (1439 − 207 − 207) */
  --jump-nav-offset: 85px;     /* INVENTED — sticky-header height (measured) the service-page
                                  Jump Nav pins below once the header goes sticky at <= --bp-nav */

  /* Type stays at its designed desktop size across 769–1439 (no fluid ramp):
     Figma ships two discrete sizes (48/58, 38/42) and blocks switch at
     --bp-mobile. See INVENTED.md. */

  /* Content gutter and max width — INVENTED. Figma stops at 1440 and says
     nothing about wider viewports. Full-bleed surfaces, capped content. */
  --content-max: var(--frame-desktop);
  --gutter: clamp(20px, 5vw, 100px);

  /* Motion — INVENTED. No motion is specified in the source file. */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --dur-fast: .15s;
  --dur:      .25s;

  /* Focus ring — INVENTED. Uses --surface-accent (sky #58AADB) so the ring
     reads distinct from the primary fill (#336887). */
  --focus-ring: 2px solid var(--surface-accent);
  --focus-offset: 3px;

  /* Responsive breakpoint — INVENTED. The design ships only fixed 1440/428
     frames, no breakpoint. @media rules use the 768px literal (a media query
     cannot read a custom property); this token documents the value. */
  --bp-mobile: 768px;

  /* Nav-only breakpoint — INVENTED, and deliberately HIGHER than --bp-mobile.
     The horizontal nav's CONTENT alone measures ~1066px (logo ~199 + the 5 links
     & Services trigger ~689 + "Book A Call" CTA ~178), so it cannot sit on one
     row below ~1146px even with a tightened inset — and needs ~1266px at the
     1440 design's 100px inset. Below that it wrapped to 2–3 rows (and, under
     ~911px, overflowed with a horizontal scrollbar). So the nav — and the mega
     menu, which shares its collapse — switch to the hamburger drawer / in-drawer
     accordion at --bp-nav, while every OTHER block and the footer stay on
     --bp-mobile (blocks hold their desktop layout down to 768). 1200 gives the
     one-row nav comfortable slack at 1201 (with the tightened inset used below
     1440) while keeping the desktop nav for standard laptops (1280/1366/1440).
     @media rules use the 1200px literal; this token documents it. */
  --bp-nav: 1200px;

  /* Interaction states — INVENTED. Hover / pressed / error are not designed. */
  --accent-primary-hover: #2A5670;  /* darkened GS-Full Blue (~-12% L) — primary control hover */
  --state-error:       #C0392B;  /* form-field error border/text — no error state designed, no red in palette */
  --state-error-tint:  #F9E7E5;  /* error-field background wash — invented companion to --state-error */
}


/* ============================================================================
   [3] THEME — dark sections
   ----------------------------------------------------------------------------
   Blocks carry Theme=Light / Theme=Dark variants in Figma. Applying
   .theme-dark remaps the surface and text roles; block CSS never needs to
   know which theme it is in.
   ============================================================================ */
.theme-dark {
  --surface:       var(--surface-dark);
  --surface-tint:  #1B3D50;   /* INVENTED — no tinted dark surface in source */
  --text-heading:  var(--text-on-dark);
  --text-body:     var(--text-body-on-dark);
  --border-divider: var(--text-body-on-dark);  /* #EFF7FC hairline on dark */
  --label-accent:   var(--surface-accent);     /* #58AADB eyebrow on dark */
  --surface-card:   var(--accent-primary);     /* #336887 card surface on dark */
}


/* ============================================================================
   [4] BASE
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--surface);
  color: var(--text-body);
  font-family: var(--font-body);
  font-size: var(--size-body);
  line-height: calc(var(--lh-body) / var(--size-body));
  font-weight: var(--wt-body);
  -webkit-font-smoothing: antialiased;
}
/* No default block margins anywhere. The design system spaces every stack with
   gap/padding (see the block CSS); browser-default <p> margins (1em) are not part
   of it and, left un-reset, inflated text-driven blocks by ~17px per element. */
p, figure, blockquote { margin: 0; }

/* Leading-trim, matching the Figma text nodes (which carry
   `text-box-trim: trim-both; text-box-edge: cap alphabetic`). Without it, every text
   box keeps its full line-height (half-leading top+bottom ≈ 11-13px), so text-driven
   blocks rendered ~13px per element taller than their Figma instances. This is the
   shared cause; trimming here fixes it once for all blocks rather than per-block padding.
   Progressive: Chrome 133+/Safari 18.2+ apply it; older engines fall back to the
   (slightly taller) untrimmed metrics — no breakage, just less exact. */
:where(h1, h2, h3, h4, p, ul, ol, .section-label__text,
       .bullet-point-items__headline, .bullet-point-items__text) {
  text-box-trim: trim-both;
  text-box-edge: cap text;   /* top trimmed to cap-height (matches Figma's top trim); bottom kept at
                                the font's descent, NOT the alphabetic baseline — `cap alphabetic`
                                put the box bottom on the baseline, so descenders (g/p/j/y) fell
                                outside the box and were clipped by any `overflow:hidden` ancestor
                                (e.g. the Pricing "Key Focus Areas" nowrap+ellipsis items). */
}
/* NOTE: trim the list CONTAINER (`ul`/`ol`), never the individual `li`. trim-both strips
   half-leading at BOTH edges; on a single-line box it collapses to ~cap-height, so trimming
   each `li` removes the inter-item space and consecutive items overlap. Trimming the `ul`/`ol`
   trims the block once (first item's top, last item's bottom) — matching the Figma list nodes —
   while the `li` keep their full line-height, so they never overlap. Every trimmed role above is
   therefore either a prose block, a flex/grid-gap-separated element, or a list container. */
h1, h2, h3, h4 { color: var(--text-heading); margin: 0; }
h1 { font-size: var(--size-h1); line-height: calc(var(--lh-h1) / var(--size-h1)); font-weight: var(--wt-h1); }
h2 { font-size: var(--size-h2); line-height: calc(var(--lh-h2) / var(--size-h2)); font-weight: var(--wt-h2); }
h3 { font-size: var(--size-h3); line-height: calc(var(--lh-h3) / var(--size-h3)); font-weight: var(--wt-h3); }
h4 { font-size: var(--size-h4); line-height: calc(var(--lh-h4) / var(--size-h4)); font-weight: var(--wt-h4); }

:where(a, button, input, textarea, select):focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
