/* ==========================================================================
   Propertybuyer, token layer. Shared by every page in this repository.
   --------------------------------------------------------------------------
   Every value below is an alias of a token in Figma "2. Mapped".
   Source: Property Buyer, Source, file 0cUUO8Qye1DBPPPGhmPWmr
   Values pulled from Figma Variables 13 August 2026, not from the DESIGN.md
   snapshot. Where the two disagreed, Figma won. See HANDOVER.md.
   Nothing here is a raw value chosen by hand.

   THIS FILE IS NOT EDITED BY A PAGE BUILD. It was split out of styles.css on
   21 August 2026 so that the paid landing pages and the location pages could
   be built in parallel without colliding in one file. A page build changes
   its own design layer, never this one. A value changed here changes every
   page in the repository, so it needs a fresh read of Figma Variables and a
   line in HANDOVER.md.

   Load order, every page, in this order and never fewer:
     1. assets/css/tokens.css     this file, tokens and the two faces
     2. assets/css/base.css       reset, base type, buttons, pills
     3. assets/css/landing.css    OR locations.css, never both
   ========================================================================== */

:root {
  /* --- Backgrounds ------------------------------------------------------ */
  --bg-page: #ffffff;            /* bg/page          base/white  */
  --bg-surface: #fbfaf7;         /* bg/surface       sand/50     */
  --bg-surface-alt: #f5f1e9;     /* bg/surface-alt   sand/100    */
  --bg-brand: #00404b;           /* bg/brand         teal/700    */
  --bg-brand-deep: #02313a;      /* bg/brand-deep    teal/800    */
  --bg-info-subtle: #e8eef0;     /* bg/info-subtle   teal/100    */
  --bg-success-subtle: #eff6f1;  /* bg/success-subtle success/50 */
  --bg-warning-subtle: #fff8e8;  /* bg/warning-subtle warning/50 */
  --bg-error-subtle: #fbf0ef;    /* bg/error-subtle  destructive/50 */

  /* FLAG, do not use until resolved. The Figma variable bg/prestige resolves
     to #001114 (teal/950), but its own description and the Colours page both
     say night/950 #1B1C25, "not a teal", client direction 3 Aug 2026. There is
     no night ramp in Base Values. The documented ratio text/prestige on
     bg/prestige = 7.15 only computes against #1B1C25; against #001114 it is
     8.13. Unused on this page. See HANDOVER.md. */
  --bg-prestige: #001114;        /* bg/prestige      CONFLICTED  */

  /* --- Text ------------------------------------------------------------- */
  --text-heading: #00404b;       /* text/heading     teal/700    */
  --text-body: #1c2b2f;          /* text/body        grey/900    */
  --text-muted: #5c6b6f;         /* text/muted       grey/500    */
  --text-on-brand: #ffffff;      /* text/on-brand    base/white  */
  --text-on-brand-muted: #b6c8cb;/* text/on-brand-muted teal/300 */
  --text-link: #00404b;          /* text/link        teal/700    */
  --text-prestige: #c9a26b;      /* text/prestige    gold/400    */
  --text-highlight: #ff7f22;     /* text/highlight   orange/500  */
  --text-info: #00404b;          /* text/info        teal/700    */
  --text-success: #2f5f42;       /* text/success     success/700 */
  --text-warning: #a87c0e;       /* text/warning     warning/700 */
  --text-error: #b0392e;         /* text/error       destructive/600 */

  /* --- Borders ---------------------------------------------------------- */
  --border-default: #e4e0d8;     /* border/default   sand/200    */
  --border-muted: #d2d9da;       /* border/muted     grey/200    */
  --border-brand: #00404b;       /* border/brand     teal/700    */
  --border-focus: #00404b;       /* border/focus     teal/700    */
  --border-info: #526f75;        /* border/info      teal/500    */
  --border-success: #a3cdb1;     /* border/success   success/300 */
  --border-warning: #e6c96a;     /* border/warning   warning/300 */
  --border-error: #b0392e;       /* border/error     destructive/600 */

  /* --- Actions ---------------------------------------------------------- */
  --action-primary: #a26246;         /* action/primary       terracotta/500, white 4.80 */
  --action-primary-hover: #89533b;   /* action/primary-hover terracotta/600, white 6.24 */
  --action-prestige: #c9a26b;        /* action/prestige      gold/400   */
  --action-prestige-hover: #b18a50;  /* action/prestige-hover gold/500  */

  /* Derived in code, not a token. Interactive States rule: pressed moves
     15 percent away from the background, hover moves 8. Mapped holds no
     pressed value for either action, so the fallback lives here, which is
     where DESIGN.md says a fallback belongs. */
  --action-primary-pressed: color-mix(in oklab, var(--action-primary), black 15%);
  --action-prestige-pressed: color-mix(in oklab, var(--action-prestige), black 15%);

  /* Also derived, not a token. Mapped holds no bg/brand-hover: its only
     hover values are action/primary-hover and action/prestige-hover. The
     closer band was asked for "the brand hover colour", dark and distinct
     from the footer, so this follows the Interactive States rule in
     DESIGN.md section 6, 8 percent away from the surface for hover. It
     lands between bg/brand and bg/brand-deep, so the closer reads a step
     darker than the brand band and still separates from the footer.
     Requested 18 Aug 2026, pending a real token. See HANDOVER.md. */
  --bg-brand-hover: color-mix(in oklab, var(--bg-brand), black 8%);

  /* --- Spacing, nine tokens --------------------------------------------- */
  --space-section-y: 48px;       /* space/section-y  48 mobile, 80 from 768 */
  --space-gutter: 20px;          /* space/gutter     */
  --gap-lg: 40px;                /* space/gap-lg     sparse  */
  --gap: 24px;                   /* space/gap        standard */
  --gap-sm: 12px;                /* space/gap-sm     dense   */
  --tap-min: 44px;               /* space/tap-min    constraint, every viewport */
  --container: 1200px;           /* space/container  */
  --content-max: 1160px;         /* space/content-max */
  --measure-intro: 760px;        /* space/measure-intro */

  /* --- Radius, two tokens ------------------------------------------------ */
  --radius-card: 8px;            /* radius/card      */
  --radius-pill: 999px;          /* radius/pill      */

  /* --- Type sizes, mobile column ---------------------------------------- */
  --type-stat: 40px;             /* type/stat     52 desktop, 40 at 390 */
  --type-display: 34px;          /* type/display  44 desktop, 34 at 390 */
  --type-h2: 28px;               /* type/h2       34 desktop, 28 at 390 */
  --type-h3: 18px;               /* type/h3       20 desktop, 18 at 390 */
  --type-body: 16px;             /* type/body     16 at every viewport  */
  --type-small: 14px;            /* type/small    14 at every viewport  */
  --type-micro: 13px;            /* type/micro    13 at every viewport  */
  --type-button: 16px;           /* type/button   16 at every viewport  */

  /* --- Font tokens ------------------------------------------------------- */
  --family-display: "Proyale", Georgia, serif;
  --family-text: "Geist", Helvetica, Arial, sans-serif;
  --tracking-display: -0.02em;   /* font/tracking-display  H1 and H2 */
  --tracking-heading: -0.015em;  /* font/tracking-heading  H3 down   */
  --tracking-body: -0.01em;      /* font/tracking-body     */
  --tracking-button: -0.005em;   /* font/tracking-button   */
  --tracking-caps: 0.04em;       /* font/tracking-caps     uppercase micro only */
}

@media (min-width: 768px) {
  :root {
    --space-section-y: 80px;
    --type-stat: 52px;
    --type-display: 44px;
    --type-h2: 34px;
    --type-h3: 20px;
  }
}

/* ==========================================================================
   Fonts
   Proyale is supplied by the design lead and is in this repo, converted from
   the source TTF to WOFF2. It ships one weight, 400. Never ask a browser for
   Proyale Bold: it will synthesise one, badly.

   Proyale is a CAPITALS-ONLY face. Its lowercase glyphs have outlines and
   bounds identical to the uppercase, with no x-height and no descenders, so
   H1 and H2 render as capitals whatever case is typed. No text-transform is
   applied anywhere; the face does it. ACCEPTED 13 Aug 2026 as a property of
   the face rather than a breach of the sentence case rule, which governs how
   copy is written, not how a chosen face renders it. Write H1 and H2 in
   sentence case regardless: the fallback, Georgia, is mixed case and renders
   them that way until Proyale loads.

   Geist is in, one variable file, open licensed and self hosted with no CDN.
   Supplied 13 Aug 2026.
   ========================================================================== */

@font-face {
  font-family: "Proyale";
  src: url("../fonts/proyale-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Geist is a single variable file covering the whole 100 to 900 axis, which is
   67 KB against 131 KB for the four static cuts this previously declared, and
   one request rather than four. The page asks for 300, 400, 600 and 700; the
   axis serves all four. Supplied 13 Aug 2026. */
@font-face {
  font-family: "Geist";
  src: url("../fonts/geist-variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
/* ==========================================================================
   Token addendum, Paper theme
   --------------------------------------------------------------------------
   Source: Paper.Design "Property Buyer - Landing Page - Buyer", file
   01KZW0Y27PGW3NV0QJRPXAJ9DZ, artboard "BUYER 1440", read 17 August 2026.
   The design lead authored these in Paper on top of the 13 August Figma
   snapshot above. Where the two disagree, the Paper value is used by the
   design layer and the disagreement is recorded in HANDOVER.md so Figma can
   be brought up to date. Nothing here is a value chosen by hand in code.
   ========================================================================== */

:root {
  /* --- Spacing added in Paper ------------------------------------------- */
  --gap-xs: 4px;                 /* Paper --space-gap-xsm */
  --gap-xl: 64px;                /* Paper --space-gap-xl  */

  /* Paper --space-section-y is 120 desktop, 48 in the mobile-390 mode. The
     Figma token above stays 48/80 until Figma is updated; the design layer
     uses this one. */
  --band-y: 48px;

  /* --- Radius added in Paper --------------------------------------------- */
  --radius-avatar: 4px;          /* Paper --radius-avatar */
  --radius-avatar-inner: 2px;    /* Paper --radius-avatar-inner */

  /* --- Type: Paper h3 is 24 desktop. Mobile derived at 20 pending an
     authored mobile value, recorded in HANDOVER.md. ----------------------- */
  --type-h3-card: 20px;

  /* --- Weights, named in Paper ------------------------------------------- */
  --weight-display: 400;
  --weight-body: 300;
  --weight-regular: 400;
  --weight-medium: 500;          /* used by Paper on step titles and pills */
  --weight-semibold: 600;
  --weight-bold: 700;

  /* --- Colour values that exist only in the Paper design ----------------- */
  /* Dark pill gradient, oklab stops from Paper. Approx teal/700 to teal/800. */
  --grad-pill-dark: linear-gradient(0deg in oklab, oklab(16.2% -0.025 -0.013) 0%, oklab(21.5% -0.028 -0.018) 100%);
  /* Light pill gradient, sand tokens. */
  --grad-pill-light: linear-gradient(1deg in oklab, var(--bg-surface-alt) 4.86%, var(--bg-page) 95.91%);
  /* Stats band gradient, oklab stops from Paper. Lighter teal ramp. */
  --grad-band-teal: linear-gradient(90deg in oklab, oklab(42.6% -0.051 -0.034) 27.61%, oklab(34.1% -0.05 -0.033) 72.4%);
  /* Photo fades. */
  --fade-photo-dark: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.5) 100%);
  --fade-brand-deep: linear-gradient(180deg in oklab, oklab(16.2% -0.025 -0.013 / 0%) 0%, oklab(16.2% -0.025 -0.013 / 90%) 100%);
  /* Frosted surfaces on dark bands. */
  --bg-frost: #FFFFFF26;         /* white 15, hero avatar cards */
  --bg-frost-subtle: #FFFFFF1A;  /* white 10, stats review pill */
  --border-on-brand: #FFFFFF24;  /* white 14, footer rule */
  --bg-photo-fallback: #D6D1C4;  /* behind auction photography */

  /* --- Shadow stacks from Paper, declared once --------------------------- */
  --shadow-btn: 0 2px 2px rgba(0,0,0,0.2), 0 3px 4px rgba(0,0,0,0.1), 0 5px 16px rgba(0,0,0,0.1);
  --shadow-pill-dark: drop-shadow(0 4px 5px rgba(0,0,0,0.29)) drop-shadow(0 18px 9px rgba(0,0,0,0.26));
  --shadow-pill-light: drop-shadow(0 4px 5px rgba(0,0,0,0.1)) drop-shadow(0 18px 9px rgba(0,0,0,0.06));
  /* A box-shadow, not the drop-shadow filter stack Paper exports. These cards
     are sticky, opaque and rectangular, so drop-shadow bought nothing that
     box-shadow does not: it draws the same shadow, because a filter blur
     radius and a box-shadow blur radius are both twice the deviation. What it
     did buy was a filter over four sticky cards that each hold a live WebGL
     canvas, which forces the whole subtree down the repaint path every time
     the stack moves. Measured scrolling the stack three times at 1440px,
     18 Aug 2026: worst frame 300 to 633ms and 4 to 13 dropped frames per
     pass, against a clean 17ms and none once this became a box-shadow.
     Verified by isolation, so keep shadows off `filter` on this component. */
  --shadow-card-stack: 0 1px 2px rgba(0,17,20,0.06), 0 4px 7px rgba(0,17,20,0.05), 0 8px 14px rgba(0,17,20,0.05), 0 15px 24px rgba(0,17,20,0.04);
  --shadow-cta-panel: 0 1px 2px rgba(0,32,38,0.07), 0 6px 10px -4px rgba(0,32,38,0.1), 0 18px 28px -10px rgba(0,32,38,0.14), 0 40px 60px -24px rgba(0,32,38,0.22);
  --shadow-badge: drop-shadow(0 4px 5px rgba(0,0,0,0.29)) drop-shadow(0 10px 14px rgba(0,0,0,0.18));
  --shadow-avatar-card: 0 2px 8px rgba(0,0,0,0.1);

  /* --- Marquee edge fade, a mask not a colour ---------------------------- */
  --mask-marquee: linear-gradient(90deg, transparent 0%, rgb(0,0,0) 8%, rgb(0,0,0) 92%, transparent 100%);
}

@media (min-width: 768px) {
  :root {
    --band-y: 120px;
    --type-h3-card: 24px;
  }
}
