/* ============================================================================
   Rentari design tokens, the single source of truth for web.
   ----------------------------------------------------------------------------
   WHY THIS FILE EXISTS
   The product had no token layer. btn-brand.css held 15 custom properties, all
   brand decoration (the gradient, its glow, five avatar fills, a hero
   background). There was no neutral ramp, no radius scale, no spacing scale,
   no type scale, no elevation ladder and no status colours, so every screen
   invented its own. Measured across app/features/<domain>/ui/*.html:

     970    distinct hex literals
     ~3,400 pasted copies of the three brand hexes, rather than the var
     1,250  distinct box-shadow recipes for 2,039 declarations
     ~140   distinct border-radius values
     67     near-identical hairline greys doing the job of one border token

   The mobile app already solved this: mobile/src/theme/tokens.ts is a clean
   semantic token file and the mobile codebase carries TWO hardcoded hexes.
   This file ports that STRUCTURE and NAMING to CSS. It deliberately does NOT
   port mobile's values, because mobile's radius ramp (10/14/15/20/24) is not
   the web's Tailwind ramp (8/12/16/24) and copying it would silently restyle
   every corner in the product. Values here match what the web renders TODAY.

   RULES
   1. This file only DECLARES custom properties. It must not style a single
      element, so adding it changes no rendered pixel. That is the gate.
   2. New work references these vars instead of hardcoding. Existing per-screen
      literals migrate here incrementally, never in one sweep.
   3. Status colours (emerald / amber / rose) encode STATE. They are never
      action colours and never the brand. See DESIGN.md:67.
   4. The brand gradient marks the PRIMARY action, the progress meter, and the
      active/selected state. Never decoration. See DESIGN.md:266-269.
   5. Font family is Inter on web. Do NOT port mobile's PlusJakartaSans, which
      DESIGN.md:121 bans as a UI font.

   Loaded FIRST in every shell so anything later can override it.
   ========================================================================== */

:root {
  /* --- Brand -------------------------------------------------------------
     The identity gradient's three stops. These mirror --brand-* in
     btn-brand.css, which stays the canonical home for the gradient itself and
     its glow so white-label shells can keep overriding it. */
  --brand-purple: #8c6cff;
  --brand-blue:   #6a9eff;
  --brand-teal:   #48e2d9;
  --brand-deep:   #0f766e;

  /* The deep stops (2026-08-16). Same hue arc, lowered lightness until white
     text clears WCAG AA without the dark scrim that used to be layered over
     every brand button: #7B58EA 4.74:1, #4070CD 4.75:1, #00817A 4.75:1, and
     4.74:1 at the worst point along the ramp. Composed into
     --brand-gradient-deep in btn-brand.css, which stays the canonical home for
     gradients (this file declares values, never compositions, and must never
     grow an @supports block: test_design_tokens.py parses it and fails on any
     rule that is not a plain :root custom property). */
  --brand-deep-purple: #7b58ea;
  --brand-deep-blue:   #4070cd;
  --brand-deep-teal:   #00817a;

  /* The gradient system's stop values (2026-08-16), declared here so they are
     nameable and so the colour ratchet counts them as on-system. The
     GRADIENTS themselves are composed in btn-brand.css, which stays the
     canonical home for compositions; this file only ever declares values.
     Generator: stop2 = OKLCH(L - delta) with chroma and hue held. Every ramp
     that carries white text was verified at 41 points along it. */
  --action-1: #6164ef;  --action-2: #4943cc;   /* 4.59:1 */
  --success-1:#1f8563;  --success-2:#006747;   /* 4.57:1 */
  --warning-1:#bb5a16;  --warning-2:#9a3b00;   /* 4.58:1 */
  --danger-1: #d02c4a;  --danger-2: #ac002e;   /* 5.07:1 */
  /* The LIGHT red, added 2026-08-25 at the owner's request for the rent
     card's action button. Same hue as --danger (16.9 in OKLCH, so it is the
     card's own red rather than a second one), lifted to the highest lightness
     that still holds a WHITE label: L 0.590 against --danger-1's 0.564, which
     is the ceiling, not a preference. Anything lighter drops white below
     4.5:1 and the label has to go dark instead. */
  --danger-light-1: #da3450;  --danger-light-2: #c1113d;   /* 4.58:1 */
  --info-1:   #2a5fe9;  --info-2:   #103dc7;   /* 5.37:1 */
  --ai-1:     #7a3deb;  --ai-2:     #6008c8;   /* 5.68:1 */

  /* Role fills. 2.08 to 3.12:1, so NEVER put white text on these. */
  --accent-landlord-1:#79aeff; --accent-landlord-2:#5b8eee;
  --accent-tenant-1:  #9b7cff; --accent-tenant-2:  #7e5ced;
  --accent-vendor-1:  #34c8b6; --accent-vendor-2:  #00a897;
  /* Their text-safe twins. */
  --accent-landlord-deep-1:#4273d0; --accent-landlord-deep-2:#2654af;
  --accent-tenant-deep-1:  #7d5aec; --accent-tenant-deep-2:  #6239c9;
  --accent-vendor-deep-1:  #008575; --accent-vendor-deep-2:  #006759;

  /* Surface stops. Delta chosen for a 7 to 9 step channel difference: enough
     to read as depth, wide enough not to band on an 8-bit display. */
  --surface-canvas-2:  #eff1f3;
  --surface-sunken-2:  #e8ecf0;
  --surface-tint-2:    #eceaf6;
  --surface-command-1: #121927;  --surface-command-2: #060b19;

  /* --- The email palette -------------------------------------------------
     Email is the one surface that CANNOT use any of this. Most clients do not
     support custom properties, and Outlook drops CSS gradients outright, so
     every email template inlines literal hex and always will. That is not
     drift, it is the medium.

     What WAS drift is that nobody wrote the values down, so the same panel
     grew three near-identical tints across 50-odd templates. These three are
     the ones actually in use (measured 2026-08-16: #f8faff in 47 email files,
     #eef0f6 in 33, #eef4ff in 31). Declared here so they have names and so the
     colour ratchet counts them as on-system. PASTE THE LITERAL into an email
     template, never var(); the var will not resolve there. */
  --email-surface: #f8faff;   /* the panel / card fill */
  --email-border:  #eef0f6;   /* its hairline */
  --email-tint:    #eef4ff;   /* the cooler second panel */

  /* --- Concierge tier -----------------------------------------------------
     Gold is NOT drift, and it is NOT a contrast defect. It is the deliberate
     identity of the top pricing tier (.pricing-card-tag-concierge and friends)
     and of the gold sidebar theme. It was the last undocumented colour family
     after the 2026-08-16 audit, so it is named here and nothing about its
     rendering changed.

     MEASURED, and worth recording because it is easy to get wrong: gold is
     rendered on .pricing-card-inner, a DARK card (#0b1220), where #d4af37
     measures 8.90:1. A first pass at this "fixed" it to a deep gold on the
     strength of a contrast walker that composited background-COLOR only and
     ignored the card's dark background-IMAGE, so it reported the white page
     body and claimed 1.88:1. On the real surface that deep gold would have
     been 4.02:1, i.e. the fix was the regression. Measure against
     background-image too, or do not measure.

     The deep pair below exists only for the case where gold ever has to sit on
     a LIGHT surface (4.65:1 there). Nothing uses it today. */
  --tier-concierge:        #d4af37;   /* 8.90:1 on the dark concierge card */
  --tier-concierge-light:  #f4e5b9;
  --tier-concierge-dark:   #b08d57;
  --tier-concierge-deep-1: #936f00;   /* only for gold on a LIGHT surface */
  --tier-concierge-deep-2: #755200;

  /* Chart series. FLAT on purpose: a gradient per series makes two adjacent
     series harder to separate, and the colourblind validator scores flat
     values. Validated all-pairs in BOTH light and dark for the first four,
     adjacent-pairs for all six. Never reuse a status colour as a series. */
  --viz-1: #6366f1;  --viz-2: #c2410c;  --viz-3: #0d9488;
  --viz-4: #a21caf;  --viz-5: #0891b2;  --viz-6: #7c3aed;

  /* --- Action ------------------------------------------------------------ */
  --action:            #6366f1;  /* brand-primary, indigo-500 */
  --action-hover:      #4f46e5;
  --action-tint:       #e7edff;
  --action-tint-strong:#e0e7ff;

  /* --- Surfaces ----------------------------------------------------------
     NOTE: the app canvas is theme-driven (the landlord shell ships a Cream
     default plus ~10 named themes via [data-theme]). --surface-canvas is the
     DESIGN.md:55 baseline for surfaces that are not themed; themed shells keep
     using their own --main-bg. Do not force this onto a themed shell. */
  --surface:          #ffffff;   /* cards, modals, sidebars. OPAQUE. */
  --surface-alt:      #f1f5f9;   /* sunken rows, segmented tracks */
  --surface-canvas:   #f8fafc;   /* unthemed page canvas */
  --surface-inverse:  #0f172a;
  --surface-command:  #0b1220;   /* dark "command" hero base, DESIGN.md:261 */
  --surface-scrim:    rgba(15, 23, 42, 0.45);

  /* --- Borders -----------------------------------------------------------
     Two rungs replace the 67 near-identical greys. */
  --border:        #e2e8f0;
  --border-strong: #cbd5e1;
  --border-hairline: #eef2f7;    /* dense-table dividers, DESIGN.md:251 */

  /* --- Text --------------------------------------------------------------
     Darkened 2026-09-03 to close the measured 22-point OKLCH lightness gap
     against TurboTenant. Hue and chroma are held, only lightness moves; the
     full derivation and the reason it is a lightness problem and not a hue
     one live in the slate block in tailwind.config.js. Keep the two in sync:
     these values ARE slate-600 / slate-500 as that config now defines them.

     --text-muted is the floor for body copy, now 10.0:1 on white.
     --text-disabled deliberately did NOT move and no longer equals slate-400.
     Its job is to read inactive, so it stays light, which also means it stays
     unfit for text: 2.56:1, for genuinely inactive controls only. */
  --text:          #0f172a;
  --text-secondary:#293649;
  --text-muted:    #354358;
  --text-disabled: #94a3b8;
  --text-on-dark:  #f8fafc;
  --text-on-dark-muted: rgba(255, 255, 255, 0.82);

  /* --- Status. State only, never actions, never brand. ------------------- */
  --success:    #047857;  --success-bg: #defcee;  --success-border: #a7f3d0;
  --warning:    #b45309;  --warning-bg: #fff7d9;  --warning-border: #fde68a;
  --danger:     #be123c;  --danger-bg:  #ffeaec;  --danger-border:  #fecdd5;
  --info:       #1d4ed8;  --info-bg:    #e5f0fe;  --info-border:    #bfdbfe;
  --ai:         #6d28d9;  --ai-bg:      #f1eeff;  --ai-border:      #ddd6fe;

  /* --- Radius. Matches the Tailwind ramp the product already uses. ------- */
  --radius-xs:   4px;
  --radius-sm:   6px;
  --radius-md:   8px;    /* rounded-lg */
  --radius-lg:   12px;   /* rounded-xl */
  --radius-card: 16px;   /* rounded-2xl, the default card */
  --radius-xl:   24px;   /* rounded-3xl */
  --radius-pill: 9999px;

  /* --- Spacing. 4pt grid. ------------------------------------------------ */
  --space-2xs: 2px;
  --space-xs:  4px;
  --space-sm:  8px;
  --space-md:  12px;
  --space-lg:  16px;
  --space-xl:  20px;
  --space-2xl: 24px;
  --space-3xl: 32px;
  --space-4xl: 48px;

  /* --- Type --------------------------------------------------------------
     IMPORTANT: the landlord shell pins html { font-size: 14px } and offers a
     working Small / Medium / Large picker (12.5 / 14 / 16px). Every rem value
     below therefore scales WITH the user's choice, which is the accessible
     behaviour and the reason these are rem and not px. At the 14px default:
       --text-xs   = 10.5px      --text-base = 14px
       --text-sm   = 12.25px     --text-lg   = 15.75px
     Hardcoded px in templates does NOT scale with the picker, which is exactly
     the defect these tokens exist to retire. Prefer these over px. */
  --text-2xs:  0.625rem;
  --text-xs:   0.75rem;
  --text-sm:   0.875rem;
  --text-base: 1rem;
  --text-lg:   1.125rem;
  --text-xl:   1.25rem;
  --text-2xl:  1.5rem;
  --text-3xl:  1.875rem;
  --text-4xl:  2.25rem;

  /* Weights. DESIGN.md hierarchy is weight + tracking, not size alone. The
     product currently sets 77% of its type at 700+, which flattens hierarchy;
     body and labels belong at 400-600 and 700 is the exception. */
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  /* THE PRODUCT'S BOLD IS 600, AND THIS LINE IS WHAT MAKES IT SO.
     Added 2026-08-27, owner-approved.

     `font-bold` in tailwind.config.js resolves to var(--fw-bold, 700), so
     whichever surface declares this variable decides what bold means there.
     This file is loaded on the five APP shells (landlord, tenant, vendor,
     owner, admin) and deliberately NOT on the public marketing shell, so:

       product   -> 600, because this line applies
       marketing -> 700, because it falls through to the fallback

     That is exactly DoorLoop's arrangement, read out of their two
     stylesheets: 700 on marketing headings, and `--font-weight-bold: 600` in
     their app's theme layer with no 700 override anywhere in the file.
     Provenance: Downloads/doorloop-type-framework/README.md.

     It is also the fix for the note three lines above this one, which has
     been true and unactioned since July: when the label, the value and the
     row title are all 700, nothing leads. This changes all 2,267 `font-bold`
     sites in the product without editing a single template.

     To revert, delete this one declaration. Nothing else depends on it. */
  --fw-bold: 600;

  --leading-tight:  1.2;
  --leading-snug:   1.35;
  --leading-normal: 1.55;
  --measure:        68ch;   /* max line length for long-form body copy */

  --tracking-tight: -0.02em;
  --tracking-label:  0.08em;  /* uppercase micro-labels */

  /* --- Elevation ---------------------------------------------------------
     Four rungs replace 1,250 bespoke recipes. All slate-900 tinted per
     DESIGN.md:192. Never pure black: rgba(0,0,0,...) reads muddy on the warm
     and tinted canvases the themes ship. Brand-tinted glows stay in
     btn-brand.css, where they belong to brand surfaces only. */
  --elev-1: 0 1px 2px rgba(15, 23, 42, 0.04);
  --elev-2: 0 1px 3px rgba(15, 23, 42, 0.06), 0 4px 12px -4px rgba(15, 23, 42, 0.08);
  --elev-3: 0 8px 24px -8px rgba(15, 23, 42, 0.12);
  --elev-4: 0 24px 48px -16px rgba(15, 23, 42, 0.18);

  /* --- Focus, the Gradient Halo (DESIGN.md:216-226) ----------------------
     Defined ONCE. Do not re-paste these literals per page; 23 files currently
     do, which is why the halo drifts. */
  --halo-hover:       0 0 0 4px rgba(106, 158, 255, 0.10);
  --halo-focus:       0 0 0 3px rgba(140, 108, 255, 0.18), 0 0 0 6px rgba(72, 226, 217, 0.12);
  --halo-border:      #6a9eff;

  /* --- Motion (DESIGN.md:147-165) ---------------------------------------- */
  --ease-out:     cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out:  cubic-bezier(0.77, 0, 0.175, 1);
  --ease-drawer:  cubic-bezier(0.32, 0.72, 0, 1);
  --dur-press:    140ms;
  --dur-fast:     180ms;
  --dur-base:     220ms;
  --dur-drawer:   340ms;

  /* --- Per-role accent ---------------------------------------------------
     Deliberate wayfinding, mirroring mobile's roleAccent: a landlord, tenant
     and vendor session feel distinct without leaving the brand. Each maps to
     one stop of the identity gradient. This divergence is INTENTIONAL; the
     divergence to unify is components, type and spacing, not accent. */
  --accent-landlord: #6a9eff;  --accent-landlord-tint: #e5f0fe;
  --accent-tenant:   #8c6cff;  --accent-tenant-tint:   #f1eeff;
  --accent-vendor:   #14b8a6;  --accent-vendor-tint:   #defcee;

  /* --- Dense data screens (DESIGN.md:232-269) ---------------------------- */
  --row-height:      52px;
  --row-height-dense:44px;
  --table-divider:   var(--border-hairline);
}
