/*
 * Apertura site tokens (landing-design lane, 2026-10-15).
 *
 * One token layer for every NEW page type (pages.css imports nothing; pages link
 * tokens.css then pages.css after styles.css). All names are --ap-* so they can
 * never collide with the home page's own :root in styles.css (--ink, --paper,
 * --mint ...). styles.css is NOT rewritten and is NOT edited.
 *
 * PROVENANCE. Every value cites one of three sources, or is marked NEW with a
 * reason. No brand colour is invented.
 *   [S] web/marketing/src/styles.css  (the shipped home page; dark-first, warm ink, mint)
 *   [T] design/tokens.json            (shared Mac/Windows tokens; light + dark pairs, WCAG gated)
 *   [B] Apertura/Theme/BrandTokens.swift + tokens.json _meta.palette
 *                                      (brand.primary #0A84FF, brand.accent #30D158)
 *   NEW  a documented addition with the reason in the comment.
 *
 * SCHEME MODEL. Dark is the default, because the home page is dark-only
 * (styles.css `color-scheme: dark`) and a new page must not look like a different
 * site. Light applies when the OS asks for it (prefers-color-scheme: light) unless
 * the page says <html data-theme="dark">, or whenever it says data-theme="light".
 * The light block and the [data-theme="light"] block are the same declarations;
 * test/design-system.test.mjs fails if they drift apart.
 *
 * CHROME. The header and footer stay on the dark brand surface in BOTH schemes
 * (--ap-chrome-*), exactly like styles.css's hard-coded #090a0c header. This is why
 * a light page does not need a second header design and why home and new pages
 * share one header.
 */

:root {
  color-scheme: dark;

  /* ---- colour: surfaces --------------------------------------------------- */
  --ap-bg: #090a0c;            /* [S] --paper */
  --ap-surface: #111317;       /* [S] --paper-raised */
  --ap-surface-2: #171a1f;     /* [S] --paper-soft */
  --ap-sunken: #0f1215;        /* [T] surface.base dark: the quiet well under code/tables */

  /* ---- colour: text ------------------------------------------------------- */
  --ap-text: #f4f1e8;          /* [S] --ink */
  --ap-text-muted: #c8c4b8;    /* [S] --ink-muted */
  --ap-text-faint: #9c988c;    /* [S] --ink-faint */

  /* ---- colour: accent + status ------------------------------------------- */
  --ap-accent: #8ff2c6;        /* [S] --mint. Text-safe accent on dark. */
  --ap-accent-fill: #8ff2c6;   /* [S] --mint as a button/pill fill */
  --ap-on-accent: #090a0c;     /* [S] --paper on mint = 14.79:1 per styles.css */
  --ap-link: #8ff2c6;          /* [S] --mint */
  --ap-success: #30d158;       /* [T] status.success dark */
  --ap-warning: #ffc77b;       /* [S] --warning */
  --ap-danger: #ff8e8e;        /* [S] --danger */
  --ap-info: #7ec0ff;          /* [T] status.info dark */
  --ap-focus: #8ff2c6;         /* [S] :focus-visible outline is --mint */

  /* ---- focus ring ---------------------------------------------------------
     NEW (accessibility-polish lane, 2026-10-28). The ring used to be spelled
     `outline: 3px solid …; outline-offset: 3px` inline in four places, so the
     thickness and the gap could drift between the page body, the header, the
     footer and the cards. One token pair makes every ring the same ring, and
     `var(--ap-focus-ring-offset)` is what a scroll container negates for its
     inset ring. 3px is above the WCAG 2.2 focus-appearance floor (2px) and
     survives a 1px device pixel ratio. */
  --ap-focus-ring-width: 3px;  /* NEW: >= 2px, WCAG 2.2 2.4.13 */
  --ap-focus-ring-offset: 3px; /* NEW: the gap between control and ring */

  /* ---- colour: lines + edge ---------------------------------------------- */
  --ap-line: rgba(244, 241, 232, 0.16);        /* [S] --line */
  --ap-line-strong: rgba(244, 241, 232, 0.28); /* [S] --line-strong */
  --ap-fill-faint: rgba(255, 255, 255, 0.05);  /* [T] fill.faint dark */
  --ap-fill-subtle: rgba(255, 255, 255, 0.08); /* [T] fill.subtle dark */
  --ap-edge-light: inset 0 1px 0 rgba(244, 241, 232, 0.055); /* [S] --edge-light */

  /* ---- elevation ---------------------------------------------------------- */
  --ap-elev-1: 0 1px 2px rgba(0, 0, 0, .5), 0 4px 12px rgba(0, 0, 0, .26);  /* [S] --elev-1 */
  --ap-elev-2: 0 1px 2px rgba(0, 0, 0, .55), 0 8px 20px rgba(0, 0, 0, .3), 0 26px 50px rgba(0, 0, 0, .32); /* [S] --elev-2 */
  --ap-elev-3: 0 2px 4px rgba(0, 0, 0, .5), 0 12px 30px rgba(0, 0, 0, .36), 0 44px 90px rgba(0, 0, 0, .44); /* [S] --elev-3 */

  /* ---- hero glow (decorative, never text) -------------------------------- */
  --ap-glow: rgba(143, 242, 198, 0.09);        /* [S] .signal-dot halo alpha on --mint */
  --ap-glow-blue: rgba(10, 132, 255, 0.14);    /* [B] brand.primary #0A84FF at 14% */

  /* ---- chrome: header, mega menu, footer. Dark in BOTH schemes ----------- */
  --ap-chrome-bg: #090a0c;     /* [S] .site-header background */
  --ap-chrome-menu-bg: #101216; /* [S] .nav-links mobile panel background */
  --ap-chrome-text: #f4f1e8;   /* [S] --ink */
  --ap-chrome-muted: #c8c4b8;  /* [S] --ink-muted */
  --ap-chrome-line: rgba(244, 241, 232, 0.16); /* [S] --line */
  --ap-chrome-accent: #8ff2c6; /* [S] --mint (focus ring on chrome) */

  /* ---- type: families ----------------------------------------------------- */
  /* Latin stack [S] --sans. mono [S] --mono. The CJK stack is NEW: styles.css has
     no CJK family at all (it falls through to the platform default), so zh/ja text
     rendered in whatever the browser chose. PingFang SC + Microsoft YaHei are the
     pair backend/apertura_license/account_mail.py already ships for zh-Hans mail;
     the Hiragino/Yu Gothic/Meiryo trio is the standard platform set for ja
     (Mac, Windows 10+, Windows 7+). Noto Sans CJK is the Linux/Android fallback. */
  --ap-font-cjk-sc: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "Source Han Sans SC";
  --ap-font-cjk-jp: "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", "Meiryo", "Noto Sans CJK JP", "Source Han Sans JP";
  --ap-font-latin: "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI"; /* [S] --sans */
  --ap-font-sans: var(--ap-font-latin), var(--ap-font-cjk-sc), var(--ap-font-cjk-jp), sans-serif;
  --ap-font-mono: "SFMono-Regular", ui-monospace, "Cascadia Mono", monospace; /* [S] --mono */

  /* ---- type: modular scale -------------------------------------------------
     NEW: ratio 1.25 (major third) from a 1rem base. styles.css sizes are
     hand-tuned clamps (18px lead, 14px button, 13px caption) and the shared
     tokens.json type roles top out at 30px for the in-app UI; a marketing site
     needs a head-to-toe scale, and 1.25 keeps the existing 13/14/16/18 sizes
     on-grid (xs/sm/base/md) while giving 20/25/31/39/49/61 above them.
     Display sizes clamp so 390px never overflows. */
  --ap-fs-xs: 0.8125rem;   /* 13px [S] feature small / [T] body */
  --ap-fs-sm: 0.875rem;    /* 14px [S] nav, button */
  --ap-fs-base: 1rem;      /* 16px */
  --ap-fs-md: 1.125rem;    /* 18px [S] section lead */
  --ap-fs-1: 1.25rem;      /* 20 */
  --ap-fs-2: 1.5625rem;    /* 25 */
  --ap-fs-3: clamp(1.5625rem, 1.2rem + 1.6vw, 1.953rem);  /* 25 to 31 */
  --ap-fs-4: clamp(1.75rem, 1.2rem + 2.4vw, 2.441rem);    /* 28 to 39 */
  --ap-fs-5: clamp(2rem, 1.1rem + 3.8vw, 3.052rem);       /* 32 to 49: page h2 */
  --ap-fs-display: clamp(2.5rem, 1rem + 6.4vw, 4.768rem); /* 40 to 76: page h1 */
  --ap-fw-regular: 400;
  --ap-fw-medium: 500;
  --ap-fw-semibold: 600;   /* [T] title/headline weight */
  --ap-fw-bold: 680;       /* [S] .brand and .button weight */

  --ap-lh-body: 1.6;        /* >= 1.6 is the CJK floor the design-system test gates */
  --ap-lh-tight: 1.25;      /* [T] type.title lineHeight */
  --ap-lh-display: 1.08;    /* NEW: Latin display; CJK overrides below */
  --ap-lh-headline: 1.16;
  --ap-ls-display: -0.045em; /* NEW: between [S] -.065em hero and -.035em card h3 */
  --ap-ls-headline: -0.03em;
  --ap-ls-eyebrow: 0.12em;  /* [S] .eyebrow */
  --ap-measure: 68ch;       /* NEW: article line length; 60-75ch is the readable band */

  /* ---- spacing: 4px grid --------------------------------------------------- */
  --ap-space-1: 0.25rem;   /* 4  [T] */
  --ap-space-2: 0.5rem;    /* 8  [T] */
  --ap-space-3: 0.75rem;   /* 12 [T] */
  --ap-space-4: 1rem;      /* 16 [T] */
  --ap-space-5: 1.5rem;    /* 24 [T] */
  --ap-space-6: 2rem;      /* 32 [T] */
  /* 7 to 10 are NEW: tokens.json stops at 32 because it is for in-app panels. Page
     rhythm needs larger steps; they continue the 4px grid (48/64/96/128) and 8 is
     close to styles.css's 122px section padding. */
  --ap-space-7: 3rem;      /* 48 */
  --ap-space-8: 4rem;      /* 64 */
  --ap-space-9: 6rem;      /* 96 */
  --ap-space-10: 8rem;     /* 128 */
  --ap-section-y: clamp(4rem, 2.5rem + 6vw, 7.625rem); /* up to 122px [S] .section */

  /* ---- radii --------------------------------------------------------------- */
  --ap-radius-xs: 6px;     /* [T] radius.sm */
  --ap-radius-sm: 12px;    /* [S] --radius-sm */
  --ap-radius-md: 22px;    /* [S] --radius-md */
  --ap-radius-lg: 34px;    /* [S] --radius-lg */
  --ap-radius-pill: 999px; /* [S] .nav-cta */
  /* The app icon next to the wordmark, in the header AND the footer. One PNG, so one corner
     radius: the header shipped 9px and the footer 8px, and pages.css loads after styles.css
     on every page, so that same 30-34px icon had different corners at the top and the bottom
     of every page. Not a page-scale step (it is tuned to the icon's own artwork), so it is not
     an --ap-radius-<step>; the parity test treats it as a declared value, not a scale member. */
  --ap-radius-icon: 9px;   /* [S] .brand img, .footer-brand img */

  /* ---- motion --------------------------------------------------------------- */
  --ap-dur-fast: 120ms;    /* [T] motion.duration.fast */
  --ap-dur-base: 180ms;    /* [T] base; [S] transitions are .18s */
  --ap-dur-slow: 240ms;    /* [T] slow */
  --ap-dur-reveal: 420ms;  /* [T] springs.reveal response .42 s */
  --ap-ease-standard: cubic-bezier(0.2, 0, 0, 1);    /* [T] */
  --ap-ease-emphasized: cubic-bezier(0.16, 1, 0.3, 1); /* [T] */
  --ap-ease-exit: cubic-bezier(0.4, 0, 1, 1);         /* [T] */

  /* ---- layout: container widths for 390 / 768 / 1440 ------------------------
     Breakpoints are the ones styles.css already uses (720 and 980), so a new page
     and the home page reflow at the same widths. Media queries cannot read
     custom properties; the numbers are repeated in the @media rules below. */
  --ap-shell: min(1180px, calc(100vw - 48px)); /* [S] --shell, 1440 viewport => 1180 */
  --ap-prose: 46rem;                          /* NEW: 736px article column */
  --ap-sidebar: 15rem;                        /* NEW: docs sidebar, 240px */
  --ap-touch: 44px;                           /* Han 10-15: 44pt touch targets */

  /* NEW: the sticky header's resting height. It was the literal 72px repeated in
     three rules (the header itself, the docs sidebar's sticky offset and its
     max-height) plus a 64px twin in the 720px breakpoint. A skip link must also
     scroll its target clear of the sticky header, which needs the same number
     from CSS; one token keeps the four uses in step. */
  --ap-header-h: 72px;
}

@media (max-width: 980px) {
  :root { --ap-shell: min(100% - 36px, 820px); } /* [S] 768 viewport => 732 */
}

@media (max-width: 720px) {
  :root {
    --ap-shell: calc(100% - 28px); /* [S] 390 viewport => 362 */
    --ap-header-h: 64px;           /* the header wraps to two rows below 720 */
  }
}

/* CJK: the glyph fills its em box, so Latin tracking collides and the Latin display
   size orphans the last glyph. Same intent and same numbers as styles.css
   `:root:lang(zh-Hans), :root:lang(ja)` (ls -.02em, lh 1.14, headline -.01em/1.16),
   which test/cjk-display.test.mjs gates for the home page. */
:root:lang(zh-Hans), :root:lang(ja) {
  --ap-ls-display: -0.02em;
  --ap-lh-display: 1.14;
  --ap-ls-headline: -0.01em;
  --ap-lh-headline: 1.16;
  --ap-lh-body: 1.75;
  --ap-fs-display: clamp(2.25rem, 1rem + 4.4vw, 4.125rem); /* [S] --fs-hero ceiling 66px */
}

:root:lang(zh-Hans) { --ap-font-sans: var(--ap-font-cjk-sc), var(--ap-font-latin), var(--ap-font-cjk-jp), sans-serif; }
:root:lang(ja) { --ap-font-sans: var(--ap-font-cjk-jp), var(--ap-font-latin), var(--ap-font-cjk-sc), sans-serif; }

/* ---- light scheme -----------------------------------------------------------
   All light values come from tokens.json "light" columns [T]. Accent text on light
   is accent.default #0060C3, not the mint: mint on #F2F5FB is ~1.2:1. The dark
   page keeps the shipped mint. brand.primary #0A84FF is used only for fills. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --ap-bg: #f2f5fb;              /* [T] surface.base light */
    --ap-surface: #ffffff;         /* [T] surface.raised light */
    --ap-surface-2: #e8ebf1;       /* [T] surface.overlay light */
    --ap-sunken: #e8ebf1;          /* [T] surface.sunken light */
    --ap-text: #0f1215;            /* [T] text.primary light */
    --ap-text-muted: #494d54;      /* [T] text.secondary light */
    --ap-text-faint: #5f646a;      /* [T] text.tertiary light */
    --ap-accent: #0060c3;          /* [T] accent.default light */
    --ap-accent-fill: #0060c3;     /* [T] accent.fill */
    --ap-on-accent: #ffffff;       /* [T] text.onAccent */
    --ap-link: #0060c3;            /* [T] accent.default light */
    --ap-success: #007b15;         /* [T] status.success light */
    --ap-warning: #8d5e00;         /* [T] status.warning light */
    --ap-danger: #c42a2f;          /* [T] status.danger light */
    --ap-info: #004b98;            /* [T] status.info light */
    --ap-focus: #0060c3;           /* [T] accent.default light */
    --ap-line: rgba(15, 18, 21, 0.12);        /* [T] line.hairline light */
    --ap-line-strong: rgba(15, 18, 21, 0.28); /* [T] line.strong light */
    --ap-fill-faint: rgba(15, 18, 21, 0.04);  /* [T] fill.faint light */
    --ap-fill-subtle: rgba(15, 18, 21, 0.07); /* [T] fill.subtle light */
    --ap-edge-light: inset 0 1px 0 rgba(255, 255, 255, 0.8); /* [T] line.rim light */
    --ap-elev-1: 0 1px 2px rgba(15, 18, 21, 0.08);  /* [T] effects.elevation.1 light */
    --ap-elev-2: 0 4px 16px rgba(15, 18, 21, 0.10); /* [T] elevation.2 light */
    --ap-elev-3: 0 8px 28px rgba(15, 18, 21, 0.14); /* [T] elevation.3 light */
    --ap-glow: rgba(0, 96, 195, 0.08);       /* [T] accent.default light at 8% */
    --ap-glow-blue: rgba(10, 132, 255, 0.10); /* [B] brand.primary at 10% */
  }
}

:root[data-theme="light"] {
  color-scheme: light;
  --ap-bg: #f2f5fb;
  --ap-surface: #ffffff;
  --ap-surface-2: #e8ebf1;
  --ap-sunken: #e8ebf1;
  --ap-text: #0f1215;
  --ap-text-muted: #494d54;
  --ap-text-faint: #5f646a;
  --ap-accent: #0060c3;
  --ap-accent-fill: #0060c3;
  --ap-on-accent: #ffffff;
  --ap-link: #0060c3;
  --ap-success: #007b15;
  --ap-warning: #8d5e00;
  --ap-danger: #c42a2f;
  --ap-info: #004b98;
  --ap-focus: #0060c3;
  --ap-line: rgba(15, 18, 21, 0.12);
  --ap-line-strong: rgba(15, 18, 21, 0.28);
  --ap-fill-faint: rgba(15, 18, 21, 0.04);
  --ap-fill-subtle: rgba(15, 18, 21, 0.07);
  --ap-edge-light: inset 0 1px 0 rgba(255, 255, 255, 0.8);
  --ap-elev-1: 0 1px 2px rgba(15, 18, 21, 0.08);
  --ap-elev-2: 0 4px 16px rgba(15, 18, 21, 0.10);
  --ap-elev-3: 0 8px 28px rgba(15, 18, 21, 0.14);
  --ap-glow: rgba(0, 96, 195, 0.08);
  --ap-glow-blue: rgba(10, 132, 255, 0.10);
}

/* Explicit dark on a light OS: nothing to override, the :root block above is dark. */
:root[data-theme="dark"] { color-scheme: dark; }
