/* ─────────────────────────────────────────────────────────
   offplan.online · design system tokens
   Source of truth: the offplan.online design system (this token file is canonical)
   Two registers: Skeleton White (marketing) · Warm Stone (product)
   ───────────────────────────────────────────────────────── */

/* Fonts — self-hosted from /fonts (locked, no third-party CDN).
   Variable cuts for Inter, Inter Tight and JetBrains Mono; four static
   weights for IBM Plex Sans Arabic (no variable cut shipped yet).
   File paths are relative to colors_and_type.css. */
@font-face {
  font-family: 'Inter Tight';
  src: url('fonts/InterTight-Variable.woff2') format('woff2-variations'),
       url('fonts/InterTight-Variable.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/Inter-Variable.woff2') format('woff2-variations'),
       url('fonts/Inter-Variable.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/JetBrainsMono-Variable.woff2') format('woff2-variations'),
       url('fonts/JetBrainsMono-Variable.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('fonts/IBMPlexSansArabic-Light.woff2')    format('woff2');
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('fonts/IBMPlexSansArabic-Regular.woff2')  format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('fonts/IBMPlexSansArabic-Medium.woff2')   format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans Arabic';
  src: url('fonts/IBMPlexSansArabic-SemiBold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}

:root {
  /* ─── Surface — Warm Stone (product) ─── */
  --surface-bg:        #FAFAF8;
  --surface-card:      #FFFFFF;
  --surface-subtle:    #F2F0ED;

  /* ─── Skeleton White (marketing) ─── */
  --skel-bg:           #F6F5F2;   /* bone */
  --skel-canvas:       #FFFFFF;
  --skel-rib:          #1A1816;   /* espresso ink — never pure black */
  --skel-rib-soft:     rgba(26,24,22,0.18);
  --skel-rib-hair:     rgba(26,24,22,0.08);
  --skel-shadow:       0 24px 60px -20px rgba(26,24,22,0.18);

  /* ─── Stone scale (Figma confirmed) ─── */
  --stone-700:         #7C7574;   /* buttons, borders, labels */
  --stone-600:         #909090;
  --stone-500:         #9A9594;   /* secondary labels */
  --stone-400:         #C5C8CA;   /* active tabs */
  --stone-200:         #E4E2DF;   /* dividers, hairlines */
  --stone-100:         #F2F0ED;

  /* ─── Atmosphere gradient (named stops) ─── */
  --atmo-sky:          #BBC8D6;
  --atmo-plaster:      #D4CBBF;
  --atmo-stone:        #C8C1B6;
  --atmo-deep:         #B8B0A8;
  --atmo-anchor:       #A8A29C;

  /* ─── Text scale (Figma confirmed; Text 900 = #323840) ─── */
  --text-900:          #323840;   /* primary UI text */
  --text-700:          #3D3B39;   /* body */
  --text-500:          #6A6865;   /* secondary */
  --text-300:          #A09E9C;   /* decorative only — never readable copy */

  /* ─── House brand accents (offplan.online itself) ─────────
     Aligned with the Volume Vision brandbook that owns offplan.online:
     Onyx is the HERO (strength, depth), Moss is the ACCENT (buttons,
     focus rings, prices, one-per-view highlights), Stone is the
     background wash. The palette is intentionally cool and mineral —
     "glassy" — so that when a project's brand renders on top, it is
     the only saturated thing on the page. */
  --moss:              #6A7061;       /* primary house accent — VV Moss */
  --moss-soft:         #8B9285;       /* hover / lighter pair */
  --moss-bg:           rgba(106,112,97,0.10);
  --onyx:              #1C1C1C;       /* hero / depth — VV Onyx */

  /* ─── Status (traditional traffic-light, but oxidised) ─────
     Available · forest, Reserved · burnt honey, Sold · oxblood.
     Muted enough to live next to mineral neutrals; still reads
     correctly to anyone scanning a unit grid for the first time. */
  --status-available:    #5C7A4A;   /* muted forest green */
  --status-reserved:     #8A5E1F;   /* burnt honey amber — deepened to clear WCAG AA (~5.3:1 on light) */
  --status-sold:         #8A4438;   /* oxblood / aged brick */
  --status-available-bg: rgba(92,122,74,0.16);
  --status-reserved-bg:  rgba(138,94,31,0.16);
  --status-sold-bg:      rgba(138,68,56,0.14);

  /* ─── Data viz palette (sequential, never rainbow) ─── */
  --viz-1: #1C1C1C;  --viz-2: #3D5266;  --viz-3: #7C7574;
  --viz-4: #6A7061;  --viz-5: #8B9285;  --viz-6: #A8A29C;  --viz-7: #D4CBBF;

  /* ─── Quiet dark surface (admin chrome only) ──────────────
     We deliberately do not ship a marketed dark mode — the
     marketing register is sun-bleached stone, and a heavy
     navy-night palette fought it. These two tokens exist only
     so admin nav rails / modal scrims have a credible deep
     surface to sit on. Do NOT use as a marketing background. */
  --ink-surface:       #1A1816;       /* espresso, same family as --skel-rib */
  --ink-hairline:      rgba(255,255,255,0.10);

  /* ─── Shadows (premium-restraint, low opacity) ─── */
  --shadow-subtle:     0 2px 8px  rgba(0,0,0,0.06);
  --shadow-card:       0 8px 24px rgba(0,0,0,0.10);
  --shadow-float:      0 16px 40px rgba(0,0,0,0.14);

  /* ─── Type families (chosen pairing) ─── */
  --font-display:      'Inter Tight', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-body:         'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:         'JetBrains Mono', 'Courier New', monospace;
  --font-arabic:       'IBM Plex Sans Arabic', 'Inter', sans-serif;

  /* ─── Tracking ─── */
  --tracking-tight:    -0.035em;   /* display headlines */
  --tracking-tightish: -0.02em;
  --tracking-nav:       0.16em;
  --tracking-wide:      0.14em;
  --tracking-wider:     0.18em;
  --tracking-mega:      0.32em;    /* hero eyebrows */
  /* Operational tracking — used on UI labels + card titles. Chosen
     visually after the EN + RU comparison pass: opens the script
     enough to stop Cyrillic feeling cramped, while still reading
     intentional on Latin. Apply to .section-label and the card
     title role. Do not invent intermediate values. */
  --tracking-ui:        0.05em;

  /* ─── Locked weights for the two operational UI roles ──────────
     These rely on the variable-font import above. Real values, not
     snapped to nearest static instance. Locked after EN + RU + tracking
     comparison. Do not invent intermediate weights. */
  --weight-section-label:  450;     /* "Available units · L20+"  · Доступные... */
  --weight-card-title:     350;     /* "Sky Villa · 4 BR + study" · Пентхаус... */

  /* ─── Radius (Apple-like continuous corners — never overly square) ─── */
  --radius-xs:         6px;    /* chips, micro pills */
  --radius-sm:         10px;   /* small buttons, inputs */
  --radius-md:         14px;   /* default buttons, fields, small cards */
  --radius-lg:         20px;   /* cards, panels */
  --radius-xl:         28px;   /* sheets, large surfaces */
  --radius-pill:       999px;  /* status pills */

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

  /* ─── Layout ─── */
  --shell-max:        1240px;
  --shell-pad-sm:     24px;
  --shell-pad-md:     32px;
  --shell-pad-lg:     48px;

  /* ─── Motion (premium-restraint) ─── */
  --ease-out:          cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in:           cubic-bezier(0.4, 0, 1, 1);
  --ease-in-out:       cubic-bezier(0.4, 0, 0.2, 1);
  --duration-micro:    120ms;   /* hover, opacity */
  --duration-page:     200ms;   /* filter, view changes */
  --duration-panel:    280ms;   /* sidebar, modal entry */
  --duration-wing:     720ms;   /* marketing reveals only — sculptural */

  /* ─── Density ─── */
  --field-h:           44px;    /* comfortable */
  --field-h-compact:   32px;
  --row-h:             56px;
  --row-h-compact:     40px;

  /* ─── Hit target ─── */
  --tap-min:           44px;    /* mobile */
  --click-min:         32px;    /* desktop */
}

/* ─── Semantic typography ─── */
.h1, h1 {
  font-family: var(--font-display);
  font-size: 88px;        font-weight: 200;
  line-height: 0.98;      letter-spacing: 0;
  color: var(--text-900);
}
.h2, h2 {
  font-family: var(--font-display);
  font-size: 44px;        font-weight: 300;
  line-height: 1.05;      letter-spacing: 0;
  color: var(--text-900);
}
.h3, h3 {
  font-family: var(--font-display);
  font-size: 28px;        font-weight: 300;
  line-height: 1.15;      letter-spacing: 0;
  color: var(--text-900);
}
.h4, h4 {
  font-family: var(--font-display);
  font-size: 18px;        font-weight: 400;
  letter-spacing: 0.025em;
  color: var(--text-900);
}
.eyebrow {
  font-family: var(--font-display);
  font-size: 11px;        font-weight: 500;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  color: var(--text-500);
}
.eyebrow-mega {
  font-family: var(--font-display);
  font-size: 11px;        font-weight: 500;
  letter-spacing: var(--tracking-mega);
  text-transform: uppercase;
  color: var(--text-500);
}
.label {
  font-family: var(--font-display);
  font-size: 12px;        font-weight: 500;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-900);
}
.body, p {
  font-family: var(--font-body);
  font-size: 15px;        line-height: 1.6;
  color: var(--text-700);
}
.body-sm, .small {
  font-family: var(--font-body);
  font-size: 13px;        line-height: 1.55;
  color: var(--text-500);
}
.mono, .meta {
  font-family: var(--font-mono);
  font-size: 11px;        letter-spacing: 0.08em;
  color: var(--text-500);
}
.price {
  font-family: var(--font-display);
  font-size: 28px;        font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--moss);
}

/* Two operational roles that sit beneath h1–h4. Both share the
   --tracking-ui (+0.05em) token; they only differ in weight. */
.section-label, .ui-section-label {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: var(--weight-section-label);
  letter-spacing: var(--tracking-ui);
  color: var(--text-900);
}
.card-title, .ui-card-title {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: var(--weight-card-title);
  letter-spacing: var(--tracking-ui);
  color: var(--text-900);
}
.lede {
  font-family: var(--font-body);
  font-size: 18px;        line-height: 1.55;
  color: var(--text-700);
  text-wrap: pretty;
}

/* Per-script bindings — declare lang="xx" on the surface; the right
   family + tracking adjustments apply automatically. */
[lang="ar"] { direction: rtl; font-family: var(--font-arabic); }
[lang="zh"], [lang="zh-CN"] { font-family: 'Noto Sans SC', var(--font-body); }
[lang="hi"] { font-family: 'Noto Sans Devanagari', var(--font-body); }

/* ─── Reduced motion ─── */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-micro: 0ms; --duration-page: 0ms;
    --duration-panel: 0ms; --duration-wing: 0ms;
  }
}

/* ─────────────────────────────────────────────────────────
   ADAPTIVE TEXT PRIMITIVE  ─  luminance-driven contrast
   ─────────────────────────────────────────────────────────
   Surfaces that sit over imagery (hero blocks, glass panes,
   project covers, render-over-render compositions) flip their
   text ink between Onyx and paper White based on what's
   actually behind the text.

   How:
   1.  Add `data-adaptive` to the surface element.
   2.  Make sure `system/adaptive-text.js` is loaded once
       per page (the script auto-boots on DOMContentLoaded).
   3.  Inside the surface, reference --surface-fg + --surface-shadow
       on any text element. They default to the dark-bg branch
       (white text + dark shadow) so the layout never breaks
       even when JS is off or the image is cross-origin.

   Optional attributes:
     data-sample-from="#selector"  · point the sampler at a
                                     different element's bitmap
     data-sample-rect="bottom"     · which 25% strip to read
                                     (top | bottom | center | full)

   The script also dispatches an `adaptive-text:decided` event
   on the surface — listen for it to chain custom adjustments
   (e.g. swap a logo asset between light/dark variants).
   ───────────────────────────────────────────────────────── */

/* ─────────────────────────────────────────────────────────
   CAPTION PLATE  ─  retired
   The first ship of this primitive added a semi-opaque band
   under hero captions. We reverted: the brand requires pure
   text-on-image with adaptive ink, no extra surface element.
   The token below is kept as a 0-cost class so existing markup
   that referenced it doesn't break, but it applies nothing.
   ───────────────────────────────────────────────────────── */
.caption-plate { /* intentionally empty — adaptive ink does the work */ }

/* Fallbacks: every adaptive surface starts on the dark-bg branch
   so a slow-loading sampler never strands text in the wrong colour.
   Shadows are deliberately HEAVY (16–22 px blur, 70% alpha) because
   text now relies entirely on ink contrast — no scrim, no plate. */
[data-adaptive] {
  --surface-fg:     #FAFAF8;
  --surface-ink:    #FAFAF8;
  --surface-shadow: 0 2px 18px rgba(0,0,0,0.70), 0 1px 3px rgba(0,0,0,0.55);
}

/* When the sampler decides "light backdrop", the script writes
   onto the element directly — these are just the documented values. */
[data-adaptive][data-adaptive-mode="light-bg"] {
  --surface-fg:     #1C1C1C;
  --surface-ink:    #1C1C1C;
  --surface-shadow: 0 2px 18px rgba(255,255,255,0.70), 0 1px 3px rgba(255,255,255,0.55);
}

/* Convenience: every text element that descends from an adaptive
   surface and opts in via .on-surface picks up the chosen ink.
   Authors can also reference --surface-fg directly. */
.on-surface,
[data-adaptive] .adaptive-text {
  color: var(--surface-fg);
  text-shadow: var(--surface-shadow);
  transition: color 200ms var(--ease-out), text-shadow 200ms var(--ease-out);
}

/* ─────────────────────────────────────────────────────────
   PROJECT BRAND CONTRACT  ─  per-development overrides
   ─────────────────────────────────────────────────────────
   The Sales App and the marketing kit both render for a
   specific developer/project (e.g. Aldar · Côte Résidence).
   Each project ships its own brand identity layered on top
   of offplan.online's house identity:

     · a wordmark / logo asset
     · 1 primary accent + 1 supporting tone
     · a 5-stop tinted map ramp (for the Locations page)

   Implementation: every project-themable surface uses the
   --proj-* CSS variables below. They DEFAULT to the
   offplan.online house identity. To re-theme any subtree,
   set [data-project="<slug>"] on a parent (typically <body>).

   Contract:
     --proj-name           project display name
     --proj-accent         primary accent (price, CTA, focus)
     --proj-accent-soft    hover / lighter pair
     --proj-accent-bg      low-opacity wash (rings, chips)
     --proj-deep           depth color (footer, hero stamp)
     --proj-on-deep        text on --proj-deep
     --proj-logo           url() of the project wordmark (svg)
     --proj-logo-mark      url() of the icon-only mark (svg)
     --proj-logo-on-dark   url() of the inverted wordmark (svg)
     --proj-map-water      map: water bodies
     --proj-map-land       map: building blocks
     --proj-map-park       map: green / parks
     --proj-map-road       map: roads / strokes
     --proj-map-pin        map: project pin + ribbon

   Hard rules:
     · One accent per project. Never mix two project accents
       on the same view.
     · Project identity NEVER overrides type, density,
       spacing, or status semantics. Sage / moss / charcoal
       remain house tokens for product status.
     · House moss and project accent never coexist on the
       same view. Add `.project-themed` to opt a marketing
       subtree into using --proj-accent in place of --moss.
     · Admin-panel chrome NEVER themes — agents must always
       know which side of the wall they are on.
     · Project logos render at the same height as the
       offplan wordmark (24px / 28px / 36px). No exceptions.
   ─────────────────────────────────────────────────────── */

:root {
  --proj-name:          'offplan.online';
  --proj-accent:        var(--moss);
  --proj-accent-soft:   var(--moss-soft);
  --proj-accent-bg:     var(--moss-bg);
  --proj-deep:          var(--onyx);
  --proj-on-deep:       #FFFFFF;
  --proj-logo:          url('../assets/brand/wordmark.svg');
  --proj-logo-mark:     url('../assets/brand/wordmark.svg');     /* TODO: ship a mark-only SVG */
  --proj-logo-on-dark:  url('../assets/brand/wordmark.svg');     /* TODO: ship an inverted (paper-white) SVG */

  --proj-map-water:     #C9D6DE;
  --proj-map-land:      #ECE7DD;
  --proj-map-park:      #C9D4B6;
  --proj-map-road:      #FFFFFF;
  --proj-map-pin:       var(--moss);
}

/* Status pill — stronger weight + halo so it reads atop any imagery */
.status-pill { font-weight: 500; }
.unit-card__status {
  box-shadow:
    0 0 0 1px rgba(255,255,255,0.92),
    0 1px 3px rgba(0,0,0,0.18);
}

/* Opt-in: rebind house moss → project accent on this subtree.
   Use on marketing register (sales-presentation, locations,
   brochure). Admin chrome stays on house moss. */
.project-themed {
  --moss:               var(--proj-accent);
  --moss-soft:          var(--proj-accent-soft);
  --moss-bg:            var(--proj-accent-bg);
  --onyx:               var(--proj-deep);
  --status-reserved:    var(--proj-accent);
  --status-reserved-bg: var(--proj-accent-bg);
}

/* Three reference projects — illustrative only.
   Real projects ship their own block, generated when the
   developer onboards via the Admin Panel "Brand identity" form. */

[data-project="cote"] {
  --proj-name:          'Côte Résidence';
  --proj-accent:        #6B7F6E;            /* sage-leaning, marine */
  --proj-accent-soft:   #8FA293;
  --proj-accent-bg:     rgba(107,127,110,0.10);
  --proj-deep:          #1C1C1C;
  --proj-map-water:     #B8CDD6;
  --proj-map-land:      #ECE7DD;
  --proj-map-park:      #C5D2B5;
  --proj-map-pin:       #6B7F6E;
}

[data-project="velvet"] {
  --proj-name:          'Velvet';
  --proj-accent:        #7C4A5E;            /* burgundy / mulberry */
  --proj-accent-soft:   #9F6A7E;
  --proj-accent-bg:     rgba(124,74,94,0.10);
  --proj-deep:          #2A1A24;
  --proj-on-deep:       #F4E9DC;
  --proj-map-water:     #D4C2C9;
  --proj-map-land:      #EFE5E1;
  --proj-map-park:      #C9C2B0;
  --proj-map-pin:       #7C4A5E;
}

[data-project="redwall"] {
  --proj-name:          'Redwall Heights';
  --proj-accent:        #1F4E6A;            /* deep teal-blue */
  --proj-accent-soft:   #4A7A93;
  --proj-accent-bg:     rgba(31,78,106,0.10);
  --proj-deep:          #0D2538;
  --proj-map-water:     #B8C9D6;
  --proj-map-land:      #EAE5DD;
  --proj-map-park:      #C0CEB5;
  --proj-map-pin:       #1F4E6A;
}
