/* ==========================================================================
   Chunk Chunk — brand tokens + primitives
   ==========================================================================

   Drop this file into any Chunk Chunk site and it is on-brand: the palette,
   the type stack, the radii, the shadows and a handful of components, in
   light and dark.

       <link rel="stylesheet" href="brand.css">

   ── This file is a SNAPSHOT, not the source ─────────────────────────────
   The source of truth is ../styles.css. The token block below was copied
   out of it byte for byte, deliberately — the website is a separate deploy
   target from the app and cannot @import across it. The cost of that is
   drift: if you change a colour in styles.css, re-copy it here, then re-run
   the check that the two agree:

       node brand/check.js

   ── Rules that are load-bearing, not preferences ────────────────────────
   · --orange is UI and chart only. It never reaches 4.5:1 as text on any
     surface here, so it is never a text colour.
   · The banknote green is a STATUS colour (success, the hero tile) and is
     never a chart series — against the orange it scores ΔE 5.0 for deutan
     viewers, well under the floor. That is why the third series is rose.
   · --red is reserved for status. It is not available as a brand accent.
   · Every currency figure carries font-variant-numeric: tabular-nums, so
     columns align and digits do not jitter when a value changes.
   See ../CLAUDE.md for the contrast and CVD numbers behind all of this.
   ========================================================================== */

:root {
  /* Brand — straight off the logo. */
  --brand: #3460A0;            /* the tile */
  --brand-cream: #FAF2E8;      /* her fur */
  --brand-ink: #1C2A3D;        /* the outlines */

  --blue: #3460A0;             /* 6.31:1 on card */
  --green: #4E7D3F;            /* deepened banknote green, 4.85:1 */
  --red: #B03A2E;              /* warm red, tuned to the palette, 6.02:1 */
  --orange: #F38234;           /* her clip — UI and chart only, never text */
  --amber: #9A5410;            /* the clip, deepened until it can be TEXT: 5.75:1 on card */

  /* Row washes. An alpha of the status colour itself rather than a second
     literal — the technique .cat-fill and the calendar tint already use. */
  /* NOT an alpha of --amber/--red: those are deepened until they can be TEXT,
     and an alpha of a dark brown over cream is dirt rather than a warning.
     See styles.css for the measurement. */
  --amber-wash: rgba(243, 130, 52, .24);
  --red-wash: rgba(224, 107, 91, .22);
  /* Success. Added 31 August 2026 for the login page's confirmation notice.
     --green is 4.85:1 as text and does NOT have the dark-brown problem
     --amber has, so this one is an alpha of the status colour itself. */
  --green-wash: rgba(78, 125, 63, .16);

  /* Chart series — validated for CVD separation against the card surface.
     The banknote green is deliberately NOT here: against the orange it
     scores ΔE 5.0 (deutan), far under the floor. Green stays a status
     colour. See CLAUDE.md before changing any of these. */
  --series-debt: #3460A0;
  --series-loc: #F38234;
  --series-hloc: #A8437A;

  --bg: #FAF2E8;
  --surface: #FFFFFF;
  --surface-2: #F3EDE3;
  --surface-3: #E8E0D3;

  /* Text and hairlines are alphas of the ink navy, not neutral grey, so
     even the dividers stay warm. */
  --label: #1C2A3D;            /* 13.07:1 on page, 14.50:1 on card */
  --label-2: rgba(28, 42, 61, 0.62);
  --label-3: rgba(28, 42, 61, 0.38);
  --separator: rgba(28, 42, 61, 0.16);

  --chrome-bg: rgba(250, 242, 232, 0.72);

  /* Navy-tinted rather than neutral black: a warm palette goes muddy under
     grey shadow. */
  --shadow: 0 1px 2px rgba(28, 42, 61, .05), 0 8px 24px rgba(28, 42, 61, .08);
  --thumb-shadow: 0 3px 8px rgba(28, 42, 61, .14), 0 1px 1px rgba(28, 42, 61, .05);
  --ring: rgba(52, 96, 160, .32);
  /* Retuned when the mark lost its tile. A blue glow read as deliberate
     behind a blue square; around fur it reads as a bluish smudge. Light mode
     wants a plain warm shadow that just grounds her. */
  --hero-glow: rgba(28, 42, 61, .18);

  --radius: 16px;
  --radius-sm: 10px;
  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  /* How long a card takes to turn over. One token because all three cards
     have to agree: the PLOC, the HLOC and every debt card share one .flip. */
  --turn: .75s;

  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
          "Helvetica Neue", Helvetica, Arial, sans-serif;
}

/* Dark is the logo at night — her cream fur on her own blue, not black.

   OPT-IN, not automatic. Vic asked for a Day/Night toggle on 27 August 2026
   and said twice that he likes the day colours, so Day is what paints when
   nothing has been chosen — including on a device set to dark. Dark arrives
   only as data-theme="dark", written by the toggle and restored by the boot
   script in the page head before the first paint.

   That boot script also sets `colorScheme` on the same element. It has to:
   the NATIVE controls — the due-date picker above all — follow that property
   and not these tokens, and a light table holding a dark calendar widget is
   the exact class of fault this pass began with. */
:root[data-theme="dark"] {
  --blue: #6E9BD8;           /* 5.56:1 on card */
  --green: #7FB069;          /* 6.30:1 */
  --red: #E06B5B;            /* 4.87:1 */
  --orange: #F39A5C;
  /* Pushed toward yellow on purpose: dark --red is a salmon, and an amber
     sitting next to it would converge. 8.52:1 on card. */
  --amber: #F0B34A;
  /* .12 over navy resolved to rgb(50,52,50) — a desaturated olive-grey that
     did not read as a warning at all, just as a slightly lighter row. Raised
     to .30, which lands on rgb(89,78,55) and is unmistakably yellow. Vic asked
     for it on 27 August 2026, after the light-mode wash was fixed.

     Still an alpha of --amber, not a new literal. A brighter #F5C542 was tried
     at the same opacity and is a 6-point difference in the green channel that
     reads slightly GREENER, not more yellow — not worth a hue the palette has
     never validated. Rendered side by side before deciding.

     Both tiers move together, as in light: raising the warning alone makes it
     outshout the failure. */
  --amber-wash: rgba(240, 179, 74, .30);
  --red-wash: rgba(224, 107, 91, .30);
  /* .30 like its neighbours: the same .16 that reads clearly over cream
     disappears over navy, which is the measurement the two washes above
     already record. */
  --green-wash: rgba(127, 176, 105, .30);

  --series-debt: #3C7FCC;
  --series-loc: #CE7E0A;
  --series-hloc: #C9628E;

  --bg: #101A26;
  --surface: #18232F;
  --surface-2: #22303F;
  --surface-3: #2C3B4C;

  --label: #F5F0E8;          /* 15.46:1 on page, 14.02:1 on card */
  --label-2: rgba(245, 240, 232, 0.62);
  --label-3: rgba(245, 240, 232, 0.34);
  --separator: rgba(245, 240, 232, 0.14);

  --chrome-bg: rgba(16, 26, 38, 0.72);
  --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 8px 24px rgba(0, 0, 0, .40);
  --thumb-shadow: 0 3px 8px rgba(0, 0, 0, .45);
  --ring: rgba(110, 155, 216, .38);
  /* Dark keeps a brand-blue lift — a neutral shadow is invisible on navy —
     but at half the old strength, which was tuned to a tile, not to fur. */
  --hero-glow: rgba(52, 96, 160, .28);
}

/* ==========================================================================
   Primitives — copied from ../styles.css, same snapshot rule as above.
   Enough to build a page with: base, buttons, cards, tiles, fields and the
   segmented control. Everything below is expressed in the tokens above, so
   changing a token changes every component.
   ========================================================================== */

* { box-sizing: border-box; }

/* The `hidden` attribute only carries a UA-default `display: none`, which any
   class setting display (a flex or grid component) silently beats. If you
   toggle `hidden` in JS, this rule is load-bearing, not tidiness. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.45;
  color: var(--label);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

/* Every figure is tabular so columns line up and digits don't jitter. */
.num, .tile-value, .debt-total { font-variant-numeric: tabular-nums; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ── type scale ─────────────────────────────────────────────────────── */

.t-display {
  margin: 0 0 4px;
  font-size: 34px; font-weight: 700; letter-spacing: -0.022em; line-height: 1.1;
}
.t-lede { margin: 0; max-width: 58ch; font-size: 15px; color: var(--label-2); }
.t-body { font-size: 15px; line-height: 1.45; }
/* The uppercase 11px section label used on every card and tile. */
.t-eyebrow {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--label-2);
}
.t-caption { font-size: 12px; color: var(--label-2); }

@media (max-width: 900px) {
  .t-display { font-size: 28px; }
}

/* ── buttons ────────────────────────────────────────────────────────── */

.btn {
  font: inherit; font-weight: 600;
  border: 0; border-radius: var(--radius-sm);
  padding: 7px 14px;
  cursor: pointer;
  transition: opacity .2s var(--ease), background .2s var(--ease), transform .1s var(--ease);
}
.btn:active { transform: scale(.97); }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }
.btn:disabled { color: var(--label-3); cursor: default; pointer-events: none; }

.btn-primary { background: var(--blue); color: #fff; }
.btn-primary:hover { opacity: .88; }

.btn-plain {
  background: transparent; color: var(--blue);
  font-size: 14px; padding: 6px 10px;
}
.btn-plain:hover { background: var(--surface-2); }

.btn-small { background: var(--blue); color: #fff; font-size: 13px; padding: 5px 12px; }
.btn-small:hover { opacity: .88; }

/* ── cards ──────────────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--separator);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  min-width: 0;
}
.card-head {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 16px; flex-wrap: wrap;
}
.card-head .card-title { margin-bottom: 0; }
.card-title {
  margin: 0 0 16px;
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--label-2);
}
.card-sub { margin-left: auto; font-size: 12px; color: var(--label-2); }

/* ── KPI tiles ──────────────────────────────────────────────────────── */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 12px;
}
.tile {
  background: var(--surface);
  border: 1px solid var(--separator);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 18px;
}
.tile-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--label-2);
  margin-bottom: 6px;
}
.tile-value {
  font-size: 30px; font-weight: 600; letter-spacing: -0.025em;
  line-height: 1.05;
}
.tile-value.is-muted { color: var(--label-3); }
.tile-hero .tile-value { color: var(--green); }
.tile-note { margin-top: 4px; font-size: 12px; color: var(--label-2); }

/* ── fields ─────────────────────────────────────────────────────────── */

.field {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 9px 0;
  border-bottom: 1px solid var(--separator);
}
.field:last-of-type { border-bottom: 0; }
.field label { font-size: 15px; }

/* ── segmented control ──────────────────────────────────────────────── */

.segmented {
  position: relative;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  background: var(--surface-2);
  border-radius: 9px;
  padding: 2px;
  isolation: isolate;
}
.segmented button {
  position: relative; z-index: 1;
  appearance: none; border: 0; background: none;
  font: inherit; font-size: 12px; font-weight: 500;
  color: var(--label); cursor: pointer;
  padding: 6px 4px; border-radius: 7px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color .2s var(--ease);
}
.segmented button[aria-checked="true"] {
  font-weight: 600;
  background: var(--surface);
  box-shadow: var(--thumb-shadow);
}
:root[data-theme="dark"] .segmented button[aria-checked="true"] { background: var(--surface-3); }
.segmented button:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }

/* ── chrome ─────────────────────────────────────────────────────────── */

.chrome {
  position: sticky; top: 0; z-index: 20;
  background: var(--chrome-bg);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--separator);
}

/* The in-page mark wears mark-*.png (no tile) so it sits IN the cream page.
   Never add border-radius: the tiled icons already have the curve in their
   pixels, and the untiled ones have no tile left to round. */
.brand-mark { object-fit: contain; flex: none; }
.brand-mark-hero {
  width: 72px; height: 72px;
  filter: drop-shadow(0 6px 16px var(--hero-glow));
}
