/*
 * Telyne — design tokens. THE ONLY FILE IN design/ THAT MAY CONTAIN A HEX.
 * ---------------------------------------------------------------------------
 * Extracted from Pixel Data's design system (see DESIGN-BENCHMARK.md) and
 * substituted to Telyne's palette. Every divergence from the benchmark is
 * listed in §12 of that document with the value chosen and the reason.
 *
 * Rules, in force across every page:
 *
 *   1. A component references an alias (--surface, --border, --text-secondary),
 *      never a ramp step and never a hex. Change a value here, every page
 *      follows. That is the whole point.
 *   2. Every font size comes from the twelve-step scale below. There are
 *      deliberate gaps in it — nothing between 15px and 18px, nothing between
 *      22px and 26px. Filling them is what produces "inconsistent text sizes".
 *   3. Every space comes from the twelve-step 4px scale. 7px, 9px, 13px, 18px,
 *      22px and 28px do not exist.
 *   4. Tints are composed here, once, with color-mix. Never write rgba() at a
 *      call site — the hex would then live in two places.
 */

:root {
  /* --- families ---------------------------------------------------------
   * Loaded from Google Fonts with preconnect and font-display: swap, so the
   * page is never blocked on them. Inter for UI, JetBrains Mono for code and
   * identifiers. */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    Helvetica, Arial, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas,
    monospace;

  /* --- type scale -------------------------------------------------------
   * Every display size is a clamp(). The upper bound is the designed value,
   * reached at 1440px; the lower bound is what a 320px phone gets. Type scales
   * with the viewport, so the layout never has to break around a headline —
   * this is the single most important structural property of the benchmark. */
  --text-display-xl: clamp(2.75rem, 0.85rem + 4.9vw, 5rem);   /* 44 → 80 */
  --text-display-l: clamp(2.25rem, 1.05rem + 3.35vw, 3.75rem); /* 36 → 60 */
  --text-display-m: clamp(2rem, 1.25rem + 2.05vw, 3rem);       /* 32 → 48 */
  --text-display-s: clamp(1.625rem, 1.05rem + 1.55vw, 2.5rem); /* 26 → 40 */
  --text-h1: clamp(1.375rem, 1.05rem + 0.8vw, 1.75rem);        /* 22 → 28 */
  --text-h2: clamp(1.1875rem, 1.05rem + 0.35vw, 1.375rem);     /* 19 → 22 */
  --text-h3: 1.125rem;                                          /* 18 */
  --text-lg: 1.125rem;                                          /* 18 */
  --text-body: 0.9375rem;                                       /* 15 */
  --text-sm: 0.8125rem;                                         /* 13 */
  --text-xs: 0.75rem;                                           /* 12 */
  --text-micro: 0.6875rem;                                      /* 11 */
  --text-stat: clamp(1.25rem, 0.85rem + 1vw, 1.75rem);          /* 20 → 28 */
  --text-stat-lg: clamp(1.75rem, 1.05rem + 1.75vw, 2.5rem);     /* 28 → 40 */

  --leading-display: 1.04;
  --leading-heading: 1.22;
  --leading-body: 1.6;

  --tracking-display: -0.035em;
  --tracking-heading: -0.02em;
  --tracking-body: -0.006em;
  --tracking-caps: 0.09em;

  /* --- neutrals ---------------------------------------------------------
   * The ramp is REVISION-1 §1 verbatim; no value here has been altered.
   *
   * Measured, though: ink-400 (#A7B1BF) is 2.05:1 on white and ink-500
   * (#7A8798) is 3.65:1, so neither clears AA 4.5:1 for text. §1 asks that
   * "ink-500 and darker must clear WCAG AA on white" and, as supplied, it does
   * not. Both stay as given — they are correct for dividers, icon washes and
   * non-text marks — but --text-muted resolves to ink-600 (7.29:1) so that no
   * text on the site is ever set in a colour that fails. Raised in the report.
   * ink-600 7.29:1 · ink-700 11.06:1 · ink-900 17.66:1. */
  --grey-0: #ffffff;
  --grey-25: #fcfdfe;
  --grey-50: #f8fafc;
  --grey-100: #f3f6fa;
  --grey-200: #e4e9ef;
  --grey-300: #d3d9e1;
  --grey-400: #a7b1bf;
  --grey-500: #7a8798;
  --grey-600: #46586e;
  --grey-700: #21384f;
  --grey-800: #12283f;
  --grey-900: #08192e;

  /* Dark ink — for the code panel and any dark band. */
  --ink-950: #030c17;
  --ink-900: #05121f;
  --ink-880: #08192e;
  --ink-850: #0a1d33;
  --ink-800: #0d2340;
  --ink-750: #112a4b;
  --ink-700: #163254;
  --ink-650: #1b3d63;
  --ink-600: #21384f;
  --ink-550: #2c4b68;
  --ink-500: #3a5d80;

  /* --- brand ------------------------------------------------------------ */
  --brand-50: #ebf4ff;
  --brand-100: #d6e8ff;
  --brand-200: #a8ccff;
  --brand-300: #68a7ff;
  --brand-400: #2882ff;
  --brand-500: #0054f0;
  --brand-600: #0a4bd4; /* PRIMARY — buttons, links, focus */
  --brand-700: #073ca6; /* pressed */
  --brand-800: #08327e;
  --brand-900: #0a2a60;

  /* --- accents ----------------------------------------------------------
   * Six identity marks for the capability areas and the four activation
   * states. Restrained by design: the brand ramp does the work. */
  --accent-cyan: #00b8d9;
  --accent-teal: #009ca9;
  --accent-coral: #ff6a45;
  --accent-amber: #e08a00;
  --accent-green: #0ba36f;

  --tint-azure: #ebf4fe;
  --tint-cyan: #e4f8fc;
  --tint-brand: #d6e8fd;
  --tint-teal: #e4f7f9;
  --tint-coral: #fff0ec;
  --tint-amber: #fff6e5;
  --tint-green: #e6f7f1;

  /* The neutral state tint. The comparison matrix has three states — covered,
   * in part, not offered — and "in part" was set in amber, which is the palette's
   * warning hue. A partial capability is information, not a caution, and amber
   * was making one supplier category look like a hazard. The grey ramp is
   * already blue-weighted, so this reads as a considered neutral rather than a
   * disabled state. */
  --tint-neutral: #e4e9ef;

  /* --- text weights of each accent, for use ON its own tint --------------
   * The bright signal hues are marks, not text: cyan is 2.31:1 on white and
   * green 3.24:1, so setting an 11px state chip in them fails AA outright.
   * These are the darkened weights, each measured against the tint it sits on
   * and each clearing 4.5:1. The bright hue stays for dots, connector lines,
   * gradients and the platform illustration, where nothing is read. */
  --on-azure: #0a4396; /* 8.38:1 on --tint-azure */
  --on-cyan: #075c6b;  /* 6.95:1 on --tint-cyan  */
  --on-teal: #00676f;  /* 5.99:1 on --tint-teal  */
  --on-green: #076b4a; /* 5.90:1 on --tint-green */
  --on-coral: #a8341a; /* 5.97:1 on --tint-coral */
  --on-amber: #8a5400; /* 5.84:1 on --tint-amber */
  --on-neutral: #46586e; /* 5.97:1 on --tint-neutral */

  /* --- gradients — the one place cyan appears at strength ---------------
   * Never more than one visible at a time.
   *
   * Split by whether text sits on top, because the specified cyan end is
   * 2.37:1 against white and the coral end 2.84:1. Both are fine behind
   * nothing and unusable behind a label.
   *
   *   --gradient-signal / --gradient-accent  §1 verbatim. Decorative only:
   *       the aurora, the platform illustration. No text may sit on either.
   *   --gradient-primary                     carries the button label, so its
   *       far end is #00788D. White measures 5.10:1 at the azure end and
   *       5.16:1 at the cyan end, and never drops below 5.10:1 anywhere in
   *       between, so the label is legible at every point of the hover sweep. */
  --gradient-signal: linear-gradient(100deg, #0054f0 0%, #00b8d9 100%);
  --gradient-accent: linear-gradient(100deg, #0054f0 0%, #ff6a45 100%);
  --gradient-primary: linear-gradient(100deg, #0054f0 0%, #00788d 100%);
  --gradient-primary-end: #00788d;

  /* --- semantics --------------------------------------------------------
   * danger never doubles as "down" — it means a problem, nothing else. */
  --success-500: #0ba36f;
  --success-600: #0ba36f;
  --success-700: #09835a;
  --success-50: #e6f7f1;
  --warn-500: #e08a00;
  --warn-600: #a86800;
  --warn-50: #fff6e5;
  --danger-500: #d6224b;
  --danger-600: #b01a3d;
  --danger-50: #fdecef;

  /* --- aliases — components reference ONLY these ------------------------ */
  --bg: var(--grey-0);
  --bg-alt: var(--grey-100);
  --bg-sunken: var(--grey-50);
  --surface: var(--grey-0);
  --surface-raised: var(--grey-0);
  --surface-hover: var(--grey-50);
  --border: var(--grey-200);
  --border-strong: var(--grey-300);
  --text: var(--grey-900);
  --text-secondary: var(--grey-600);
  /* ink-500 measures 3.65:1 on white — below AA. Muted text uses ink-600. */
  --text-muted: var(--grey-600);
  --text-inverse: var(--grey-0);
  /* brand-500 is 5.10:1 on white, so it clears AA for body text as well as
   * large; brand-600 at 6.90:1 is used for links per §1 all the same. */
  --link: var(--brand-600);
  --focus-ring: var(--brand-500);
  --focus-width: 3px;
  --focus-offset: 2px;
  --eyebrow-text: var(--brand-700);
  /* Comments on the dark code panel. ink-500 is 2.30:1 there — unreadable. */
  --code-comment: #7a94ad; /* 5.01:1 on --ink-800 */

  /* --- composed tints --------------------------------------------------- */
  --tint-brand-08: color-mix(in srgb, var(--brand-600) 8%, transparent);
  --tint-brand-10: color-mix(in srgb, var(--brand-600) 10%, transparent);
  --tint-brand-12: color-mix(in srgb, var(--brand-600) 12%, transparent);
  --ring-brand-25: color-mix(in srgb, var(--brand-600) 25%, transparent);
  --ring-brand-30: color-mix(in srgb, var(--brand-400) 30%, transparent);
  --on-dark-06: color-mix(in srgb, var(--grey-0) 6%, transparent);
  --on-dark-10: color-mix(in srgb, var(--grey-0) 10%, transparent);
  --on-dark-18: color-mix(in srgb, var(--grey-0) 18%, transparent);
  --on-dark-45: color-mix(in srgb, var(--grey-0) 45%, transparent);
  --on-dark-70: color-mix(in srgb, var(--grey-0) 70%, transparent);
  --scrim: color-mix(in srgb, var(--grey-900) 45%, transparent);

  /* --- spacing — 4px base, twelve values, nothing else ------------------- */
  /* A half-step. A 4px base has no value for pill padding or a 2px optical
   * nudge, and the audit found 22 literal 2px margins and 30 literal 2px
   * paddings sitting off the scale as a result. Naming it keeps them on the
   * scale; rounding them to 4px would have changed every pill's height. */
  --space-05: 0.125rem;
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;

  /* --- radii ------------------------------------------------------------ */
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-pill: 999px;

  /* --- elevation --------------------------------------------------------
   * Restrained. There is no shadow here you would notice on its own — the 1px
   * border does the work, and the shadow only stops a card sitting flat. */
  --shadow-xs: 0 1px 2px rgba(8, 25, 46, 0.05);
  --shadow-sm: 0 1px 3px rgba(8, 25, 46, 0.07), 0 1px 2px rgba(8, 25, 46, 0.04);
  --shadow-md: 0 6px 16px -4px rgba(8, 25, 46, 0.1), 0 2px 6px -2px rgba(8, 25, 46, 0.05);
  --shadow-lg: 0 18px 40px -12px rgba(8, 25, 46, 0.16), 0 6px 14px -6px rgba(8, 25, 46, 0.08);
  --shadow-brand: 0 10px 26px -10px rgba(18, 104, 227, 0.5);
  --shadow-dark: 0 24px 60px -20px rgba(0, 0, 0, 0.75);

  /* --- motion ----------------------------------------------------------- */
  --duration-instant: 80ms;
  --duration-fast: 140ms;
  --duration-base: 200ms;
  --duration-slow: 300ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);

  /* --- layout ----------------------------------------------------------- */
  --container-max: 1280px;
  --container-wide: 1560px;
  --container-prose: 46rem;
  --nav-h: 68px;
}

/* Reduced motion is handled twice — here at the token level, and again as a
 * global override in components.css. Anything added later is covered by the
 * second one whether or not it uses these tokens. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-instant: 1ms;
    --duration-fast: 1ms;
    --duration-base: 1ms;
    --duration-slow: 1ms;
  }
}

/* === capability-page tokens: generated by tools/extract-capability-css.js — do not edit by hand === */
/* Lifted from the approved eSIM design reference. Namespaced --cap-* because
 * --bg, --brand-50, --brand-100 and --brand-600 already exist above with
 * different values, and redefining those would restyle every page. */
:root {
  --cap-ink: #08192E;
  --cap-ink2: #12283F;
  --cap-ink3: #1C3550;
  --cap-body: #4A5C72;
  /* WCAG AA, founder ruling 7 September 2026. Was #8593A5, which measured */
  /* 3.13:1 on --grey-0 and 3.02:1 on --cap-bg. This carries real prose -- */
  /* breadcrumbs, .cp-micro lines, spec labels -- so AA is not negotiable on it. */
  /* Now 4.78:1 and 4.61:1. Hue and saturation are unchanged; only lightness */
  /* moved, and it moved past 4.5 rather than onto it, because a value that */
  /* measures 4.50 in one engine measures 4.49 in another. */
  --cap-muted: #647488;
  --cap-line: #E6EAF0;
  --cap-bg: #FAFBFD;
  --cap-white: #fff;
  --cap-brand: #0054F0;
  --cap-brand-600: #0A45C8;
  --cap-brand-100: #D3E5FF;
  --cap-brand-50: #EEF5FF;
  --cap-cyan: #00B8D9;
  --cap-green: #0BA36F;
  --cap-green-50: #E9F8F2;

  /* TEXT-SAFE VARIANTS OF THE TWO BRAND ACCENTS.
   *
   * Founder ruling, 7 September 2026: --cap-cyan and --cap-green keep their
   * hex. They are brand, they are used decoratively — arcs, rules, fills,
   * chips — and darkening a brand accent to satisfy a rule damages the palette
   * to fix something the instance's own treatment solves.
   *
   * But three instances put real text in those colours and measured below AA:
   *
   *     .cp-lcarc "Resume"        cyan on white            2.37:1
   *     .cp-state--live "Live"    green on --cap-green-50  2.96:1
   *     .cp-ct.cp-done "04"       white ON green           3.24:1
   *
   * Type weight cannot rescue any of them: large text still needs 3.0:1 and
   * two of the three are below even that. So each instance gets a text-safe
   * variant, and the brand tokens are untouched. Hue and saturation are the
   * accent's; only lightness moved.
   *
   * --cap-green-700 serves both green cases: as text on the tint it measures
   * 4.60:1, and as the background under white text 5.04:1. */
  --cap-cyan-text: #008097;    /* on --cap-white  4.63:1 */
  --cap-green-700: #097F56;    /* text on --cap-green-50 4.60:1; white on it 5.04:1 */
  /* --on-teal #00676F is the teal-on-light token and stays. On the dark code
   * panel it measured 2.38:1 against --ink-800, the worst pair on the site,
   * and it carries code strings — the values a developer reads. Same remedy
   * as the two accents: the token keeps its hex and the one instance that
   * puts text on the dark panel gets a variant. Lightened, not darkened,
   * because it sits on ink. */
  --on-teal-ink: #009AA6;      /* on --ink-800  4.62:1 */
  --cap-red: #C8434E;
  --cap-amber: #D9860A;
  --cap-r-m: 10px;
  --cap-r-l: 14px;
  --cap-max: 1160px;
  --cap-note: #7189A5;  /* placeholder and small print on the deep CTA band */
  --cap-line-hover: #C7D6EA;  /* border on hover: .btn-g, .path, .route */
  --cap-ink4: #26405C;  /* field and ghost-button surface inside the deep band */
  --cap-code-string: #8ED8A8;  /* string literal in a code sample */
  --cap-code-param: #5FD3EC;  /* parameter name in a code sample */
  --cap-label-cyan: #7FD6E8;  /* group label and coverage call on a deep ground */
  --cap-on-deep-soft: #9FB0C4;  /* secondary text on the deep CTA band */
  --cap-btn-d-hover: #E9F0FA;  /* hover fill of the light button on the deep band */
  --cap-field-border: #D7DEE9;  /* input border in the launch-list field */
  --cap-line-strong: #DDE4EE;  /* the configurator's outer border */
  --cap-dot-border: #C7D2E0;  /* the unselected option dot */
  --cap-muted-deep: #5A7590;  /* profile-card footer labels */
  --cap-call-text: #8093A8;  /* the one-line call under the configurator */
  --cap-code-keyword: #FF9878;  /* HTTP verb and numeric literal in a code sample */
  /* WCAG AA, same ruling. Was #5A6E85 on --cap-ink at 3.37:1. A comment line in */
  /* a code sample is prose a developer reads, so it meets AA like any other. */
  /* Now 4.60:1, lightened rather than darkened because it sits on the dark */
  /* panel. Hue and saturation unchanged. */
  --cap-code-comment: #6F849D;  /* comment line in a code sample */
  --cap-call-accent: #FF9E64;  /* the GET verb in the coverage call */
  --cap-code-text: #8FA2B8;  /* body text of a code block */
  --cap-nolist-note: #8FA6BE;  /* the sub-line in the no-minimum list */
}
/* === end capability-page tokens === */
