/* ─── Theme tokens ────────────────────────────────────────────────────────────
   D36 / 09-design-system: Finch-like — soft pastels, cozy, rounded. Warm and
   unhurried. "An app about money that is deliberately not trying to look like
   a bank."

   TWO SCOPES, deliberately separate:

     APP tokens      what renders inside the phone screen — repainted here
     --chrome-*      the phone bezel and the Admin Tools panel — stay NEUTRAL

   The admin panel is dev tooling, not the product under test. If it shared the
   app's palette it would read as part of the thing being evaluated, and a
   tester's eye would not know where the product stops. It also keeps a real
   red for the error log: "no red" governs app surfaces, not instrumentation.

   ── FOUR THEMES (L21) ───────────────────────────────────────────────────────
   The admin panel offers four, so a tester can compare the D36 repaint against
   the v2 look it replaced. Dark is the default.

     Light          .theme-light          v2's crisp blue-on-white
     Dark           .theme-dark           v2's cool dark          ← DEFAULT
     Natural Light  (no class — :root)    D36 cream + sage
     Natural Dark   .theme-natural-dark   D36 dimmed, warm

   THE CONTRACT: each of the three classes must define ALL 40 colour tokens
   that :root defines below, no more and no fewer. A missing one silently falls
   through to :root's cream and paints one stray warm patch into a cool theme —
   which is exactly the kind of bug that looks deliberate. `scripts/sweep.sh`
   asserts the three sets match, so a token added here must be added to all
   three or the sweep fails.

   Light and Dark reproduce v2 faithfully, INCLUDING its real alarm reds. D36's
   "no red" governs the product design, which is what the Natural pair is; the
   v2 pair exists to be compared against and is not held to it.

   WHAT A THEME MUST NEVER TOUCH: --chrome-*, --bg, --phone. Those style the
   admin panel, the page and the bezel — all of which live OUTSIDE .screen,
   where these classes are applied. An override here cannot reach them (it is
   inert), and the frame is meant to hold still while the app repaints. The
   sweep asserts this too. */

:root {
  /* ── The design-system palette, raw ─────────────────────────────────────── */
  --cream:     #FBF7F0;   /* page background */
  --sage:      #A8C4A2;   /* primary, buddy stage, positive states */
  --sky:       #9BBFD4;   /* secondary, informational */
  --apricot:   #E8B48A;   /* accents, kibble, streak */
  --clay:      #C98B7E;   /* attention — never alarm red */
  --ink:       #3D3A36;   /* text */
  --ink-soft:  #7A736B;   /* secondary text */

  /* ── App surfaces ───────────────────────────────────────────────────────── */
  /* No pure white anywhere: cards are a warm off-white lifted off the cream. */
  --screen:    var(--cream);
  --card:      #FFFDF9;
  --soft:      #F4EEE4;
  --text:      var(--ink);
  --muted:     var(--ink-soft);
  --line:      #E7DFD3;
  --bar:       #DCD2C4;
  --progress-bg: #EFE8DC;
  /* Slider rail edge. --progress-bg is a FILL and sits at 1.02-1.20:1
     against --card in every theme, so a track drawn in it has no
     perceptible edge — which is why the budget sliders read as a thumb
     floating in space. This clears ~2.6:1 and is used as a hairline. */
  --rail:      #A69E93;

  /* Interactive. Sage is the primary, but the raw pastel is too light to carry
     white text — buttons use sage FILL with ink text, and --accent is a
     deepened sage for links and small type where contrast has to hold. */
  --accent:        #557B58;   /* deepened from sage to clear 4.5:1 on card */
  --accent-fill:   var(--sage);
  --accent-fill-text: var(--ink);   /* text ON the fill — see below */
  --accent-soft:   #EDF3EC;
  --accent-border: #C4D8BF;

  /* Positive. Sage again, deepened enough to read as text. */
  --good:          #4B7650;   /* sage, deepened to clear 4.5:1 */
  --good-bg:       #EDF3EC;
  --good-border:   #C4D8BF;
  --good-pill-bg:  #E4EEE2;
  --good-pill-text:#3F6644;

  /* Attention. Clay, not danger colouring — nothing here is an emergency. */
  --warn:          #9B5A4C;   /* clay, deepened to clear 4.5:1 */
  --warn-bg:       #FBF0EC;
  --warn-border:   #EFCFC5;
  --warn-pill-bg:  #F7E6E0;
  --warn-pill-text:#8E5145;
  --warn-pill-strong-bg:   #F2D9D1;
  --warn-pill-strong-text: #7C4438;

  /* There is no alarm red in the app. --danger resolves to clay so any
     inherited v2 styling lands on the right side of D36 rather than shouting. */
  --danger:        var(--warn);
  --danger-bg:     var(--warn-bg);
  --danger-border: var(--warn-border);

  /* Informational — sky, deepened to clear 4.5:1 on --info-bg like --accent and
     --good are. It shipped at #4E7F98 (3.92:1) and the contrast gate added with
     the four themes caught it; the other two deepenings were done by eye. */
  --info:        #456F86;
  --info-bg:     #EDF4F7;
  --info-border: #C3DBE6;

  /* Text on a deliberately dark surface (lesson stage, bezel). Fixed — it must
     not flip with the theme, and it is warm rather than pure white (D36). */
  --on-dark: #FBF7F0;

  /* Text that sits ON a themed fill. Two tokens, because the two fills invert
     in opposite directions and a single fixed value cannot serve both:

       --accent-fill-text   pairs with --accent-fill (primary button)
       --on-accent          pairs with --accent      (chat link, active segment)

     --accent is DARK in the light themes and LIGHT in the dark ones, so the
     cream that reads on it in Natural Light is unreadable on Natural Dark's
     pale sage. Before these existed those rules hardcoded --ink and --on-dark
     and the pairing was implicit, which is how that went unnoticed. */
  --on-accent: #FBF7F0;

  --tier-copper: #B87333;
  --scroll-thumb: rgba(61, 58, 54, .24);

  /* ── Shape, depth, motion (09-design-system) ───────────────────────────── */
  --radius-card:   16px;
  --radius-button: 24px;
  --radius-pill:   999px;
  --shadow-soft:   0 4px 24px rgba(61, 58, 54, .06);
  --ease:          cubic-bezier(.22, .61, .36, 1);   /* ease-out */
  --dur:           240ms;

  /* ── Type ───────────────────────────────────────────────────────────────── */
  /* The spec names Nunito/Quicksand and Inter/Source Sans. Webfonts cannot be
     loaded here — the app runs on file:// with no network at runtime (D02) —
     so these are the closest system stacks. Swap in real files if the fonts
     are ever bundled locally. */
  --font-display: ui-rounded, "SF Pro Rounded", "Avenir Next Rounded", Nunito,
                  Quicksand, system-ui, sans-serif;
  --font-body:    Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI",
                  Roboto, "Helvetica Neue", sans-serif;

  /* ── Chrome: phone bezel + admin panel. NOT the product. ─────────────────── */
  --phone:         #2B2723;   /* warm bezel rather than v2's blue-black */
  --bg:            #EDE8E0;   /* the page behind the phone */
  --chrome-card:   #FFFFFF;
  --chrome-text:   #172033;
  --chrome-muted:  #667085;
  --chrome-line:   #D9DEE8;
  --chrome-accent: #315EFB;
  --chrome-danger: #B42318;   /* a real red — this is instrumentation */

  /* Streak splash — branded full-bleed launch screen. */
  --streak-bg:     #6B5FD1;
  --streak-burst:  #7D72E0;
  --streak-pill:   #5849BF;
  --streak-text:   #FFFFFF;
  --streak-accent: var(--apricot);
  --streak-on:     #FFFFFF;
  --streak-off:    rgba(255, 255, 255, .28);
}

/* ─── Spacing scale ──────────────────────────────────────────────────────── */
:root {
  --space-xs:  4px;
  --space-sm:  8px;
  --space-md: 12px;
  --space-lg: 16px;
  --space-xl: 20px;
}

/* ─── Chrome heights ─────────────────────────────────────────────────────────
   Stated ONCE. v2 duplicated the 78px nav reservation in three places — the
   CSS default, the per-mode override classes, and an inline JS fallback — and
   v3 adds a top bar, which would have doubled that. Everything references
   these; nothing hardcodes a pixel offset. */
:root {
  --topbar-h: 52px;
  --nav-h:    78px;
}

/* ─── Natural Dark ────────────────────────────────────────────────────────────
   The v3 spec specifies no dark mode, but v2 ships one and D37 says carry
   forward what the spec does not mention. So these are warm equivalents —
   the palette dimmed rather than a different, colder theme. */
.theme-natural-dark {
  --cream:     #26231F;
  --screen:    var(--cream);
  --card:      #302C27;
  --soft:      #35302A;
  --ink:       #EFE9E0;
  --ink-soft:  #A79E93;
  --text:      var(--ink);
  --muted:     var(--ink-soft);
  --line:      #3E3830;
  --bar:       #4A4339;
  --progress-bg: #35302A;
  --rail:      #716C64;

  --sage:      #7FA87C;
  --accent:        #9CC298;
  --accent-fill:   #4D6F4B;   /* dark-mode fill, so cream text clears 4.5:1 */
  --accent-fill-text: var(--ink);
  --accent-soft:   #23301F;
  --accent-border: #3C5439;
  /* --accent is a PALE sage here, so text on it has to be dark, not cream. */
  --on-accent:     #26231F;

  --good:          #8DBE89;
  --good-bg:       #1E2C1C;
  --good-border:   #37502F;
  --good-pill-bg:  #1E2C1C;
  --good-pill-text:#8DBE89;

  --clay:      #D89A8C;
  --warn:          #DFA294;
  --warn-bg:       #34211C;
  --warn-border:   #5A382F;
  --warn-pill-bg:  #34211C;
  --warn-pill-text:#DFA294;
  --warn-pill-strong-bg:   #402720;
  --warn-pill-strong-text: #E8B0A2;

  --danger:        var(--warn);
  --danger-bg:     var(--warn-bg);
  --danger-border: var(--warn-border);

  --sky:       #8AAFC4;
  --info:        #9DC3D6;
  --info-bg:     #1D2A31;
  --info-border: #35505C;

  --apricot:   #E0AC82;
  --scroll-thumb: rgba(239, 233, 224, .22);
}

/* ─── Light — v2's palette, restored ──────────────────────────────────────────
   Crisp blue-on-white. This is the look D36 replaced, kept switchable so the
   repaint can be judged against it rather than from memory. Values are v2's
   own; the ten tokens v2 never had (--sage, --sky, --apricot, --clay, --ink*,
   --info*, --on-accent, --accent-fill*) are derived into the same cool
   register — NOT left to inherit, which would leak cream into a blue theme. */
.theme-light {
  --cream:     #F8FAFC;
  --screen:    var(--cream);
  --card:      #FFFFFF;      /* v2 did use pure white — that is the contrast */
  --soft:      #F2F4F7;
  --ink:       #172033;
  --ink-soft:  #667085;
  --text:      var(--ink);
  --muted:     var(--ink-soft);
  --line:      #D9DEE8;
  --bar:       #D0D5DD;
  --progress-bg: #E8EBF0;
  --rail:      #9C9FA6;

  --sage:      #7EA0F0;      /* the "primary pastel" role, in blue */
  --accent:        #315EFB;
  --accent-fill:   #315EFB;  /* saturated, unlike sage — so the text is white */
  --accent-fill-text: #FFFFFF;
  --accent-soft:   #EDF1FF;
  --accent-border: #C7D4FF;
  --on-accent:     #FFFFFF;

  --good:          #087443;
  --good-bg:       #EEFAF4;
  --good-border:   #B7E4CE;
  --good-pill-bg:  #DCFCE7;
  --good-pill-text:#166534;

  --clay:      #E08472;
  --warn:          #A15C07;
  --warn-bg:       #FFF8EC;
  --warn-border:   #F5D78E;
  --warn-pill-bg:  #FEF9C3;
  --warn-pill-text:#854D0E;
  --warn-pill-strong-bg:   #FEF3C7;
  --warn-pill-strong-text: #92400E;

  /* A real red, unlike the Natural pair where --danger resolves to clay. */
  --danger:        #B42318;
  --danger-bg:     #FEF3F2;
  --danger-border: #FECDCA;

  --sky:       #7FB2D9;
  --info:        #175CD3;
  --info-bg:     #EFF4FF;
  --info-border: #B2CCFF;

  --apricot:   #F6B73C;
  --scroll-thumb: rgba(16, 24, 40, .28);
}

/* ─── Dark — v2's dark, restored. THE DEFAULT (L21). ──────────────────────────
   Two deliberate deviations from v2's exact values, both for legibility:
     --accent      lightened #4F76FC → #7DA0FF. v2's blue on its own dark card
                   is ~3.2:1, under the 4.5 floor for the link text it carries.
     --accent-fill deepened  #4F76FC → #3A5BD9, so white on it clears 4.5:1.
   v2 got away with both because it had no contrast gate. This build does. */
.theme-dark {
  --cream:     #1E2128;
  --screen:    var(--cream);
  --card:      #282C35;
  --soft:      #23272F;
  --ink:       #E3E6EF;
  --ink-soft:  #8B95A8;
  --text:      var(--ink);
  --muted:     var(--ink-soft);
  --line:      #343844;
  --bar:       #3D4251;
  --progress-bg: #2A2D35;
  --rail:      #676B77;

  --sage:      #6E8FD6;
  --accent:        #7DA0FF;
  --accent-fill:   #3A5BD9;
  --accent-fill-text: #FFFFFF;
  --accent-soft:   #1A2347;
  --accent-border: #1F3080;
  --on-accent:     #0B1020;   /* --accent is pale here — dark text on it */

  --good:          #2DBD6E;
  --good-bg:       #0D2616;
  --good-border:   #1A5232;
  --good-pill-bg:  #0D2616;
  --good-pill-text:#2DBD6E;

  --clay:      #E8897A;
  --warn:          #F5A623;
  --warn-bg:       #2D1800;
  --warn-border:   #5C3600;
  --warn-pill-bg:  #2D2000;
  --warn-pill-text:#F5A623;
  --warn-pill-strong-bg:   #2D1800;
  --warn-pill-strong-text: #F5A623;

  --danger:        #F04438;
  --danger-bg:     #2D0A08;
  --danger-border: #5C1A17;

  --sky:       #7FA8C9;
  --info:        #84ADFF;
  --info-bg:     #101A33;
  --info-border: #2A3E7A;

  --apricot:   #F5A623;
  --scroll-thumb: rgba(255, 255, 255, .22);
}
