/* WarehouseNow design system — tokens
   ====================================================================
   Ported verbatim from warehousenow-core `src/app/globals.css`
   (the v1 app's Tailwind v4 @theme block) on 2026-09-22.

   WHY A COPY AND NOT A DEPENDENCY: these mockups are static HTML with no
   build step, so they cannot consume Tailwind v4's @theme syntax. The
   values are identical; only the wrapper changed (`@theme {}` -> `:root {}`,
   `.light {}` kept as-is).

   DO NOT TUNE THESE VALUES HERE. Every colour below was measured against
   WCAG AA on every background it can land on — the comments record which
   ticket moved it and what the ratios were. A value changed here to make a
   mockup look better will diverge from the app and lose that history.
   If a token is wrong, fix it in warehousenow-core and re-port.

   Dark is the default (:root). Add class="light" to <html> for light.
   ==================================================================== */

:root {

  /* Backgrounds — layered elevation */
  --color-bg-app:       #0f0f10;
  --color-bg-base:      #141415;
  --color-bg-elevated:  #1a1a1c;
  --color-bg-overlay:   #232326;
  --color-bg-hover:     #1e1e21;
  --color-bg-active:    #26262a;
  --color-bg-input:     #18181b;
  /* WAR-3494 — the hover highlight for an item inside a floating MENU.
     Menus paint bg-elevated (#1a1a1c) and were highlighting with bg-hover
     (#1e1e21): 1.05:1, which is not a highlight, it is nothing. You could not
     see which item you were about to click.

     Every other background token was measured against bg-elevated and none of
     them fixes it -- bg-active is the best at 1.15:1, so swapping to it would
     have moved the number without fixing the thing.

     THIS VALUE IS AT A CEILING, and the ceiling is the TEXT, not taste.
     text-tertiary (#8f8f93) sits on menu items, and on:
         #282830  ->  1.19 vs the panel,  tertiary 4.54  (AA)
         #2a2a30  ->  1.22,               tertiary 4.43  (fails)
         #2e2e34  ->  1.29,               tertiary 4.19  (fails)
     So a background alone CANNOT make a dark menu highlight properly visible
     while keeping its own text readable. That is why `.menu-item` below also
     paints an accent bar: the bar carries the affordance and is not competing
     for the same contrast budget. Changing this value without re-checking the
     text is how one problem gets traded for another. */
  --color-bg-menu-hover: #282830;

  /* Borders */
  --color-border-subtle:  rgba(255,255,255,0.06);
  --color-border-default: rgba(255,255,255,0.10);
  --color-border-strong:  rgba(255,255,255,0.16);

  /* Text */
  --color-text-primary:   #e2e2e5;
  --color-text-secondary: #95959f;
  /* WAR-1435 → WAR-1437 — dark tertiary. WAR-1435 raised it from #5a5a63
     (~2.5-2.8:1 on dark cards, fails AA) to #7e7e88, which cleared 4.5:1
     on app + base but missed elevated at 4.33:1 (caught by WAR-1437 QA).
     Bumped again to #858589 to clear 4.5:1 across every dark surface in
     use: app #0f0f10 → 5.21, base #141415 → 5.01, elevated #1a1a1c → 4.73,
     hover #1e1e21 → 4.52. Active #26262a → 4.10 still misses but it's a
     transient pressed state. Hierarchy with secondary (#8b8b96, lum 0.2616)
     preserved via a 0.023 luminance gap. Affects KPI tile labels, period
     tabs, OrderInfoCard footer, table column labels — every consumer of
     text-text-tertiary on elevated surfaces. */
  --color-text-tertiary:  #8f8f93;

  /* Phase 0.3e — these three moved because a text token has to clear AA on
     EVERY background token it can land on, and bg-active was never checked.
     It is the row-hover/selected background, so it is under text constantly.

     After 0.3d the whole of dark mode's remaining failures were this one pair:
     39x text-secondary at 4.47 and 5x text-tertiary at 4.10, both on
     bg-active. Light had the same shape at 4.25.

     WAR-1302 tuned the LIGHT tertiary to "clear WCAG AA on BOTH white cards
     AND the #f5f5f7 body canvas" -- two of the five surfaces. Same miss as
     mine, a year earlier, which is why the fix here is a matrix check rather
     than three new numbers.

                        app   base  elev  hover  active
       dark  secondary  6.46  6.20  5.86  5.60   5.08
       dark  tertiary   5.95  5.71  5.39  5.16   4.68
       light tertiary   5.30  5.77  5.77  5.07   4.72   */
  --color-text-accent:    #60a5fa;

  /* Accent (Bright Royal Blue) */

  /* ── brand ─────────────────────────────────────────────────────────────
     WHERE YOU ARE is not WHAT TO DO. The mark and the current nav item used
     --color-accent, which is also every primary button in the product, so the
     one permanently-lit thing on screen wore the same blue as the one thing
     you are meant to click. Two different jobs cannot share a colour when one
     of them is always on.

     It is deliberately outside the status family, all of which mean something
     here: done green, progress amber, blocked red are used heavily across the
     AP flows, and snoozed and accepted are light violets that would read as
     status if this were near them. A deep violet is far enough from all of
     them and from accent blue.

     Same value in both themes, like --color-accent, because white on it is
     the constant: 7.02:1, measured. */
  --color-brand:       #6d28d9;
  --color-brand-hover: #5b21b6;

  --color-accent:         #2563eb;
  --color-accent-hover:   #1d4ed8;
  --color-accent-subtle:  rgba(37,99,235,0.15);

  /* Status Colors */
  --color-status-todo:        #95959f;  /* was #6b7280 — 3.81:1 on the dark
     canvas and 3.48:1 on its own tint, i.e. below AA in DARK the whole time.
     It IS used as text. #95959f is --color-text-secondary's dark value, already
     proven on every surface. */
  /* WAR-3434 — the foreground for TEXT ON a status fill (a banner's CTA), not
     status text on a page.

     DELIBERATELY NOT named --color-status-*. Everything in that family is a
     status COLOUR, checked by design-qa-light-semantic-contrast as text on a
     tint of itself. This is the opposite role — a foreground FOR those fills —
     and `bg-on-status` exists nowhere, so that check would be meaningless on it
     (white on a 10% white tint is 1:1 and would fail for the wrong reason).
     Its real pairing is proven by war-3434-banner-palette-contrast, which
     computes fg-on-fill for all four severities in both themes. It has to FLIP with the theme, which is why no
     existing token worked: the dark-theme fills are bright (#f59e0b, #f87171,
     #10b981, #93c5fd) so white on them is 2.15-2.77:1, while the light-theme
     fills are deep (#92400e, #b91c1c, #065f46, #1e40af) so white is 6.47-8.72:1.
     Near-black here, white in .light. --color-primary-foreground is #ffffff with
     no light override, i.e. exactly backwards for this job.
     Measured floor across all four severities x both themes: 6.47:1. */
  --color-on-status:  #0f0f10;
  --color-status-progress:    #f59e0b;
  --color-status-done:        #10b981;
  --color-status-cancelled:   #6b7280;
  --color-status-blocked:     #f87171;
  --color-hue-pink:     #f472b6;
  --color-status-snoozed:     #a78bfa;

  /* Urgency Color */
  --color-urgency: #f97316;

  /* Design QA Sept 2026 (RC-3 / X-7) — colours that had NO token at all.
     Each was an arbitrary hex or a stock Tailwind class, so it could not
     participate in the light/dark flip and failed AA on white. */

  /* Customer TYPE, per Mike's WAR-559 spec: Carrier = dark orange,
     Broker = green, Direct = default text. Broker previously borrowed
     --color-status-done, so a change to STATUS silently moved a CUSTOMER
     colour. Same hue, two jobs — the X-7 finding, in one line. */
  --color-customer-carrier: #fb923c;
  --color-customer-broker:  #10b981;

  /* Informational accent (bottled-beverage flag, coverage chips). Some call
     sites already hand-rolled `text-[#0891b2] dark:text-[#06b6d4]` — the pair
     a token is for, except the light half still measured 3.68:1. */
  --color-info: #06b6d4;

  /* Key-account marker. Was `text-amber-300` from stock Tailwind: a
     dark-tuned value with no theme awareness, measuring 1.33:1 on its own
     tint — the single worst contrast in the app, 21 instances. */
  --color-key-account: #f59e0b;

  /* Order-status chips (Phase 0.3c). STATUS_COLORS in src/lib/constants.ts held
     the whole palette as arbitrary hexes, which is why 49 of the audit's
     remaining 68 light failures came from one file. The generic
     --color-status-todo/progress/done family could not absorb these: it has no
     way to say quoted-blind vs quoted-covered, or accepted vs future, and
     collapsing them would lose distinctions reps read at a glance.

     Four hues that map onto an existing token are NOT duplicated here --
     quoted_covered uses --color-info, the green/amber/red states reuse
     --color-status-done/progress/blocked. */
  --color-status-new:      #93c5fd;
  --color-status-quoted:   #67e8f9;
  --color-status-future:   #14b8a6;

  /* #c4b5fd, not the #8b5cf6 this replaces: that value measures 4.35 on the
     dark canvas and 3.95 on its own tint, i.e. it was failing AA in DARK mode
     the whole time. Nor --color-status-snoozed's #a78bfa, which passes IN
     DARK -- it had no light value at all until Sept 2026 and measured 2.27:1
     on /inbox -- and would anyway land two meanings on one hue, the X-7
     mistake. */
  --color-status-accepted: #c4b5fd;

  /* Service category. `disposal` was the last arbitrary hex in constants.ts;
     the other categories already reused status tokens. */
  --color-service-disposal: #fb7185;

  /* A red for a SOLID badge with white text on it, which is the opposite
     constraint to --color-status-blocked. That token is read as TEXT on a 10%
     tint of itself, so it must be LIGHT against a dark canvas; white-on-solid
     needs the reverse. One value cannot serve both — the notification bell was
     `bg-[#ef4444] text-white` at 3.76:1 in BOTH themes because it borrowed the
     wrong end of that trade. Same value in both modes: white text is the
     constant here, not the surface. */
  --color-alert-solid: #dc2626;

  /* Custom breakpoint (WAR-2243, 2026-07-15).
     Tailwind v4 default breakpoints: sm=640 / md=768 / lg=1024 / xl=1280
     / 2xl=1536. Arbitrary `min-[NNNNpx]:` variants get emitted in a
     separate section of the compiled CSS and can end up BEFORE
     standard breakpoint utilities at equal specificity — so
     `min-[1360px]:grid-cols-7` was silently losing to `md:grid-cols-4`
     at any viewport ≥1360px (agent-verified in the compiled CSS
     during WAR-2243 QA). Named breakpoints declared here participate
     in Tailwind's standard sort-by-min-width ordering, so `wide:`
     (1360) correctly sorts between `xl:` (1280) and `2xl:` (1536)
     and wins at ≥1360px viewports. */
  --breakpoint-wide: 1360px;

  /* Priority Colors */
  --color-priority-urgent: #f87171;
  --color-priority-high:   #f59e0b;
  --color-priority-medium: #93c5fd;
  --color-priority-low:    #6b7280;
  --color-priority-none:   #4b5563;

  /* Semantic — for shadcn compatibility */
  --color-background:    #0f0f10;
  --color-foreground:    #e2e2e5;
  --color-card:          #1a1a1c;
  --color-card-foreground: #e2e2e5;
  --color-popover:       #232326;
  --color-popover-foreground: #e2e2e5;
  --color-primary:       #2563eb;
  --color-primary-foreground: #ffffff;
  --color-secondary:     #1e1e21;
  --color-secondary-foreground: #e2e2e5;
  --color-muted:         #1a1a1c;
  --color-muted-foreground: #8b8b96;
  --color-accent-fg:     #e2e2e5;
  --color-destructive:   #ef4444;
  /* Destructive TEXT, split from the fill above — the same lesson as
     --color-accent vs --color-text-accent (gotcha #759), on a second token.
     One value cannot do both jobs in dark: the fill carries `text-white`, so
     it must stay DARK, while text on a dark surface must be LIGHT. #ef4444 was
     the compromise and failed both — 3.76:1 under white, and 4.42/4.01 as text
     on bg-hover/bg-active, which is where a table row's text actually sits.
     Found by the WAR-3343 sweep on /accounting/cleanup. #f87171 measures
     6.93/6.66/6.28/6.01/5.45 across the five dark backgrounds.

     ENFORCED (WAR-3355): `destructive` is a BACKGROUND token and has zero
     `text-destructive` call sites. `tests/design-qa-fill-tokens-are-not-text.test.ts`
     fails the build on a bare one, and asserts these two DARK values stay
     different — collapsing them back to one restores the bug in full while
     every call site still looks correct. If you are retuning the value below,
     that test is the constraint you are working against. Light may share a
     value (both #b91c1c); only dark is forced apart. */
  --color-text-destructive: #f87171;
  --color-border:        rgba(255,255,255,0.10);
  --color-input:         rgba(255,255,255,0.10);
  --color-ring:          #2563eb;

  /* Chart colors */
  --color-chart-1: #2563eb;
  --color-chart-2: #10b981;
  --color-chart-3: #f59e0b;
  --color-chart-4: #ef4444;
  --color-chart-5: #8b5cf6;

  /* Typography */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;

  /* Border Radius */
  --radius-sm:   4px;
  --radius-md:   6px;
  --radius-lg:   8px;
  --radius-xl:   12px;
  --radius-full: 9999px;

  /* Shadows — reserved for overlays only */
  --shadow-sm: 0 1px 4px rgba(0,0,0,0.3);
  --shadow-md: 0 4px 16px rgba(0,0,0,0.3), 0 1px 4px rgba(0,0,0,0.2);
  --shadow-lg: 0 8px 32px rgba(0,0,0,0.4), 0 2px 8px rgba(0,0,0,0.2), 0 0 0 1px rgba(0,0,0,0.2);

  /* Animation */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);

  /* Inbox density (WAR-399) — defaults match the existing "cozy" feel.
     Per-density overrides live in @layer base below, scoped by
     [data-inbox-density] on the inbox root. */
  --inbox-row-py: 12px;
  --inbox-row-gap: 12px;
  --inbox-avatar-size: 32px;
  --inbox-name-text: 14px;
  --inbox-subject-text: 13px;
  --inbox-snippet-text: 12px;

  /* Load Board density (WAR-2401) — defaults match the existing dense table
     so nothing regresses. Per-density overrides live in @layer base below,
     scoped by [data-loadboard-density] on the orders table wrapper. Read via
     Tailwind arbitrary values (py-[var(--loadboard-row-py)]) on the table
     cells so a single attribute flip re-densifies the whole board. */
  --loadboard-row-py: 8px;
}

/* ====================================================================
   Light overrides — same tokens, inverted roles.
   ==================================================================== */

.light {

  /* Backgrounds — light-mode layering. In dark mode the convention is
     "more elevated = lighter"; in light mode it's "more elevated = whiter
     or with shadow". Pattern matches Notion/Linear light: gray canvas,
     white content panels, white popovers (separation comes from shadow,
     not from a darker layer). */
  --color-bg-app:       #f5f5f7;  /* gray canvas — visible in margins/gaps */
  --color-bg-base:      #ffffff;  /* white content area */
  --color-bg-elevated:  #ffffff;  /* white panels (sidebar, cards) — shadow elevates, not color */
  --color-bg-overlay:   #ffffff;  /* white popovers — separation via border + shadow */
  --color-bg-hover:     #f0f0f3;
  --color-bg-active:    #e8e8ec;
  --color-bg-input:     #ffffff;
  /* WAR-3494, light. Panels are white here, so there is more room: #e4e4ea is
     1.27:1 against the panel with text-tertiary (#65656e) at 4.56 -- the same
     ceiling logic as dark, one step further along. #e2e2e9 would read 1.29 and
     drop tertiary to 4.48. */
  --color-bg-menu-hover: #e4e4ea;

  /* Borders — black overlay alpha mirrors the dark mode's white-overlay alpha */
  --color-border-subtle:  rgba(0,0,0,0.06);
  --color-border-default: rgba(0,0,0,0.10);
  --color-border-strong:  rgba(0,0,0,0.16);

  /* Text — Linear-style near-monochrome, dark text on light bg.
     Tertiary darkened from #71717a (zinc-500) to #6c6c75 to hit WCAG
     AA contrast (4.5:1) against BOTH #ffffff (cards) AND #f5f5f7
     (body canvas). At #71717a it scored 4.5:1 on white but only
     4.4:1 on the body bg — sidebar filter labels failed by 0.06
     (WAR-1302 QA). Labels still subdued vs primary but readable on
     every surface. */
  --color-text-primary:   #18181b;
  --color-text-secondary: #52525b;
  --color-text-tertiary:  #65656e;
  /* Phase 0.3f — #1d4ed8, not the #2563eb it shared with --color-accent.
     text-accent is TEXT; accent is a brand fill (buttons, active states). At
     #2563eb the text form measured 4.23 on bg-active, and this phase pointed
     81 call sites at it, so keeping them equal would have INTRODUCED failures
     on every hovered row. The brand fill is unchanged. */
  --color-text-accent:    #1d4ed8;

  /* Accent — same brand blue, slightly softer subtle layer for light bg */
  --color-accent:         #2563eb;
  --color-accent-hover:   #1d4ed8;
  --color-accent-subtle:  rgba(37,99,235,0.10);

  /* ---------------------------------------------------------------
     Design QA Sept 2026 (RC-3) — light-mode semantic colours.

     These were deliberately theme-independent, and globals.css said so:
     "Brand + status hex values are intentionally theme-independent — same
     value in both modes ... Final palette will get a designer pass in
     Phase 5/6." This is that pass, for the subset that fails WCAG.

     Measured against ALL THREE light surfaces a token can land on:
     #ffffff cards, the #f5f5f7 page canvas, AND a tint of the token itself.

     That third one was MISSED on the first pass and is the common case, not an
     edge: the app's chips are `bg-token/10` + `text-token`, so the text sits on
     a wash of its own colour. Four of the original seven values cleared white
     and the canvas and still failed there (status-done 4.49, urgency 4.22,
     key-account 4.14), which is why the audit only moved 112 -> 92 instead of
     the predicted ~85. The values below are the 800 step rather than the 700.

       token             dark      light      white  canvas  tint10  tint14
       status-done       #10b981   #065f46     7.68    7.06    6.56    6.14
       status-progress   #f59e0b   #92400e     7.09    6.51    6.07    5.70
       status-blocked    #ef4444   #b91c1c     6.47    5.94    5.46    5.09
       urgency           #f97316   #9a3412     7.31    6.71    6.22    5.82
       priority-urgent   #ef4444   #b91c1c     6.47    5.94    5.46    5.09
       priority-high     #f59e0b   #92400e     7.09    6.51    6.07    5.70
       priority-medium   #3b82f6   #1d4ed8     6.70    6.15    5.74    5.38

     Darkening is correct in EVERY usage pattern these tokens have, which
     was checked rather than assumed:
       * `bg-status-X/10` + `text-status-X` (the common chip) — text gets
         darker, the 10% tint stays pale. Better both ways.
       * `bg-status-done text-white` (status-stepper, invoice sections) —
         white-on-green goes 2.54 -> 5.48, i.e. from failing to passing.
       * bare dots and progress-bar fills — decorative, no text on them.

     Dark values are ALSO measured on their own tint now (Phase 0.3d). The
     first pass checked the tint in light mode only, and six dark values were
     failing it -- status-new at 4.27, which the production audit then caught as
     8 live failures. After the light-mode work dark had become the WORSE theme
     (55 failures vs 22), the reverse of where this started.
     --------------------------------------------------------------- */
  /* WAR-3434 — see the dark declaration. White on the deep light-theme fills. */
  --color-on-status: #ffffff;
  --color-status-progress:  #92400e;
  --color-status-done:      #065f46;
  --color-status-blocked:   #b91c1c;
  --color-urgency:          #9a3412;

  --color-priority-urgent:  #b91c1c;
  --color-priority-high:    #92400e;
  --color-priority-medium:  #1d4ed8;

  /* Light values for the newly-tokenised colours. Measured on BOTH surfaces
     (#ffffff cards / #f5f5f7 canvas), same rule as the block above:

       token             dark      light      white  canvas  tint10  tint14
       customer-carrier  #ea580c   #9a3412     7.31    6.71    6.22    5.82
       customer-broker   #10b981   #065f46     7.68    7.06    6.56    6.14
       info              #06b6d4   #155e75     7.27    6.67    6.24    5.85
       key-account       #f59e0b   #92400e     7.09    6.51    6.07    5.70  */
  --color-customer-carrier: #9a3412;
  --color-customer-broker:  #065f46;
  --color-info:             #155e75;
  --color-key-account:      #92400e;

  /* Order-status chips, light. All four surfaces, same rule as above:
       status-new       #3b82f6 -> #1e40af   8.72 / 8.01 / 7.64 / 6.89
       status-quoted    #67e8f9 -> #0369a1   5.93 / 5.45 / 5.13 / 4.83
       status-accepted  #c4b5fd -> #5b21b6   8.98 / 8.25 / 7.82 / 7.02
       status-future    #14b8a6 -> #115e59   7.58 / 6.96 / 6.70 / 6.09 */
  --color-status-new:      #1e40af;
  /* #0369a1, NOT the #155e75 that --color-info uses. WAR-488 makes blind and
     covered deliberately different shades of one hue ("blind = lighter, less
     progress; covered = saturated, near-approval"), and my first pass gave both
     the same light value -- which would have erased that distinction in light
     mode while passing every contrast check. Distinct AND clears 4.83 worst. */
  --color-status-quoted:   #0369a1;
  --color-status-accepted: #5b21b6;
  /* Was MISSING entirely, so it kept its dark #a78bfa on a light tint and
     measured 2.27:1 on /inbox. Violet, dark enough to read on its own 15%
     tint over white, and distinct from status-accepted above. */
  /* Four more greys with no light value, surfaced by the coverage check in
     tests/design-qa-light-semantic-contrast. Their dark #6b7280 / #4b5563
     read as text on a 10% tint of themselves over white, which the mid-greys
     do not clear. #52525b is the same value as --color-text-secondary, which
     is already proven on every surface. */
  --color-status-todo:      #52525b;
  --color-status-cancelled: #52525b;
  --color-priority-low:     #52525b;
  --color-priority-none:    #52525b;
  /* Had NO light value at all. #ef4444 on white is 3.76:1 and this token is
     used 80 times as TEXT — 58 of them on /settings/team alone. #b91c1c is
     6.4:1 as text on white and also under white text, so the one value works
     for `text-destructive` and `bg-destructive` alike. */
  --color-destructive:     #b91c1c;
  /* Light needs no split — #b91c1c is dark enough to read as text AND to sit
     under white text, which is what the note above says. It is repeated here
     so the token exists in both themes; a token defined in only one theme is
     the --color-status-snoozed bug. Measures 5.94/6.47/6.47/5.69/5.29. */
  --color-text-destructive: #b91c1c;
  --color-status-snoozed:  #6d28d9;
  /* The 6th avatar hash slot. The other five map to existing tokens; pink
     had only a dark hex (#f472b6), which measured 2.21:1 in light. */
  --color-hue-pink:     #9d174d;
  --color-status-future:   #115e59;
  /* service-disposal  #f43f5e -> #9f1239   8.02 / 7.36 / 6.70 / 5.55 (at /20) */
  --color-service-disposal: #9f1239;

  /* Status colors — same hex (theme-independent), only docs note here */

  /* Semantic — shadcn compat (mirror Tailwind defaults for light) */
  --color-background:    #fafafa;
  --color-foreground:    #18181b;
  --color-card:          #ffffff;
  --color-card-foreground: #18181b;
  --color-popover:       #ffffff;
  --color-popover-foreground: #18181b;
  --color-secondary:     #f5f5f7;
  --color-secondary-foreground: #18181b;
  --color-muted:         #f5f5f7;
  --color-muted-foreground: #52525b;
  --color-accent-fg:     #18181b;
  --color-border:        rgba(0,0,0,0.10);
  --color-input:         rgba(0,0,0,0.10);
}

/* ====================================================================
   Baseline. The app sets html { font-size: 13px }, which makes every
   rem-based size 19% smaller than it reads. Mockups keep that so spacing
   matches the real thing — but ANY height or touch target relied on as a
   guarantee must be written in explicit pixels, never rem.
   ==================================================================== */

html {
  font-size: 13px;
  color-scheme: dark;
}
.light html, html.light { color-scheme: light; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 13px;
  line-height: 1.5;
  background: var(--color-bg-app);
  color: var(--color-text-primary);
  -webkit-font-smoothing: antialiased;
}

*, *::before, *::after { box-sizing: border-box; }
img { max-width: 100%; }
[hidden] { display: none !important; }

/* Type scale — nothing below 11px. 10/9/8px are off the scale and are
   what "hard to read" looks like. */
.t-label   { font-size: 11px; }  /* labels, badges */
.t-small   { font-size: 12px; }  /* secondary, buttons */
.t-body    { font-size: 13px; }
.t-heading { font-size: 14px; }
.t-title   { font-size: 20px; }  /* page titles */

/* Transitions: 75-80ms, ease-out-expo. Never over 200ms. */
.transition { transition: all 80ms var(--ease-out-expo); }
