/* ============================================================
   @bp-labs-tech/design — DESIGN TOKENS
   ------------------------------------------------------------
   PORTED VERBATIM from the V1 engine (`_engine/shared.css`,
   token vocabulary locked Apr 27 2026). Values here are the
   locked design contract — changing one is an operator design
   decision, NOT a refactor (web-kit CLAUDE.md rule 6).
   The type, line-height, control and page-frame values are
   B-01's (operator 2026-10-27, BP-1795): touch vs desktop by
   pointer, public sizes and margins by window width.

   Brand accent: set [data-brand="<slug>"] on <html>.
   9 brands: aa · butzpeteza · bplabs · fflo · ffit · ffide ·
             ffaro · ffuse · ffree
   Theme: set [data-theme="light|dark"] on <html>.

   To add a brand: append a block to the brand-accent section
   AND its dark-mode --accent-text override below.
   ============================================================ */

:root {
  /* ── Cyan ramp (shared across ecosystem) ─────────────── */
  --cyan-50: #eaf6fb;
  --cyan-100: #d1edf7;
  --cyan-300: #5cc9ea;
  --cyan-500: #009dd3;
  --cyan-600: #007daa;
  --cyan-900: #003d52;

  /* ── Brand accent constants (one per brand) ──────────── */
  --orange: #f6801f; /* aa */
  --electric: #00f0ff; /* fflo, butzpeteza */
  --green: #2a9d5c; /* ffide */
  --sapphire: #2563eb; /* ffit */
  --violet: #7c3aed; /* ffaro */
  --gold: #f59e0b; /* ffuse */
  --coral: #fb7185; /* ffree */

  /* ── Per-brand colour aliases ─────────────────────────
     BUGFIX — none of these exist in the V1 engine, and that is
     a live defect there, not a porting gap. Each is READ by
     engine rules but DEFINED nowhere in the V1 repo:

       --ffide-green      .trust-ring (conic-gradient + .score),
       --ffide-green-50   .directory-verified, .vc-check,
                          .kyc-step.done, .product-tile-glyph.ffide
       --aa-orange        .vc-stars, .product-tile-glyph.aa
       --aa-cyan          .product-tile-glyph.aa
       --fflo-cyan        .product-tile-glyph.fflo
       --fflo-electric    .product-tile-glyph.fflo
       --ffit-indigo      .product-tile-glyph.ffit

     An undefined custom property with NO fallback invalidates
     the entire declaration at computed-value time. So in V1:
     the ffide trust ring paints no arc at all, the verified
     ticks fall back to body colour, the rating stars lose their
     colour, and four of the seven product tiles (aa, fflo,
     ffide, ffit) render no gradient — the three that do work
     (ffree/ffuse/ffaro) only survive because they hardcode hex.
     Porting the hole verbatim would ship the same broken UI to
     every V2 surface.

     Not design decisions: each name states its own intent and
     resolves to a colour already in the palette above, so no
     new colour enters the system. The gradients they feed match
     the locked spec (aa = orange→cyan; fflo = cyan→electric).
     The ffide tint mirrors ffide's own --accent-50 below.

     `--portal-purple`, `--flagblue` and `--flagred` are also
     undefined in the engine but are read WITH fallbacks
     (`var(--flagblue, #0038A8)`), so they render correctly and
     need nothing here.

     These should be fixed in V1's _engine too. */
  --ffide-green: var(--green);
  --ffide-green-50: rgba(42, 157, 92, 0.1);
  --aa-orange: var(--orange);
  --aa-cyan: var(--cyan-500);
  --fflo-cyan: var(--cyan-500);
  --fflo-electric: var(--electric);
  --ffit-indigo: var(--sapphire);

  /* ── Surface + ink ───────────────────────────────────── */
  --canvas: #fafafa;
  --surface: #ffffff;
  --surface-2: #f5f5f5;
  --surface-3: #ebebeb;
  --ink: #1e1e1e;
  /* THE FOURTH SURFACE IS THE ONE THAT CATCHES THESE OUT. #6b7280 cleared 4.5
     on surface, canvas and surface-2, then read 4.06:1 on surface-3 — and
     surface-3 is exactly where muted text lands: a chip, a table's zebra band,
     a disabled row. #636976 reads 5.51 / 5.28 / 5.05 / 4.62, passing on ALL
     FOUR rather than on the three anyone thinks to check.
     Operator ruling LIBRARY, 2026-09-27 (AF-180 Q1–Q4), for every brand.
     L-09 (operator 2026-10-27, UI/UX review): muted text goes darker still,
     #474d5a, 8.5:1 on white, so muted and subtle (below) are no longer two
     names for nearly one grey. Dark keeps #b4b4bc. */
  --ink-muted: #474d5a;
  /* TERTIARY TEXT, AND IT HAS TO BE READABLE. This was #9ca3af — 2.54:1 on
     white, which fails even WCAG's 3:1 large-text floor — while ~55 rules
     across this package colour TEXT with it. V1's design system documents this
     exact token as passing AA and gives the value: #71717A is 4.83:1 on
     surface and 4.63:1 on canvas. The dark value was always fine (5.45:1).
     Raised again by the same 2026-09-27 ruling and for the same surface-3
     reason: #71717a was 4.05 there; #686870 is 4.63. */
  --ink-subtle: #686870;
  /* What the old value was actually fit for: disabled controls and decorative
     fills, both outside WCAG 1.4.3, which exempts inactive components. Kept at
     the original lightness so nothing that was a BACKGROUND suddenly darkens. */
  --ink-disabled: #9ca3af;
  --border: #e5e7eb;
  --border-strong: #d1d5db;
  /* L-09: the outline of a text field, select or other input. Its edge is the
     only thing that shows where the box is, so it clears 3:1 (WCAG 1.4.11)
     on every light surface: 3.78 on white, 3.17 on surface-3, where
     --border-strong does not. The Library carries the same value. */
  --border-input: #80838d;

  /* ── Semantic ────────────────────────────────────────── */
  /* L-09 (2026-10-27): the three status hues darkened in LIGHT so a status dot
     or icon reads 3:1+ on white; dark keeps the old values (the dark block). */
  --success: #059669;
  --success-50: #ecfdf5;
  --success-text: #047857;
  --warning: #c26a06;
  --warning-50: #fffbeb;
  --danger: #ef4444;
  --danger-50: #fef2f2;
  --info: #0089b8;
  --info-50: #eaf6fb;

  /* ── Type scale (B-01, operator 2026-10-27, BP-1795) ────
     ONE SCALE, TWO DENSITIES. The values in :root are DESKTOP (a mouse-first
     computer); `@media (pointer: coarse)` below swaps in TOUCH. The Figma
     Library (sG2YVRmFBFxITjP917tLC0) carries the same table.

       token       role                            touch    desktop
       --fs-2xl    Page title                      28/36    24/32
       --fs-xl     Section title                   22/28    20/28
       --fs-lg     Card title          (--lh-lg)   18/24    16/24
                   Long reading  (--lh-lg-loose)   18/28    16/24
       --fs-base   Body, Row title, Label          16/24    14/20
       --fs-sm     Small, Label small, Mono        14/20    12/16
       --fs-xs     Overline                        12/16    11/16

     Every size has a line height of the same name (--lh-*): set them as a
     pair. Weights are 400 and 600; 700 belongs to the public headline and
     the public title only (below).

     --fs-3xl / --fs-4xl have NO role in this scale. They keep their old
     values for the components that still read them; a public page uses
     --fs-headline and --fs-public-title instead. */
  --fs-xs: 11px;
  --fs-sm: 12px;
  --fs-base: 14px;
  --fs-lg: 16px;
  --fs-xl: 20px;
  --fs-2xl: 24px;
  --fs-3xl: 36px;
  --fs-4xl: 48px;

  --lh-xs: 16px;
  --lh-sm: 16px;
  --lh-base: 20px;
  --lh-lg: 24px;
  --lh-lg-loose: 24px;
  --lh-xl: 28px;
  --lh-2xl: 32px;

  /* Public pages: by WINDOW WIDTH, not by device (the 600 and 1024
     breakpoints below). One headline (the hero) per page; the public title
     is a section headline or a big stat. Both are the only 700s. */
  --fs-headline: 36px;
  --lh-headline: 44px;
  --fs-public-title: 28px;
  --lh-public-title: 36px;

  /* ── Spacing (4px base grid) ─────────────────────────── */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-10: 40px;
  --sp-12: 48px;
  --sp-16: 64px;
  --sp-20: 80px;
  --sp-24: 96px;

  /* ── Radius ──────────────────────────────────────────── */
  --r-sm: 4px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-xl: 16px;
  --r-2xl: 24px;
  --r-full: 9999px;

  /* ── Elevation ───────────────────────────────────────── */
  --sh-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --sh-md: 0 2px 8px rgba(0, 0, 0, 0.06);
  --sh-lg: 0 8px 24px rgba(0, 0, 0, 0.08);
  --sh-xl: 0 16px 48px rgba(0, 0, 0, 0.12);

  /* ── Motion ──────────────────────────────────────────── */
  --t-fast: 150ms;
  --t-med: 250ms;
  --t-slow: 400ms;
  --ease: cubic-bezier(0.4, 0, 0.2, 1);

  /* ── Layout ──────────────────────────────────────────── */
  --sidebar-w: 260px;
  --topbar-h: 56px;

  /* Page frame (B-01), by window width: under 600 / from 600 / from 1024.
     --page-margin is the space at each side of the page, --gutter the gap
     between columns; no page's content grows wider than --content-max. */
  --page-margin: 16px;
  --gutter: 16px;
  --content-max: 1440px;

  /* Controls (B-01), DESKTOP here and TOUCH under `pointer: coarse`:
       --control-h      sm   32 | touch 40   label: --fs-sm   (Label small)
       --control-h-md   md   40 | touch 48   label: --fs-base (Label) — the default
       --control-h-lg   lg   48 | touch 56   label: --fs-base (Label)
       --min-target     the smallest thing a pointer may hit: 24 | touch 44
     The name --control-h is kept for the SMALL size so nothing that reads it
     breaks; a default button reads --control-h-md. */
  --control-h: 32px;
  --control-h-md: 40px;
  --control-h-lg: 48px;
  --min-target: 24px;

  /* L-09: the :focus-visible ring, drawn 2px, in every brand's text-safe
     accent (4.5:1 or more), never a raw accent fill: aa's orange reads
     2.5:1 as a ring (operator, 2026-10-27). */
  --focus-ring: var(--accent-text);

  /* ── Default brand accent (overridden by [data-brand]) ─
     Components read:
       --accent       solid colour for fills/borders/glyphs (any contrast)
       --accent-text  text-safe colour for type/icons on light surface
                      (WCAG AA against #FAFAFA). Differs from --accent only
                      for brands whose accent is too light to read as text
                      (fflo/butzpeteza electric, ffuse gold, ffree coral).
       --accent-50    10% tinted background for chips/callouts/hover
       --accent-600   hover/active darker shade
       --accent-grad  hero gradient (cyan→accent for ff brands;
                      orange→cyan for AA per locked spec) ────────── */
  --accent: var(--cyan-500);
  --accent-text: var(--cyan-600); /* always read --accent-text for type */
  --accent-fg: #fff; /* foreground when accent is BACKGROUND
                                      (e.g., on .btn-primary). Override per-brand
                                      for accents too light to carry white text. */
  --accent-50: var(--cyan-50);
  --accent-600: var(--cyan-600);
  --accent-grad: linear-gradient(135deg, var(--cyan-500), var(--electric));
}

/* ── Touch (B-01) ──────────────────────────────────────────
   A coarse pointer — a finger — gets the TOUCH column of the type and
   control tables above. Anything else (a mouse, a trackpad, no pointer at
   all) keeps the desktop values in :root. */
@media (pointer: coarse) {
  :root {
    --fs-xs: 12px;
    --fs-sm: 14px;
    --fs-base: 16px;
    --fs-lg: 18px;
    --fs-xl: 22px;
    --fs-2xl: 28px;

    --lh-xs: 16px;
    --lh-sm: 20px;
    --lh-base: 24px;
    --lh-lg: 24px;
    --lh-lg-loose: 28px;
    --lh-xl: 28px;
    --lh-2xl: 36px;

    --control-h: 40px;
    --control-h-md: 48px;
    --control-h-lg: 56px;
    --min-target: 44px;
  }
}

/* ── Public pages and the page frame, by window width (B-01) ─
   The two breakpoints, 600 and 1024, and no others. */
@media (min-width: 600px) {
  :root {
    --fs-headline: 44px;
    --lh-headline: 52px;
    --fs-public-title: 32px;
    --lh-public-title: 40px;
    --page-margin: 24px;
    --gutter: 24px;
  }
}

@media (min-width: 1024px) {
  :root {
    --fs-headline: 56px;
    --lh-headline: 64px;
    --fs-public-title: 40px;
    --lh-public-title: 48px;
    --page-margin: 32px;
  }
}

[data-theme="dark"] {
  --canvas: #0e0e10;
  --surface: #1a1a1c;
  --surface-2: #232326;
  --surface-3: #2a2a2e;
  --ink: #f5f5f5;
  --ink-muted: #b4b4bc;
  /* 4.40:1 on --surface-3 at #8e8e96 — under AA on the raised plane, which is
     where cards put their tertiary text. #9a9aa2 is 5.12:1 there. */
  --ink-subtle: #9a9aa2;
  --ink-disabled: #6a6a72;
  --border: #2a2a2e;
  --border-strong: #3f3f46;
  --border-input: #7a7a84;
  /* Said again here so an element that is dark on its own (a section with
     data-theme="dark" on a light page) rings in ITS accent text shade, not
     the light one it would otherwise inherit from :root. */
  --focus-ring: var(--accent-text);

  --cyan-50: rgba(0, 157, 211, 0.15);
  /* L-09 darkened these three for light only; dark keeps the values :root
     carried before, so they are written here now. */
  --success: #10b981;
  --success-50: rgba(16, 185, 129, 0.12);
  --success-text: #34d399;
  --warning: #f59e0b;
  --warning-50: rgba(245, 158, 11, 0.12);
  --danger-50: rgba(239, 68, 68, 0.12);
  --info: #009dd3;
  --info-50: rgba(0, 157, 211, 0.12);

  --sh-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --sh-md: 0 2px 8px rgba(0, 0, 0, 0.35);
  --sh-lg: 0 8px 24px rgba(0, 0, 0, 0.45);
  --sh-xl: 0 16px 48px rgba(0, 0, 0, 0.55);
}

/* ── Per-brand accent overrides (9 brands) ────────────────
   To add a brand: append a single block below.
   Each brand defines: --accent, --accent-50, --accent-600, --accent-grad
   --accent-grad pairs the brand colour with cyan (or with itself
   for cyan-based brands). AA is the only brand whose gradient
   leads with the brand colour (orange → cyan) per the locked spec.
   ─────────────────────────────────────────────────────── */
[data-brand="aa"] {
  --accent: var(--orange);
  /* Darkened for type, and MEASURED rather than eyeballed: the previous
     #c06010 read as "darker orange" but only reached 4.27:1 on a card and
     4.09:1 on the canvas — below the 4.5 this file's own header promises.
     #a85200 clears it everywhere it is used: 5.42 on a card, 5.20 on the
     canvas, 4.85 on its own 10% tint. Corrected 2026-09-04, the same
     correction fflo's accent needed and for the same reason. */
  --accent-text: #a85200;
  --accent-50: rgba(246, 128, 31, 0.1);
  /* THE LABEL ON AN ORANGE BUTTON IS INK, NOT WHITE (operator ruling LIBRARY,
     2026-09-27, AF-180 Q1–Q4 — the Figma library already draws it this way).
     aa inherited the root's white foreground and measured 2.62:1 on #f6801f,
     the worst of the five brands BP-1072 found. #1e1e1e reads 6.37:1 on the
     fill and 4.61:1 on the hover, so the label clears 4.5 in BOTH states
     rather than only at rest. Light and dark alike: the fill does not change
     between themes, so neither may the thing written on it.
     Measured, not eyeballed — the same discipline as the note above. */
  --accent-fg: #1e1e1e;
  /* Hover/pressed. #c06010 was the old shade and white on it reached 4.27:1;
     with an ink label #cf6c1a reaches 4.61:1. Ruled with the pair above, so
     the two move together or the hover state silently fails on its own. */
  --accent-600: #cf6c1a;
  --accent-grad: linear-gradient(
    135deg,
    var(--orange) 0%,
    var(--cyan-500) 100%
  );
}
[data-brand="butzpeteza"] {
  --accent: var(--electric);
  --accent-text: var(--cyan-600); /* electric → cyan for type */
  --accent-fg: var(--ink); /* dark text on electric bg */
  --accent-50: rgba(0, 240, 255, 0.1);
  --accent-600: #00c2d9;
  --accent-grad: linear-gradient(135deg, var(--cyan-500), var(--electric));
}
[data-brand="bplabs"] {
  --accent: var(--cyan-500);
  --accent-text: var(--cyan-600);
  --accent-50: var(--cyan-50);
  --accent-600: var(--cyan-600);
  --accent-grad: linear-gradient(135deg, var(--cyan-500), var(--electric));
}
[data-brand="fflo"] {
  /* Electric #00F0FF is the fflo mark, but as a UI accent it fails AA (3.73:1),
     so the product surface uses a tamed cyan — matching fflo V1's 2026-08
     redesign. --accent paints borders/dots/bars; --accent-strong is the value
     for TEXT and solid fills (5.9:1); --accent-fg is the foreground on that
     fill. The electric hue survives as --accent-vivid for the dark rail and
     the brand glyph, where it sits on near-black and reads fine. */
  --accent: #0a91a8;
  --accent-strong: #076b7d;
  --accent-text: #076b7d;
  --accent-fg: #ffffff;
  --accent-50: #e3f6fa;
  --accent-100: #bfe9f1;
  --accent-600: #076b7d;
  --accent-vivid: var(--electric);
  --accent-grad: linear-gradient(135deg, #0a91a8, #076b7d);
}
[data-brand="ffit"] {
  --accent: var(--sapphire);
  --accent-text: var(--sapphire); /* sapphire is dark enough */
  --accent-50: rgba(37, 99, 235, 0.1);
  --accent-600: #1e3fcc;
  --accent-grad: linear-gradient(135deg, var(--cyan-500), var(--sapphire));
}
[data-brand="ffide"] {
  --accent: var(--green);
  --accent-text: #1f7e47; /* darker green for type */
  --accent-50: rgba(42, 157, 92, 0.1);
  --accent-600: #1f7e47;
  --accent-grad: linear-gradient(135deg, var(--cyan-500), var(--green));
  --accent-fg: #fff;
}
[data-brand="ffaro"] {
  --accent: var(--violet);
  --accent-text: var(--violet); /* violet is dark enough */
  --accent-50: rgba(124, 58, 237, 0.1);
  --accent-600: #6a2dd3;
  --accent-grad: linear-gradient(135deg, var(--cyan-500), var(--violet));
}
[data-brand="ffuse"] {
  --accent: var(--gold);
  --accent-text: #b45309; /* darker gold for type */
  --accent-fg: var(--ink); /* dark text on gold bg */
  --accent-50: rgba(245, 158, 11, 0.1);
  --accent-600: #d88b0a;
  --accent-grad: linear-gradient(135deg, var(--cyan-500), var(--gold));
}
[data-brand="ffree"] {
  --accent: var(--coral);
  --accent-text: #be123c; /* darker coral for type */
  --accent-50: rgba(251, 113, 133, 0.1);
  --accent-600: #e04a60;
  --accent-grad: linear-gradient(135deg, var(--cyan-500), var(--coral));
}

/* ── Dark-mode accent-text overrides ───────────────────────
   Brands whose --accent-text is darkened for contrast against
   light surfaces need a lighter variant for dark surfaces.
   Light-on-dark requires the OPPOSITE of dark-on-light.
   Also lightens accent-50 tints so chips stay readable. */
[data-theme="dark"][data-brand="aa"] {
  --accent-text: #ffa859; /* lighter orange on dark */
  --accent-50: rgba(246, 128, 31, 0.18);
}
[data-theme="dark"][data-brand="bplabs"],
[data-theme="dark"][data-brand="butzpeteza"],
[data-theme="dark"][data-brand="fflo"] {
  /* On dark the accent becomes a BRIGHT fill, so the foreground flips to ink. */
  --accent-strong: #67e8f5;
  --accent-text: #67e8f5;
  --accent-fg: #0c1a20;
  --accent-50: #123a40;
  --accent-100: #1c4d54;
  --accent-50: rgba(0, 240, 255, 0.18);
}
[data-theme="dark"][data-brand="ffide"] {
  --accent-text: #5cce8a; /* lighter green on dark */
  --accent-50: rgba(42, 157, 92, 0.2);
}
[data-theme="dark"][data-brand="ffit"] {
  --accent-text: #7b9bff; /* lighter sapphire on dark */
  --accent-50: rgba(37, 99, 235, 0.2);
}
[data-theme="dark"][data-brand="ffaro"] {
  --accent-text: #b98dff; /* lighter violet on dark */
  --accent-50: rgba(124, 58, 237, 0.22);
}
[data-theme="dark"][data-brand="ffuse"] {
  --accent-text: #ffb54a; /* lighter gold on dark */
  --accent-50: rgba(245, 158, 11, 0.2);
}
[data-theme="dark"][data-brand="ffree"] {
  --accent-text: #ff8fa5; /* lighter coral on dark */
  --accent-50: rgba(251, 113, 133, 0.18);
}

/* ── GENERATED by site-kit:assets — do not edit ─────────────────
   The [data-theme="dark"] rules above, repeated for visitors whose
   OS prefers dark. See BpLabs\SiteKit\Support\TokenStylesheet. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --canvas: #0e0e10;
    --surface: #1a1a1c;
    --surface-2: #232326;
    --surface-3: #2a2a2e;
    --ink: #f5f5f5;
    --ink-muted: #b4b4bc;
    --ink-subtle: #9a9aa2;
    --ink-disabled: #6a6a72;
    --border: #2a2a2e;
    --border-strong: #3f3f46;
    --border-input: #7a7a84;
    --focus-ring: var(--accent-text);
    --cyan-50: rgba(0, 157, 211, 0.15);
    --success: #10b981;
    --success-50: rgba(16, 185, 129, 0.12);
    --success-text: #34d399;
    --warning: #f59e0b;
    --warning-50: rgba(245, 158, 11, 0.12);
    --danger-50: rgba(239, 68, 68, 0.12);
    --info: #009dd3;
    --info-50: rgba(0, 157, 211, 0.12);
    --sh-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --sh-md: 0 2px 8px rgba(0, 0, 0, 0.35);
    --sh-lg: 0 8px 24px rgba(0, 0, 0, 0.45);
    --sh-xl: 0 16px 48px rgba(0, 0, 0, 0.55);
  }
  [data-brand="aa"]:not([data-theme="light"]) {
    --accent-text: #ffa859;
    --accent-50: rgba(246, 128, 31, 0.18);
  }
  [data-brand="bplabs"]:not([data-theme="light"]),
  [data-brand="butzpeteza"]:not([data-theme="light"]),
  [data-brand="fflo"]:not([data-theme="light"]) {
    --accent-strong: #67e8f5;
    --accent-text: #67e8f5;
    --accent-fg: #0c1a20;
    --accent-50: #123a40;
    --accent-100: #1c4d54;
    --accent-50: rgba(0, 240, 255, 0.18);
  }
  [data-brand="ffide"]:not([data-theme="light"]) {
    --accent-text: #5cce8a;
    --accent-50: rgba(42, 157, 92, 0.2);
  }
  [data-brand="ffit"]:not([data-theme="light"]) {
    --accent-text: #7b9bff;
    --accent-50: rgba(37, 99, 235, 0.2);
  }
  [data-brand="ffaro"]:not([data-theme="light"]) {
    --accent-text: #b98dff;
    --accent-50: rgba(124, 58, 237, 0.22);
  }
  [data-brand="ffuse"]:not([data-theme="light"]) {
    --accent-text: #ffb54a;
    --accent-50: rgba(245, 158, 11, 0.2);
  }
  [data-brand="ffree"]:not([data-theme="light"]) {
    --accent-text: #ff8fa5;
    --accent-50: rgba(251, 113, 133, 0.18);
  }
}
