/* >>> GENERATED by tools/derive-palette.mjs — do not edit by hand <<< */
/* 46/46 contrast proofs passing. Re-run `node tools/derive-palette.mjs`
   after any change here; a value without a passing proof is not a token. */
:root {
  --flex-tokens-version: '46proofs-f7b5a988'; /* compare with flex-style to spot a stale copy */
  /* --- brand layer: fixed. Only Simon changes these. --- */
  --flex-brand-red: #EA0043; /* the official mark. oklch(0.594 0.238 18.4) */

  /* --- neutrals: warm axis (OKLCH hue 70), even lightness curve --- */
  --flex-neutral-25: #FDFCFC;
  --flex-neutral-50: #F8F7F6;
  --flex-neutral-100: #F1F0EF;
  --flex-neutral-200: #E4E3E1;
  --flex-neutral-300: #D1CFCD;
  --flex-neutral-400: #A6A4A2;
  --flex-neutral-500: #81807E;
  --flex-neutral-600: #6A6967;
  --flex-neutral-700: #514F4E;
  --flex-neutral-800: #343331;
  --flex-neutral-900: #201F1E;

  /* --- surfaces --- */
  --flex-paper: #FFFFFF; /* cards, tables, forms. Text lives here. */
  --flex-shell: #F8F7F6; /* the app background behind the paper */

  /* --- ink --- */
  --flex-ink-strong: #2D2B2A; /* headings — 14.09:1 */
  --flex-ink-body: #3D3C3B; /* body copy — 11.01:1 */
  --flex-ink-muted: #6D6C6A; /* labels, table headers — 5.25:1 */
  --flex-ink-faint: #8E8C8B; /* placeholder, disabled — non-text only */

  /* --- action: the one red, doing four jobs --- */
  --flex-action: #EA0043; /* filled primary bg; white label at 4.59:1 */
  --flex-action-pressed: #BD0034;
  --flex-red-ink: #D2003B; /* red *text*, links, icons — 5.52:1 */
  --flex-danger-ink: #B40031; /* validation, error borders — 7.04:1 */
  --flex-red-wash: #FFEFEF; /* danger-zone panel background */
  --flex-red-line: #C26569; /* danger-zone border */

  /* --- lines. Two, and they are not interchangeable. --- */

  /* --- inverse surface: dark chrome, INTERNAL TOOLS ONLY (support console, admin) --- */
  --flex-inverse-surface: #201F1E; /* header/sidebar on a staff tool. Never a merchant surface. */
  --flex-inverse-raised: #343331; /* hovered nav item, active chip */
  --flex-on-inverse: #FFFFFF; /* 16.46:1 */
  --flex-on-inverse-muted: #898786; /* 4.6:1 */

  --flex-meter-fill: #8B8988; /* progress/meter fill — 3.06:1 on its track. Never --flex-action. */
  --flex-border-strong: #82807F; /* inputs, switches, checkboxes — WCAG 1.4.11, 3.67:1 on shell */
  --flex-neutral-line: #82807F; /* the "off"/neutral pill border — 3.45:1 on sunken. Matches the status lines. */
  --flex-divider: #E4E3E1; /* decorative hairlines ONLY — 1.29:1, never an input */

  /* --- status. Hues 155 / 75 / 250 — all far from the brand at 18. --- */
  --flex-success-ink: #217749; /* 5.53:1 on paper */
  --flex-success-wash: #E5FAEB;
  --flex-success-line: #3E9060;
  --flex-warning-ink: #8F5F00; /* 5.52:1 on paper */
  --flex-warning-wash: #FFF1DF;
  --flex-warning-line: #AF7500;
  --flex-info-ink: #3E6C9A; /* 5.5:1 on paper */
  --flex-info-wash: #EBF5FF;
  --flex-info-line: #5584B5;

  /* --- focus. The brand red, which clears the 3:1 non-text floor on both surfaces. --- */
  --flex-focus: #EA0043;
}
/* <<< END GENERATED >>> */

/* ============================================================================
 * Hand-authored below. The generator preserves everything after the END marker.
 *
 * PRODUCT register — Portal Web, Partner Platform, Admin. Not the marketing site,
 * which keeps its own louder scale (flexrewards-web/src/styles/tokens.css).
 * Rationale for every choice here is in PRODUCT-UI.md.
 * ==========================================================================*/

:root {
  /* --- type ---------------------------------------------------------------
   * Inter for the interface, Clarika Geometric for the mark and for the one or
   * two display moments per app. Why not Clarika throughout: PRODUCT-UI.md §2.
   * Inter is SIL OFL, self-hosted, variable — one file covers 400-700. */
  --flex-font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI Variable Text',
    'Segoe UI', Roboto, sans-serif;
  --flex-font-brand: 'Clarika Geometric', var(--flex-font-ui);

  /* Money and any figure that appears in a column. Tabular figures keep digits on
   * a fixed advance so a ledger column aligns; slashed zero so 0 and O differ in a
   * merchant ID. This is not decoration — it is the commission ledger's legibility. */
  --flex-font-numeric: var(--flex-font-ui);
  --flex-numeric-features: 'tnum' 1, 'zero' 1;

  /* Fixed rem steps, not a fluid clamp. A dashboard is not a poster: type that
   * resizes with the viewport makes a data table reflow unpredictably, and the
   * partner is on a 13" laptop or a tablet, not a 4K billboard.
   *
   * Body is 16px, NOT the 14px that dense dashboards default to. Deliberate:
   * DESIGN-PRINCIPLES.md commits to a 65-year-old falling in love with this, and
   * 14px body is the first thing that breaks that promise. Density is bought back
   * with spacing and row height, never by shrinking the reading size. */
  --flex-text-micro: 0.8125rem;  /* 13px — table column headers, chip labels. The floor. */
  --flex-text-small: 0.875rem;   /* 14px — helper text, timestamps, secondary metadata */
  --flex-text-body: 1rem;        /* 16px — everything a partner actually reads */
  --flex-text-lead: 1.125rem;    /* 18px — card titles, the one-line answer on a summary */
  --flex-text-h3: 1.1875rem;     /* 19px — section headings inside a page */
  --flex-text-h2: 1.375rem;      /* 22px — page title */
  --flex-text-h1: 1.75rem;       /* 28px — screen title on a focused/empty state */
  --flex-text-display: 2.25rem;  /* 36px — sign-in, onboarding welcome. Clarika only. */

  --flex-lh-tight: 1.25;   /* headings */
  --flex-lh-snug: 1.4;     /* table cells, controls, single-line labels */
  --flex-lh-body: 1.55;    /* paragraphs */

  --flex-weight-regular: 400;
  --flex-weight-medium: 500; /* labels, table headers, button text */
  --flex-weight-semi: 600;   /* headings, emphasised figures */

  /* Headings only. Applying negative tracking to 13-16px UI text closes up the
   * letterforms at exactly the sizes where legibility matters most. */
  --flex-tracking-heading: -0.015em;
  --flex-tracking-micro: 0.02em; /* uppercase micro-labels need the opposite */

  /* --- space: 4px grid, no exceptions ------------------------------------ */
  --flex-sp-1: 0.25rem;  /* 4  */
  --flex-sp-2: 0.5rem;   /* 8  */
  --flex-sp-3: 0.75rem;  /* 12 */
  --flex-sp-4: 1rem;     /* 16 — the default gap between related things */
  --flex-sp-5: 1.5rem;   /* 24 — between cards, between form groups */
  --flex-sp-6: 2rem;     /* 32 — between page sections */
  --flex-sp-7: 3rem;     /* 48 */
  --flex-sp-8: 4rem;     /* 64 */

  /* --- radius: three values, each with one job -------------------------- */
  --flex-radius-control: 8px;  /* buttons, inputs, selects, chips-with-actions */
  --flex-radius-card: 12px;    /* cards, panels, dialogs, tables */
  --flex-radius-pill: 999px;   /* status pills and avatars ONLY — never a button.
                                * portal-web's pill buttons (borderRadius 20) are the
                                * single strongest 2020 tell in the whole interface. */

  /* --- density -----------------------------------------------------------
   * Two densities and a hard rule: `compact` may only apply to rows a partner
   * reads. Anything tapped at a counter stays at `comfortable`, because 44px is
   * the accessible target size (WCAG 2.2 SC 2.5.8 asks 24px minimum; 44 is the
   * usable one on glass with a queue forming). */
  --flex-control-h: 44px;       /* buttons, inputs — comfortable, the default */
  --flex-control-h-sm: 36px;    /* toolbar controls in a data-dense header */
  --flex-row-h: 52px;           /* table row, comfortable */
  --flex-row-h-compact: 40px;   /* ledger and log tables, opt-in */
  --flex-tap-min: 44px;         /* floor for anything touchable. Not negotiable. */

  /* --- elevation ---------------------------------------------------------
   * Borders do the work, not shadows. MUI v4's default elevation on every Paper is
   * why portal-web looks busy; a flat card with a real border reads calmer and
   * survives being printed or screenshotted. Shadow is reserved for things that
   * genuinely float above the page and must be dismissed. */
  --flex-shadow-none: none;
  --flex-shadow-popover: 0 4px 12px -2px rgb(34 30 26 / 0.10), 0 2px 4px -2px rgb(34 30 26 / 0.06);
  --flex-shadow-dialog: 0 16px 40px -8px rgb(34 30 26 / 0.18), 0 4px 12px -4px rgb(34 30 26 / 0.08);

  /* --- chrome dimensions -------------------------------------------------
   * Settled with Simon 2026-08-04 after an interactive real-estate test at 1280x690.
   *
   * The assistant is 420px and RESIDENT, not 300px and not summonable. Simon's call over my
   * recommendation, and his reasoning was better than mine: the 65-year-old this platform is
   * built for already uses WhatsApp, so chat is the interface he *knows* — the thing that
   * defeats him is a thirty-item nav. On that reading the assistant is the accessibility
   * mechanism, not the advanced feature, and it earns the space.
   *
   * 420 is close to free *if* the rail can collapse: 1280 - 56 - 420 - 32 = 772px of content,
   * which is more than the 746px a 300px panel leaves at the full 232px rail. It is only
   * expensive with both open. That is why the collapsible rail is not optional. */
  --flex-rail-w: 232px;          /* expanded — the default for a new partner */
  --flex-rail-w-mini: 56px;      /* collapsed — the partner's choice, remembered */
  --flex-assistant-w: 420px;     /* resident. Never below 380: see PRODUCT-UI.md §11 */
  --flex-assistant-w-min: 380px; /* the floor if it ever has to shrink */
  --flex-bp-assistant: 1180px;   /* below this the assistant becomes an overlay sheet */

  /* --- line weights -----------------------------------------------------
   * Added 2026-08-04: the Partner Platform needed a 4px left rule for a callout and
   * found that every `--flex-border-*` token is a *colour* — the only width in the
   * system was `--flex-focus-width`. So they invented one. Correct catch.
   *
   * Three weights, and the third is the whole point: an accent rule is how a callout
   * escalates WITHOUT a new colour. See PRODUCT-UI.md §8. */
  --flex-line: 1px;              /* every border and divider. There is no 2px border. */
  --flex-rule-accent: 3px;       /* the left rule on an escalated callout. Matches the
                                  * focus ring's weight so the app has one emphatic line. */
  --flex-meter-h: 8px;           /* progress/meter track height */

  /* --- definition lists -------------------------------------------------
   * The most repeated pattern on the account surface and it had no spec; they invented a
   * 168px label column, which is a good number. Ratified as a token, in rem so it scales
   * with the user's type size, and it stacks below --flex-bp-stack. */
  --flex-dl-label-w: 10.5rem;    /* 168px at default type size */
  --flex-dl-gap: var(--flex-sp-4);
  --flex-bp-stack: 34rem;        /* 544px — below this, two-column layouts stack */

  /* --- focus ring: one definition, every surface ------------------------ */
  --flex-focus-width: 3px;
  --flex-focus-offset: 2px;

  /* --- motion. Short, or it reads as lag on the fifth repetition. ------- */
  --flex-motion-fast: 120ms;
  --flex-motion: 180ms;
  --flex-ease: cubic-bezier(0.2, 0, 0.2, 1);
}

/* Respect the OS setting rather than animating regardless. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --flex-motion-fast: 1ms;
    --flex-motion: 1ms;
  }
}

/* --- semantic aliases -----------------------------------------------------
 * What component code is allowed to reference. A component naming
 * `--flex-neutral-700` or a hex literal is a defect; it names the *role* it
 * needs and the role is mapped here, once. */
:root {
  --flex-bg-app: var(--flex-shell);
  --flex-bg-card: var(--flex-paper);
  --flex-bg-sunken: var(--flex-neutral-100);   /* code blocks, wells, empty states */
  --flex-bg-hover: var(--flex-neutral-100);
  --flex-bg-selected: var(--flex-red-wash);
  --flex-bg-table-header: var(--flex-neutral-50);

  --flex-text-primary: var(--flex-ink-body);
  --flex-text-heading: var(--flex-ink-strong);
  --flex-text-secondary: var(--flex-ink-muted);
  --flex-text-disabled: var(--flex-ink-faint);
  --flex-text-link: var(--flex-red-ink);
  --flex-text-on-action: #FFFFFF;

  --flex-border-control: var(--flex-border-strong);
  --flex-border-card: var(--flex-neutral-200);
  --flex-border-hairline: var(--flex-divider);
}
