/* Theme — Gravity design tokens
 *
 * This file does two things:
 *   1. BRIDGE: Maps project tokens → base.css contract vars
 *   2. PROJECT: Defines Gravity-specific tokens (status, avatars, rings)
 *
 * To re-theme: replace this file. All pages (admin, devise, app, landing)
 * update automatically through the contract vars.
 *
 * Contract vars set here (consumed by base.css):
 *   --color-primary, --color-primary-rgb, --color-bg, --color-surface
 *   --color-border, --color-text, --color-text-muted
 *   --color-success, --color-success-bg, --color-danger, --color-danger-bg
 *   --color-warning, --color-warning-bg
 *   --font-sans, --radius
 */

:root {
  /* ── Gravity design tokens ──────────────────────────────────── */

  /* Base */
  --bg-base:       #FAF7F2;
  --bg-card:       #FFFFFF;
  --bg-muted:      #F5F0E8;
  --bg-page:       #F2EEE7;
  --border:        #EAE4DA;
  --border-light:  #E0D8CC;

  /* Text */
  --text-primary:   #2A2418;
  --text-secondary: #6B6155;
  --text-tertiary:  #7B7064;
  --text-label:     #7A7060;
  --text-mid:       #6A6050;

  /* Theme-invariant dark ink — stays #2A2418 in BOTH themes (deliberately NOT
     overridden in the dark block below). For chrome where white/#fff sits on
     top regardless of theme: the admin header bar, and labels on always-light
     fills (the person-card "Say hello" button). --text-primary can't serve
     this — it flips to light in dark mode and the white-on-top would vanish. */
  --ink-fixed: #2A2418;

  /* Accent */
  --accent:      #C17B4A;
  --accent-text: #935830;
  --accent-bg:   #F5EFE6;
  --accent-dark: #9A5D35;

  /* Status */
  --status-overdue-bg:    #FAECE7;
  --status-overdue-text:  #993C1D;
  --status-due-bg:        #FAEEDA;
  --status-due-text:      #854F0B;
  --status-ok-bg:         #EAF3DE;
  --status-ok-text:       #3B6D11;
  --status-upcoming-bg:   #F0EDE6;
  --status-upcoming-text: #7A7060;

  /* Level colors — one canonical token per level, used everywhere a person's
     relationship depth is signalled: the warmth-ring stroke, the person card
     fill, the avatar-circle background, the onboarding picker, the mailer
     avatars. Same token across surfaces so the ring color and avatar color
     of any one person always agree.

     Decision + alternatives: docs/design/decisions/2026-05-07-color-system.md
     Brand brown (--accent) is intentionally NOT reused here — it stays the
     unique action / brand color and never doubles as a level identifier. */
  --level-inner-circle:  #B85F3D; /* terracotta — closest, warm, brand-adjacent */
  --level-friends:       #7BAE85; /* sage — grounded middle */
  --level-keep-in-touch: #6B7BB5; /* dusty indigo — cool, distant */

  /* Track sits behind the colored ring arcs and is level-agnostic. */
  --ring-track:          #EAE4DA;

  /* ── Bridge: map Gravity tokens → base.css contract ─────────── */
  --color-primary:     var(--accent);
  --color-primary-rgb: 193, 123, 74;
  --color-bg:          var(--bg-base);
  --color-surface:     var(--bg-card);
  --color-border:      var(--border);
  --color-text:        var(--text-primary);
  --color-text-muted:  var(--text-secondary);

  --color-success:     var(--status-ok-text);
  --color-success-bg:  var(--status-ok-bg);
  --color-danger:      var(--status-overdue-text);
  --color-danger-bg:   var(--status-overdue-bg);
  --color-warning:     var(--status-due-text);
  --color-warning-bg:  var(--status-due-bg);

  /* Three roles per Blueprint contract (see blueprint/01-stack/css-ownership.md).
     Lora handles display, DM Sans is the body-grade slot. Gravity already
     has display + body separation; no font change needed here. */
  --font-display: 'Lora', serif;
  --font-body:    'DM Sans', system-ui, -apple-system, sans-serif;
  --font-sans:    var(--font-body);  /* contract bridge */
  --radius:    14px;

  /* ── Content column width — scales up on tablet ──────────── */
  /* Mobile-first: 400px. Override per breakpoint below.        */
  --app-content-width: 400px;

  /* ── Type scale ───────────────────────────────────────────── */
  /* Targets (at mobile root font-size 17px):
   *   display  28px    title    22px    heading  18px
   *   body     16px    body-sm  14px    caption  13px
   *   micro    12px    nano     11px
   * Scale proportionally at the 18/19px tablet breakpoints.
   * Never hardcode font-size in stylesheets — reach for a token.
   */
  --text-display:  1.65rem;
  --text-title:    1.30rem;
  --text-heading:  1.06rem;
  --text-body:     0.94rem;
  --text-body-sm:  0.82rem;
  --text-caption:  0.76rem;
  --text-micro:    0.71rem;
  --text-nano:     0.65rem;
}

/* ── Dark theme ───────────────────────────────────────────────────────
   Override only the Gravity base tokens. The base.css contract vars
   (--color-bg, --color-surface, --color-text, …) reference these through
   var() and re-resolve automatically — both the contract and direct
   --bg-*/--text-*/--status-* token users flip with zero per-page CSS.
   `#fff` text on colored fills (person card, status badges, accent
   buttons) stays correct because those fills stay colored.

   Two activation paths, same palette:
     • [data-theme="dark"]              — explicit Dark choice
     • [data-theme="system"] + OS dark  — System choice, OS in dark mode
   The server renders <html data-theme> from User#theme, so the right
   palette is present on first paint — no flash, no inline script.

   Level colors (terracotta/sage/indigo) keep their HUE identity on dark but
   are deepened ~15% in luminance below — at full light-mode saturation they
   read as neon blocks against the warm-dark surface. The deeper variants
   harmonise with the dark palette and improve white-on-fill contrast, while
   staying unmistakably the same three colors. (Candidate — 2026-06-12.) */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] { color-scheme: dark; }
}

:root[data-theme="dark"] {
  --bg-base:   #17130D;  --bg-card:   #201B14;  --bg-muted: #29231B;  --bg-page: #110E09;
  --border:    #39322A;  --border-light: #463E33;

  --text-primary:   #F3EFE8;  --text-secondary: #BDB3A4;  --text-tertiary: #9F9485;
  --text-label:     #A89D8C;  --text-mid:       #B1A696;

  --accent:      #D9935F;  --accent-text: #E8B084;  --accent-bg: #2E251B;  --accent-dark: #C17B4A;
  --color-primary-rgb: 217, 147, 95;

  --status-overdue-bg:  #3A241C;  --status-overdue-text:  #F2AA8E;
  --status-due-bg:      #392E15;  --status-due-text:      #F0C674;
  --status-ok-bg:       #233019;  --status-ok-text:       #ABD27E;
  --status-upcoming-bg: #2A271F;  --status-upcoming-text: #B1A696;

  --ring-track: #39322A;

  /* Dark-harmony level colors — same hue, deeper luminance (see note above). */
  --level-inner-circle:  #9A5234;  /* terracotta, deepened */
  --level-friends:       #568A66;  /* sage, deepened */
  --level-keep-in-touch: #54639C;  /* dusty indigo, deepened */
}

@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    --bg-base:   #17130D;  --bg-card:   #201B14;  --bg-muted: #29231B;  --bg-page: #110E09;
    --border:    #39322A;  --border-light: #463E33;

    --text-primary:   #F3EFE8;  --text-secondary: #BDB3A4;  --text-tertiary: #9F9485;
    --text-label:     #A89D8C;  --text-mid:       #B1A696;

    --accent:      #D9935F;  --accent-text: #E8B084;  --accent-bg: #2E251B;  --accent-dark: #C17B4A;
    --color-primary-rgb: 217, 147, 95;

    --status-overdue-bg:  #3A241C;  --status-overdue-text:  #F2AA8E;
    --status-due-bg:      #392E15;  --status-due-text:      #F0C674;
    --status-ok-bg:       #233019;  --status-ok-text:       #ABD27E;
    --status-upcoming-bg: #2A271F;  --status-upcoming-text: #B1A696;

    --ring-track: #39322A;

    /* Dark-harmony level colors — same hue, deeper luminance (see note above). */
    --level-inner-circle:  #9A5234;  /* terracotta, deepened */
    --level-friends:       #568A66;  /* sage, deepened */
    --level-keep-in-touch: #54639C;  /* dusty indigo, deepened */
  }
}

/* Root font-size — SCALABLE (was a hard 17px pin, which defeated user font
   scaling — WCAG 1.4.4 Resize Text). It is now a PERCENTAGE of the UA default
   (16px), so a browser/PWA whose default-font-size preference is raised scales
   Gravity's whole rem-based token ladder. 106.25% × 16px = 17px, our baseline.
   Zoom is also re-enabled on every surface (see ApplicationHelper#viewport_meta_tag),
   so pinch-to-zoom works as the universal resize escape hatch.
   Native OS Dynamic Type (the OS text-size slider auto-scaling app text without
   pinch) is honored by the shells via -webkit-text-size-adjust on iOS / the
   Android fontScale — tracked in the iOS/Android native passes. */
html { font-size: 106.25%; }

/* Small tablet / large phone landscape (≥600px) — 18px-equivalent. */
@media (min-width: 600px) {
  :root { --app-content-width: 480px; }
  html  { font-size: 112.5%; }
}

/* iPad portrait and up (≥768px) — 19px-equivalent. */
@media (min-width: 768px) {
  :root { --app-content-width: 540px; }
  html  { font-size: 118.75%; }
}

/* ── Typography helpers ───────────────────────────────────────── */
.serif {
  font-family: 'Lora', serif;
}

.serif-i {
  font-family: 'Lora', serif;
  font-style: italic;
  color: var(--accent);
}

.text-soft {
  color: var(--text-secondary);
}

.text-hint {
  color: var(--text-tertiary);
}

.text-accent {
  color: var(--accent);
}

/* ── Shared page elements ─────────────────────────────────────── */
/* Used across settings, people, and form screens for consistent styling */

.page-title {
  font-family: 'DM Sans', system-ui, sans-serif;
  font-size: var(--text-title);
  font-weight: 400;
  color: var(--text-primary);
  margin: 0 0 var(--space-xs);
}

.page-subtitle {
  font-size: var(--text-body-sm);
  color: var(--text-tertiary);
  margin: 0 0 var(--space-lg);
}

.form-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: var(--space-lg) var(--space-md);
}
