/* tokens.css — the design system.
   Consumed by base.css and every file in components/. Nothing else defines a value.

   REWRITTEN 2026-09-09. The previous token set was reverse-engineered from an
   html.to.design scrape of a competitor's site, and it inherited their measurements
   without their decisions. Three consequences were fatal rather than cosmetic:

     - There were exactly two text colours in the whole system, #000000 and #ffffff.
       No neutral ramp at all, and docs/DESIGN_TOKENS.md recorded muted text and
       subtle borders as "deliberately absent". Every caption, rule, disabled state
       and secondary label had nothing to use, so everything was rendered at full
       black and the pages had no hierarchy.
     - The primary button was a pale tint (#e6eff7) with black text, while the strong
       brand navy was spent on section backgrounds. On an advisory site the main call
       to action read as a disabled control.
     - The type scale was not a scale: `display` was 45.1px while `h1` was 60px, so
       the display size was SMALLER than h1, and tracking was a scraped -2.256px.

   What is locked and must not change: Poppins, the logo, and the 22 photographs.
   The brand hue WAS #0B3B60 and is now #0000CD -- the client unlocked it on
   2026-09-10 and supplied a logo already drawn in it. See the brand block below.

   THE SPECIFICITY RULE THAT SHAPES ALL OF THIS

   Elementor's per-page stylesheet, uploads/elementor/css/post-<id>.css, loads AFTER
   every stylesheet this theme enqueues, and it carries rules built from the kit's own
   globals -- for example:

       .elementor-widget-heading .elementor-heading-title { color: var(--e-global-color-primary) }

   That is TWO classes, 0,2,0. Any rule of ours at equal specificity LOSES, because
   ours loads first. This was originally mis-read as 0,1,1, and the result shipped a
   homepage whose h1 rendered navy-on-navy and was invisible.

   So there are two rules, and they are not negotiable:

     1. Anything of ours that must beat Elementor needs specificity STRICTLY GREATER
        than 0,2,0. See elementor-bridge.css.
     2. The kit globals are set by bin/apply-content.php and must hold colours that
        work AS TEXT, because Elementor decides where it uses them. `accent` was set
        to the pale button fill, and Elementor uses `accent` for the active accordion
        title -- so the open FAQ question was pale mist on near-white.
*/

:root {
	/* ------------------------------------------------------------------ ink ramp */
	/* Navy-derived neutrals: every step carries a little #0B3B60. These were NOT
	   retinted toward #0000CD in the 2026-09-10 rebrand. They are the family of the
	   dark grounds, which also stayed navy, and pulling desaturated greys toward a
	   fully saturated blue is how a palette starts to look dyed. */

	--ink-900: #0a1f33;  /* headings and body copy. Not #000: pure black against white
	                        is 21:1 and glares. This is 16.7:1 on paper, still far above AA. */
	--ink-700: #2c4359;  /* strong secondary text */
	--ink-500: #5a6b7c;  /* muted text, captions, meta. 5.5:1 on paper, 5.1:1 on the
	                        raised surface -- AA at any size on both */
	--ink-300: #9aa8b4;  /* placeholders and disabled text only. Fails AA on purpose:
	                        never use for content, only for genuinely inert states. */
	--ink-200: #d8dfe6;  /* rules and borders */
	--ink-100: #eaeff4;  /* subtle fills, chip grounds */
	--ink-050: #f5f8fa;  /* raised surface */

	/* --------------------------------------------------------------------- brand */

	/* REBRANDED 2026-09-10, at the client's request: the brand hue is now #0000CD,
	   the colour of the logo they supplied. It lands at 11.16:1 on white, within half
	   a point of the #0B3B60 navy it replaces (11.61:1), so every pair in the contrast
	   table below held without re-tuning -- the same trick the 2026-09-08 rebrand used.

	   TWO FAMILIES, DELIBERATELY. The dark grounds did NOT follow the brand hue. They
	   stay the desaturated near-black navy below, so #0000CD is the only saturated
	   colour on a page and reads as the action rather than the atmosphere. `navy` and
	   `blue` are therefore not one family here and must not be merged.

	   The ground choice does NOT rest on button contrast, whatever the numbers suggest:
	   a filled primary measures 1.50:1 against #071F33, the old navy fill measured
	   1.44:1, and a derived deep blue ground would give 1.54:1. All three are equally
	   poor by the formula, and the button still reads as a crisp, clearly bounded shape
	   in a 1440px screenshot -- WCAG is luminance-only and this pair separates on
	   chroma. Read docs/DESIGN_TOKENS.md before "fixing" it. */

	--navy-700: #071f33;  /* deep ground: footer, page heroes, CTA bands, the one dark
	                         band. Still genuinely navy -- see above. */

	--blue-600: #0000cd;  /* BRAND. The logo's own colour, measured off the supplied
	                         artwork rather than eyeballed. Primary button. */
	--blue-500: #1a1ad9;  /* brand hover. Lighter and slightly desaturated, mirroring
	                         the step the old navy-600 -> navy-500 pair used. */

	/* One warm metallic, used perhaps four times on a page: the accent rule beside a
	   section title, the step numbers, a hairline under the logo. Muted brass reads as
	   professional-services seniority -- a brass plate rather than a startup gradient
	   -- and deliberately avoids the terracotta/clay accent that has become the
	   default warm choice. If it ever reads cheap, it is a one-token revert. */
	--brass-500: #b08a4a;
	--brass-100: #f0e6d2;

	/* MEASURED: brass on paper is 3.19:1. That is below the 4.5:1 needed for body
	   copy, and it is why brass appears ONLY as the section rule, the checklist tick
	   and the step numerals -- a graphical object and 22px bold text, both of which
	   clear the 3:1 threshold that applies to them. Do not put brass on a paragraph.
	   Re-measured against the new brand 2026-09-10: 3.50:1 on blue-600, 5.25:1 on
	   navy-700. Both clear 3:1, so brass survived the rebrand unchanged.
	   Every other pair in this file was recomputed 2026-09-09 and clears 4.5:1; the
	   lowest is muted text on the raised surface at 5.14:1. */

	--paper: #ffffff;

	/* ------------------------------------------------- semantic colour aliases */
	/* Components reference these, not the ramp, so a hue decision changes in one place. */

	--color-brand-primary:      var(--blue-600);
	--color-brand-primary-dark: var(--navy-700);

	--color-text-heading: var(--ink-900);
	--color-text-body:    var(--ink-900);
	--color-text-muted:   var(--ink-500);   /* NEW. Its absence was the biggest gap. */
	--color-text-inverse: var(--paper);
	--color-text-on-dark-muted: #b8c7d6;    /* muted text on navy. 9.7:1 on navy-700,
	                                           6.5:1 on blue-600. */

	--color-border-subtle: var(--ink-200);  /* NEW */
	--color-border-strong: var(--ink-300);

	--color-surface-page:   var(--paper);
	--color-surface-raised: var(--ink-050);
	--color-surface-sunken: var(--ink-100);
	--color-surface-dark:   var(--navy-700);
	--color-surface-footer: var(--navy-700); /* was #2e2e2e, a grey unrelated to the brand */

	/* The pale tints survive, demoted: surface washes only. They are no longer button
	   fills and never carry text. */
	--color-accent-mist: #e6eff7;
	--color-accent-sky:  #d3e4f2;
	--color-accent-sand: var(--brass-100);

	--color-accent-rule: var(--brass-500);

	--color-surface-overlay: rgba(7, 31, 51, 0.62); /* image scrim, navy-tinted */

	/* Focus. #004AFC on white is 8.6:1; on the brand it is 1.80:1 and fails, which is
	   why the inverse exists and why base.css switches on dark grounds. It was 1.87:1
	   against the old navy, so the rebrand did not cause this and did not worsen it.
	   The ring is an OUTLINE, drawn outside the border box, so on a light page its
	   outer edge sits on paper at 6.2:1 and SC 1.4.11 is met there. Left as is rather
	   than picking a new hex, which would be an invented value: flag before changing. */
	--color-state-focus:         #004afc;
	--color-state-focus-inverse: var(--paper);
	--color-state-error:         #b3261e;
	--color-state-notice:        var(--brass-500);
	--color-state-notice-bg:     var(--brass-100);

	/* The hero scrim. Left-weighted so the headline sits on the darkest part and the
	   photograph stays legible on the right. */
	--gradient-hero: linear-gradient(
		100deg,
		rgba(7, 31, 51, 0.96) 0%,
		rgba(7, 31, 51, 0.92) 42%,
		rgba(7, 31, 51, 0.72) 68%,
		rgba(7, 31, 51, 0.55) 100%
	);
	/* The CTA band puts its button at the RIGHT end, so unlike the hero this gradient
	   cannot fade away there — white text and a white border need the ground to stay
	   dark across the whole width. It still falls off enough to show the photograph. */
	--gradient-cta: linear-gradient(
		100deg,
		rgba(7, 31, 51, 0.94) 0%,
		rgba(7, 31, 51, 0.82) 45%,
		rgba(7, 31, 51, 0.68) 100%
	);

	/* -------------------------------------------------------------- typography */
	/* One family, Poppins, locked. Personality comes from weight and size contrast
	   rather than a second typeface -- 400 for copy, 600 for section headings, 700
	   for display. 600 and 700 are newly self-hosted; the old system had only 400 and
	   500, which is why every heading read as large body text. */

	--font-heading: "Poppins", "Segoe UI", system-ui, -apple-system, sans-serif;
	--font-body:    "Poppins", "Segoe UI", system-ui, -apple-system, sans-serif;

	--font-weight-regular:  400;
	--font-weight-medium:   500;
	--font-weight-semibold: 600;
	--font-weight-bold:     700;

	/* A real scale, ratio ~1.28, with display ABOVE h1 this time. */
	--text-display:    4rem;       /* 64px */
	--text-display-lh: 1.04;
	--text-display-ls: -0.02em;

	--text-h1:         2.75rem;    /* 44px */
	--text-h1-lh:      1.1;
	--text-h1-ls:      -0.015em;

	--text-h2:         2rem;       /* 32px */
	--text-h2-lh:      1.15;
	--text-h2-ls:      -0.01em;

	--text-h3:         1.375rem;   /* 22px */
	--text-h3-lh:      1.3;

	--text-lead:       1.25rem;    /* 20px, down from an unusable 28px */
	--text-lead-lh:    1.55;

	--text-body-lg:    1.0625rem;  /* 17px */
	--text-body-lg-lh: 1.65;

	--text-body:       1rem;       /* 16px */
	--text-body-lh:    1.6;

	--text-body-sm:    0.9rem;     /* 14.4px */
	--text-body-sm-lh: 1.5;

	--text-overline:   0.9375rem;  /* 15px. Sentence case, weight 600, NORMAL tracking.
	                                  The old eyebrow was uppercase with 0.08em tracking,
	                                  which is one of the standard tells of a generated
	                                  page. It is not coming back. */

	--text-nav:        1rem;
	--text-nav-lh:     1.5;

	--text-footer-heading:    0.9375rem;
	--text-footer-heading-lh: 1.4;

	/* Line length. The old container was 1440px with 16px gutters, which let body copy
	   run past 100 characters. */
	--measure:      68ch;
	--measure-lead: 44ch;

	/* ---------------------------------------------------------------- spacing */

	--space-1:  0.25rem;
	--space-2:  0.5rem;
	--space-3:  0.75rem;
	--space-4:  1rem;
	--space-5:  1.25rem;
	--space-6:  1.5rem;
	--space-7:  1.75rem;
	--space-8:  2rem;
	--space-10: 2.5rem;
	--space-12: 3rem;
	--space-14: 3.5rem;
	--space-16: 4rem;
	--space-20: 5rem;
	--space-24: 6rem;
	--space-32: 8rem;

	/* Section rhythm is deliberately NOT one value. Uniform 80px everywhere is what
	   made the old page read as an undifferentiated stack. */
	--section-pad-y:        6.5rem;   /* 104px, the default */
	--section-pad-y-tight:  4.5rem;   /* 72px, for a section that belongs with its neighbour */
	--section-pad-y-loose:  8.5rem;   /* 136px, around the one feature moment */
	--section-pad-y-mobile: 3.5rem;
	--footer-pad-y:         var(--space-20);

	/* ----------------------------------------------------------------- layout */

	--container-max:    75rem;     /* 1200px, down from 1440 */
	--container-gutter: 1.5rem;    /* 24px, up from 16 */
	--container-narrow: 46rem;

	/* ----------------------------------------------------------------- radii */
	/* Three steps that read as different, plus full. The old set was 22/24/32/88px:
	   22 and 24 are indistinguishable, which makes it noise rather than a scale.
	   Buttons are no longer pills -- a pill reads consumer app, and this audience is
	   business owners considering a confidential sale. */

	--radius-xs:   0.25rem;   /* 4px  — chips, small controls */
	--radius-sm:   0.5rem;    /* 8px  — buttons, cards */
	--radius-md:   0.875rem;  /* 14px — media panels, feature blocks */
	--radius-full: 9999px;    /* the utility pill in the header, and nothing else */

	--border-width-thin:  1px;
	--border-width-thick: 2px;

	/* The brass accent rule beside a section heading. */
	--accent-bar-width:  2.5rem;
	--accent-bar-height: 0.1875rem;

	/* ------------------------------------------------------------- elevation */
	/* Navy-tinted rather than grey, and differentiated by hierarchy. A single soft
	   grey shadow applied to every card is one of the commonest generic tells, so the
	   practice cards take a BORDER and no shadow, the media/feature blocks take -lg,
	   and -md is reserved for things that genuinely lift. */

	--shadow-sm: 0 1px 2px rgba(10, 31, 51, 0.06), 0 1px 1px rgba(10, 31, 51, 0.04);
	--shadow-md: 0 4px 12px rgba(10, 31, 51, 0.07), 0 1px 3px rgba(10, 31, 51, 0.05);
	--shadow-lg: 0 18px 40px rgba(10, 31, 51, 0.12), 0 4px 10px rgba(10, 31, 51, 0.06);

	/* ---------------------------------------------------------------- assets */

	--gnt-mark:         url("../images/gnt-logo-final.png");
	--gnt-mark-inverse: url("../images/gnt-logo-inverse.png");

	/* ---------------------------------------------------------------- motion */

	--duration-fast:   120ms;
	--duration-base:   200ms;
	--easing-standard: cubic-bezier(0.2, 0, 0, 1);
}

/* Breakpoints are Elementor's, 1024 and 767, plus a 479 tier that is ours alone.
   bin/apply-content.php writes Elementor's side so the two cannot drift apart. */

@media (max-width: 1024px) {
	:root {
		--text-display: 3rem;      /* 48px */
		--text-h1:      2.25rem;   /* 36px */
		--text-h2:      1.75rem;   /* 28px */
		--text-h3:      1.25rem;   /* 20px */
		--text-lead:    1.1875rem; /* 19px */

		--section-pad-y:       4.5rem;
		--section-pad-y-loose: 5.5rem;
		--section-pad-y-tight: 3.5rem;
	}
}

@media (max-width: 767px) {
	:root {
		--text-display: 2.25rem;   /* 36px */
		--text-h1:      1.875rem;  /* 30px */
		--text-h2:      1.5rem;    /* 24px */
		--text-lead:    1.125rem;  /* 18px */

		--section-pad-y:       var(--section-pad-y-mobile);
		--section-pad-y-loose: 4rem;
		--section-pad-y-tight: 2.75rem;
		--footer-pad-y:        var(--space-14);

		--container-gutter: 1.25rem;
	}
}
