/* ==========================================================================
   tokens.css — the single join between Claude Design and this codebase.

   Claude Design owns the values (design-system/tokens/*.css, imported verbatim
   below). This file adds two things and nothing else:

   1. The token NAMES from content/tokens.contract.json, aliased onto the
      design-system values, so every component can be written against the
      contract and still resolve to the real brand.
   2. Fluid type and space via clamp(), which the contract requires and the
      raw design-system export (fixed px + one breakpoint) does not provide.

   Two values are deliberately RAISED from the design-system export because the
   originals fail WCAG 2.2 AA at body size on the ivory base. docs/01 says to
   raise rather than ship a failing token. Both are marked A11Y below and both
   are re-checked on every build by scripts/check-contrast.mjs.

   Nothing else in this codebase contains a colour, a font size or a spacing
   value. If you are about to type one, put it here instead.
   ========================================================================== */

@import url("tokens/fonts.css");
@import url("tokens/colors.css");
@import url("tokens/typography.css");
@import url("tokens/spacing.css");
@import url("tokens/surfaces.css");
@import url("tokens/motion.css");

:root {
  /* ---------------------------------------------------------------- a11y */

  /* WAS an A11Y raise here, and no longer needs to be. stone-600 gives 3.31:1 on
     the ivory base, below the 4.5:1 floor for body text, so this file used to
     force stone-700. Claude Design has since adopted the same fix upstream:
     colors.css now ships --text-muted as stone-700 and keeps stone-600 as
     --text-decorative, for the logo linework where it is not text. The override
     is deleted rather than kept, because an override that no longer overrides
     anything reads as a live decision. check-contrast.mjs still proves the ratio. */

  /* A11Y RAISE: success-500 (#5A8A62) gives 3.94:1 on the ivory card ground —
     below the 4.5:1 floor, and it is used at 12px for the CredentialBlock's
     "Verified" marker, which is the smallest text in the component and the one
     making the strongest claim. #4A7350 is the same hue two steps darker: 5.36:1
     on ivory and 4.75:1 on cream, so it clears on both grounds a card can land
     on. Raised here rather than in the design-system export, and re-checked on
     every build by check-rendered.mjs, which is what found it. */
  --fg-success-500: #4A7350;

  /* A11Y RAISE: teal-600 gives 4.57:1 on ivory and drops below 4.5:1 on the
     cream and greige surfaces, where most links sit. teal-700 gives 7.03:1
     on ivory and clears the floor on every surface in the system.
     teal-600 is retained for FILLS (--surface-accent), where the pairing is
     ivory-on-teal at 4.73:1. */
  --text-accent: var(--fg-teal-700);
  --border-accent-text: var(--fg-teal-700);

  /* The rest state is now teal-700, so the design system's "hover darkens, never
     lightens" rule needs the hover step to move down a rung with it. */
  --accent-hover: var(--fg-teal-800);

  /* A11Y: WCAG 1.4.11 requires 3:1 for the boundary of an interactive control.
     taupe-500 gives 1.71:1 on ivory, so outline buttons, the menu toggle and the
     consent dialog use stone-600 (3.31:1). --border-strong keeps its original
     value for the decorative dotted leaders in the price rows. */
  --border-interactive: var(--fg-stone-600);

  /* ------------------------------------------------ text that follows its ground */

  /* Secondary and muted body text have to work on ANY band. A fixed token cannot
     do that: --text-secondary is a dark grey, correct on the ivory ground and
     effectively invisible on the dark one — which is exactly how three paragraphs
     in the homepage safety section rendered at 1.38:1 against a 4.5:1 floor.

     Deriving them from currentColor makes them follow whatever ground they land
     on, which is the same mechanism the design system uses for --eyebrow-color.
     The mixes are chosen so that on the ivory ground the result lands within a
     hair of the fixed tokens they replace: 82% of ink-900 resolves to roughly
     ink-800, and 68% to roughly stone-700. Nothing changes on light bands; dark
     bands stop being broken. */
  --text-secondary-adaptive: color-mix(in oklab, currentColor 82%, transparent);
  --text-muted-adaptive: color-mix(in oklab, currentColor 68%, transparent);

  /* ---------------------------------------------------- fluid type scale */

  /* Derived from the design-system values: the max is the desktop token, the
     min is the <900px token from spacing.css. Same values, continuous curve. */
  --text-display-1: clamp(2.75rem, 1.95rem + 3.20vw, 4.75rem);
  --text-display-2: clamp(2.25rem, 1.70rem + 2.20vw, 3.625rem);
  --text-display-3: clamp(1.875rem, 1.525rem + 1.40vw, 2.75rem);
  --text-display-4: clamp(1.625rem, 1.425rem + 0.80vw, 2.125rem);
  --text-heading: clamp(1.375rem, 1.275rem + 0.40vw, 1.625rem);
  --text-subheading: clamp(1.1875rem, 1.1375rem + 0.20vw, 1.3125rem);
  --text-body-lg: clamp(1.0625rem, 1.0125rem + 0.20vw, 1.1875rem);
  --text-body: clamp(1rem, 0.975rem + 0.10vw, 1.0625rem);
  --text-body-sm: 0.9375rem; /* 15px — the SmallPrint floor is 14px */
  --text-caption: 0.8125rem;
  --text-eyebrow: 0.75rem;

  /* ------------------------------------------------- fluid space & layout */

  --space-9: clamp(3.5rem, 2.60rem + 3.60vw, 6rem);
  --space-10: clamp(4rem, 2.67rem + 5.33vw, 8rem);
  --space-11: clamp(5rem, 3.33rem + 6.67vw, 10rem);
  --gutter: clamp(1.25rem, 1.05rem + 0.80vw, 1.5rem);
  /* Section rhythm. The design system specifies 128px desktop / 64px mobile;
     this is the same curve pulled in slightly, because without photography the
     bands are pure text and the full 128 reads as a gap rather than as air. */
  --band-y: clamp(3.5rem, 2.40rem + 4.40vw, 6.5rem);
  --header-height: clamp(4rem, 3.60rem + 1.60vw, 4.75rem);

  /* ------------------------------------- the contract in tokens.contract.json */

  /* colour */
  --fg-ink: var(--text-primary);
  --fg-muted: var(--text-muted);
  --fg-inverse: var(--text-inverse);
  --bg-base: var(--surface-page);
  --bg-raised: var(--surface-card);
  --bg-sunken: var(--surface-sunken);
  --bg-inverse: var(--surface-inverse);
  --accent: var(--surface-accent);
  --accent-soft: var(--surface-accent-soft);
  --rule: var(--border-hairline);

  /* NotePanel. Three visually distinct treatments that do not rely on colour:
     each variant also carries a stated label and a different border weight.
     critical is the darkest thing on the page by design — docs/04 requires it
     to outrank the hero for attention. */
  --note-neutral-bg: var(--surface-sunken);
  --note-neutral-fg: var(--text-primary);
  --note-neutral-rule: var(--border-subtle);
  --note-caution-bg: var(--fg-butter-100);
  --note-caution-fg: var(--text-primary);
  --note-caution-rule: var(--border-brass);
  --note-critical-bg: var(--fg-teal-800);
  --note-critical-fg: var(--fg-ivory-000);
  --note-critical-rule: var(--fg-butter-300);

  /* type */
  /* --font-display / --font-body come straight from typography.css */
  --step--1: var(--text-body-sm);
  --step-0: var(--text-body);
  --step-1: var(--text-body-lg);
  --step-2: var(--text-heading);
  --step-3: var(--text-display-3);
  --step-4: var(--text-display-2);
  --step-5: var(--text-display-1);
  --measure: var(--measure-prose);
  --measure-intro: 58ch;

  /* space */
  --space-3xs: var(--space-1);
  --space-2xs: var(--space-2);
  --space-xs: var(--space-3);
  --space-s: var(--space-4);
  --space-m: var(--space-5);
  --space-l: var(--space-6);
  --space-xl: var(--space-7);
  --space-2xl: var(--space-8);
  --space-3xl: var(--space-10);

  /* other */
  --radius: var(--radius-xs);
  --shadow-subtle: var(--shadow-xs);
  --transition: var(--dur-fast) var(--ease-calm);
  --container: var(--container-narrow);
  --container-wide: var(--container-max);

  /* Small geometry constants that are not part of the design-system export
     but must not be typed inline in a component. */
  --border-width-loud: 3px;
  --sign-size: 14px;
  --dot-size: 3px;
  --dot-gap: 6px;
  --ph-stripe: 10px;
  --ph-stripe-ink: rgba(42, 42, 38, 0.035);

  /* Footer text opacities raised to clear 4.5:1 on the deep teal band. */
  --footer-text: rgba(251, 248, 242, 0.88);
  --footer-quiet: rgba(251, 248, 242, 0.72);
  --footer-rule: rgba(251, 248, 242, 0.18);
}

/* The stylesheet is scoped under `.fga` so it can survive being pasted into a
   page builder. That leaves the document itself unstyled, which shows as the
   user agent's 8px body margin and a white gutter around the page. These two
   rules are the only unscoped ones in the project, and they set nothing a page
   builder would want to own. */
html {
  /* An in-page anchor must not land under the sticky header. */
  scroll-padding-top: calc(var(--header-height) + var(--space-s));
}
body {
  margin: 0;
  background: var(--bg-base);
}
