  :root {
    --bg: #050b0e;
    --panel: #071319;
    --panel-raised: #0c1e26;
    --border: rgba(87, 210, 220, 0.28);
    --border-soft: rgba(87, 210, 220, 0.12);
    --cyan: #5be6ef;
    --cyan-bright: #9df3f8;
    --cyan-dim: #3a8891;
    --ink: #d7f2f4;
    --ink-soft: #7fa3a8;
    /* THEME ENGINE V1.2, Part 1 — APPROVED accessibility correction to the baseline.
       Was #46626a, which measured 3.03:1 on --bg, 2.88:1 on --panel and 2.62:1 on
       --panel-raised: below the practical readability standard everywhere it was used, and the
       single token behind EVERY accessibility finding in the V1 report (muted text, chart axis
       labels, table headers, empty states, Apex hints). The V1 sprint was forbidden from
       touching Mighty Dark; this one is explicitly allowed to fix exactly this.
       #6b8c93 measures 5.47 / 5.19 / 4.72 on those same three surfaces — clear of 4.5:1 on the
       worst of them — while staying visibly fainter than --ink-soft (#7fa3a8, 6.27:1 on raised),
       so the three-tier text hierarchy is preserved rather than flattened. Nothing else in
       Mighty Dark changes. */
    --ink-faint: #6b8c93;
    --green: #55e0a8;
    --red: #ff6f61;
    --gold: #e8b23d;
    --mono: "IBM Plex Mono", ui-monospace, "SF Mono", "Roboto Mono", Consolas, monospace;

    /* ====== V1 VISUAL & UX POLISH SPRINT (Part 30) — COLOUR CHANNEL TOKENS ======
       The brand and status colours above are hex, so any translucent use of them had to be
       re-typed as a raw rgba() triple. The Part 1 re-audit counted 76 such literals. Four of
       them are EXACT re-expressions of a token above and are now written through it, so the
       palette has one definition per colour instead of one plus however many copies:

           --green-rgb  == #55e0a8   --red-rgb    == #ff6f61
           --gold-rgb   == #e8b23d   --border-rgb == the --border/--border-soft base

       The fifth needs explaining, because it is the reason this is a token and not a find-and-
       replace onto --cyan. Forty-one literals read rgba(87, 230, 239, a). --cyan is #5be6ef,
       which is rgb(91, 230, 239). They differ by FOUR in the red channel — near-certainly one
       original typo that was then copied everywhere glows are used. Folding them into --cyan
       would be a real (if tiny) colour change across half the OS, and this sprint's brief is
       explicit that only clear re-expressions should be tokenised and that this is not a
       redesign. So the value is preserved EXACTLY under its own name:

           --cyan-glow-rgb: 87, 230, 239;   (deliberately NOT --cyan — see above)

       That removes the duplication (one place to change) without changing a single rendered
       pixel, and leaves a decision — reconcile the two, or keep a distinct glow hue on purpose
       — as a documented, one-line change for after the V1 freeze. It is in the report backlog. */
    --cyan-glow-rgb: 87, 230, 239;
    --green-rgb: 85, 224, 168;
    --red-rgb: 255, 111, 97;
    --gold-rgb: 232, 178, 61;
    --border-rgb: 87, 210, 220;

    /* --- Lightweight design tokens (added by consistency audit; values match
       the existing dominant usage in this file — no visual change intended) --- */
    --space-xs: 4px;
    --space-sm: 8px;
    --space-md: 12px;
    --space-lg: 20px;
    --space-xl: 32px;

    --radius-sm: 2px;
    --radius-md: 4px;
    --radius-lg: 8px;

    /* ====== THEME ENGINE V1 — SEMANTIC TOKENS ======
       Added, not renamed. The existing palette above stays exactly as it is (Part 4: "use the
       actual existing token names wherever possible"), and these five fill the gaps that were
       previously written as literals and would therefore have survived a theme switch unchanged.
       Their values here are the EXACT values those literals held, so Mighty Dark renders
       pixel-for-pixel as before; only the other three themes give them different values.

       --on-accent    text/icons sitting ON a filled accent surface (the cyan pill, today's
                      calendar cell, an active range button). Dark ink on cyan reads well; on
                      Office's blue fill the correct answer is white. That is a per-theme
                      decision, which is exactly why it is a token now.
       --ink-strong   the brightest text, above --ink.
       --overlay-rgb  the modal scrim base. Kept as a CHANNEL so the two existing scrims keep
                      their own alphas (0.72 and 0.78) and nothing shifts by a hundredth.
       --shadow-rgb   shadow base. Pure black at dark-theme alphas is far too heavy on a light
                      surface, so light themes soften this rather than restating every shadow.
       --muted-fill-rgb  the neutral chip/badge fill base. */
    --on-accent: #04141a;
    --ink-strong: #eafcff;
    --overlay-rgb: 4, 14, 18;
    --shadow-rgb: 0, 0, 0;
    --muted-fill-rgb: 127, 163, 168;
    /* Forward-looking alias. --cyan IS the accent token throughout this file and keeps that name
       (renaming ~600 usages would be the "giant unrelated CSS rewrite" Part 5 rules out), but in
       Office it holds a blue. --accent lets anything written from here on read semantically. */
    --accent: var(--cyan);
    --accent-bright: var(--cyan-bright);
    --accent-dim: var(--cyan-dim);

    --shadow-card: 0 1px 0 rgba(var(--shadow-rgb),0.4);

    --transition-fast: 0.15s ease;
    --transition-smooth: 0.8s cubic-bezier(0.22, 1, 0.36, 1);
  }
  /* ==========================================================================================
     THEME ENGINE V1 — THEME TOKENS
     ==========================================================================================
     ARCHITECTURE: base component CSS + theme tokens. There is exactly ONE set of component
     rules in this file and the themes below re-point the tokens those rules already read. No
     component CSS is duplicated per theme, and no theme changes a single dimension — no font
     size, no padding, no height, no width, no module order (Part 25: a theme is not a density
     mode). Every block below sets colours and shadow softness ONLY.

     MIGHTY DARK is the :root block above, unchanged. It is the baseline and the default, and it
     is deliberately NOT restated here — a second copy is a second thing to drift.

     Adding a future preset is one block of the same token names. Nothing else in the file needs
     to know it exists (Part 30). */

  /* ---------- MIDNIGHT BLUE ---------------------------------------------------------------
     Premium dark technology: deep navy shell, dark blue-grey surfaces, ELECTRIC blue accent,
     cool white text. Deliberately NOT a hue-swapped Mighty Dark — the surfaces sit a full step
     lighter and bluer than Mighty Dark's near-black, which is what gives it the polished
     analytics-tool feel rather than the same OS tinted blue. Cyan survives as a SECONDARY accent
     (--cyan-bright) so the family resemblance is kept without competing with the primary. */
  :root[data-theme="midnight-blue"] {
    --bg: #080e1c;
    --panel: #111a2e;
    --panel-raised: #1a2540;
    --border: rgba(118, 152, 214, 0.30);
    --border-soft: rgba(118, 152, 214, 0.14);
    --cyan: #4d8dff;
    --cyan-bright: #8fc3ff;
    --cyan-dim: #7d97c4;
    --ink: #e8eefb;
    --ink-soft: #a8b9d6;
    --ink-faint: #8296b6;
    --ink-strong: #f6f9ff;
    --green: #46d99b;
    --red: #ff7a6d;
    --gold: #f0bc4f;
    --on-accent: #05101f;
    --cyan-glow-rgb: 77, 141, 255;
    --green-rgb: 70, 217, 155;
    --red-rgb: 255, 122, 109;
    --gold-rgb: 240, 188, 79;
    --border-rgb: 118, 152, 214;
    --muted-fill-rgb: 168, 185, 214;
    --overlay-rgb: 4, 8, 18;
    --shadow-rgb: 2, 6, 16;
    --shadow-card: 0 1px 0 rgba(var(--shadow-rgb),0.45);
    --bg-rgb: 8, 14, 28;
    --panel-rgb: 17, 26, 46;
    --panel-raised-rgb: 26, 37, 64;
    --hairline-rgb: 118, 152, 214;
  }

  /* ---------- NEON VIOLET -------------------------------------------------------------------
     Futuristic AI/cyber, with DISCIPLINE: the surfaces are charcoal with only a faint violet
     cast, and the violet lives in the accent. The interface is not purple — a purple interface
     is what the brief rules out. Magenta appears once, as the secondary highlight, and nowhere
     else. Status colours are untouched in meaning and only nudged for luminance on these
     surfaces (Part 17: accent and status are separate concepts). */
  :root[data-theme="neon-violet"] {
    --bg: #0b0912;
    --panel: #16121f;
    --panel-raised: #211a2e;
    --border: rgba(171, 133, 240, 0.30);
    --border-soft: rgba(171, 133, 240, 0.14);
    --cyan: #a97bff;
    --cyan-bright: #d7b4ff;
    --cyan-dim: #9683b8;
    --ink: #ede8f7;
    --ink-soft: #b3a6c9;
    --ink-faint: #8f83a6;
    --ink-strong: #faf7ff;
    --green: #4fe0a5;
    --red: #ff6f8f;
    --gold: #f2c14e;
    --on-accent: #100a1c;
    --cyan-glow-rgb: 169, 123, 255;
    --green-rgb: 79, 224, 165;
    --red-rgb: 255, 111, 143;
    --gold-rgb: 242, 193, 78;
    --border-rgb: 171, 133, 240;
    --muted-fill-rgb: 179, 166, 201;
    --overlay-rgb: 8, 6, 14;
    --shadow-rgb: 6, 3, 12;
    --shadow-card: 0 1px 0 rgba(var(--shadow-rgb),0.5);
    --bg-rgb: 11, 9, 18;
    --panel-rgb: 22, 18, 31;
    --panel-raised-rgb: 33, 26, 46;
    --hairline-rgb: 171, 133, 240;
  }

  /* ---------- GRAPHITE GREEN ----------------------------------------------------------------
     Technical/terminal-inspired, NOT Matrix cosplay. Surfaces are true neutral graphite with no
     green cast at all — the green appears only as an accent, which is the whole difference
     between "terminal-inspired" and "green text on everything".
     ONE DELIBERATE DECISION worth stating: the accent (#12b886, deep emerald) is kept clearly
     DARKER and more teal than the success status colour (#55e0a8, bright mint) so that "this is
     selected" and "this is good" never read as the same signal. Status green itself is NOT
     recoloured to suit the theme (Part 17); the accent moved instead. */
  :root[data-theme="graphite-green"] {
    /* Lifted from #0a0c0c/#141818 after measuring perceptual distance against Mighty Dark:
       the backgrounds were dE 1.8 apart — effectively the same surface — which left Graphite
       Green's whole identity resting on its accent. It is also simply more faithful to the name:
       graphite is a mid-dark grey, not black. Now dE ~9 from Mighty Dark on both surfaces. */
    --bg: #101413;
    --panel: #1a1f1e;
    --panel-raised: #232928;
    --border: rgba(150, 168, 164, 0.28);
    --border-soft: rgba(150, 168, 164, 0.13);
    --cyan: #12b886;
    --cyan-bright: #4fd6ac;
    --cyan-dim: #7f9a94;
    --ink: #e6ecea;
    --ink-soft: #a4b2af;
    --ink-faint: #7f8f8c;
    --ink-strong: #f5faf8;
    --green: #55e0a8;
    --red: #ff7a6d;
    --gold: #e8b23d;
    --on-accent: #04120d;
    --cyan-glow-rgb: 18, 184, 134;
    --green-rgb: 85, 224, 168;
    --red-rgb: 255, 122, 109;
    --gold-rgb: 232, 178, 61;
    --border-rgb: 150, 168, 164;
    --muted-fill-rgb: 164, 178, 175;
    --overlay-rgb: 5, 7, 7;
    --shadow-rgb: 0, 0, 0;
    --shadow-card: 0 1px 0 rgba(var(--shadow-rgb),0.45);
    --bg-rgb: 16, 20, 19;
    --panel-rgb: 26, 31, 30;
    --panel-raised-rgb: 35, 41, 40;
    --hairline-rgb: 150, 168, 164;
  }

  /* ---------- ROSE QUARTZ -------------------------------------------------------------------
     Premium soft-tech, dark-first. A deep muted plum shell with warmer raised panels and a blush
     accent — warm and elegant rather than pink-everywhere.
     Explicitly avoided (Part 15): hot-pink saturation, pastel low-contrast text, decorative
     gradients, and — the one that matters most — PINK SUCCESS STATES. Green stays green, gold
     stays gold, red stays red; the accent is the only thing that moved. The surfaces carry the
     warmth, which is what keeps it distinct from Neon Violet: violet is a COOL charcoal with a
     saturated violet accent, this is a WARM plum with a desaturated blush one. */
  :root[data-theme="rose-quartz"] {
    /* Warmed and lifted after measuring: the first surfaces sat ΔE 2.9 from Neon Violet's
       background and 4.5 from its panel — near-indistinguishable, which would have made this a
       recolour of Neon Violet rather than its own theme. Neon Violet is a COOL near-black
       charcoal; this is now a warmer, lighter plum, which is also what "warmer raised panels"
       asks for. Distance from Neon Violet after the change: bg 6.4, panel 9.6. */
    --bg: #1b1317;
    --panel: #281c22;
    --panel-raised: #34262d;
    --border: rgba(224, 168, 188, 0.28);
    --border-soft: rgba(224, 168, 188, 0.13);
    --cyan: #e8a0b4;
    --cyan-bright: #f3c3d1;
    --cyan-dim: #a8808f;
    --ink: #f2e9ee;
    --ink-soft: #c0aab4;
    --ink-faint: #9c8792;
    --ink-strong: #fdf7fa;
    --green: #4fd39b;
    --red: #ff7a8a;
    --gold: #e8b45c;
    --on-accent: #1a0f15;
    --cyan-glow-rgb: 232, 160, 180;
    --green-rgb: 79, 211, 155;
    --red-rgb: 255, 122, 138;
    --gold-rgb: 232, 180, 92;
    --border-rgb: 224, 168, 188;
    --muted-fill-rgb: 192, 170, 180;
    --overlay-rgb: 12, 8, 12;
    --shadow-rgb: 8, 4, 8;
    --shadow-card: 0 1px 0 rgba(var(--shadow-rgb),0.45);
    --bg-rgb: 27, 19, 23;
    --panel-rgb: 40, 28, 34;
    --panel-raised-rgb: 52, 38, 45;
    --hairline-rgb: 224, 168, 188;
  }

  /* ---------- OFFICE DARK -------------------------------------------------------------------
     DISCREET WORKPLACE MODE, dark. The previous Office was too white; this is a modern dark
     business productivity suite instead — dark slate shell, charcoal content surfaces, a MUTED
     office blue, and NEUTRAL GREY borders rather than a tinted accent border.
     Two things make it read as enterprise rather than tech-cool, and both are deliberate:
       - the accent is desaturated (#4a90d9, not an electric blue). It is the quietest accent of
         the five by a clear margin.
       - --cyan-glow-rgb is set to the same neutral grey as the border, so every glow in the OS
         degrades to a faint neutral edge before the refinement layer below even removes it.
     Surfaces are also the LIGHTEST of the five darks — enterprise dark mode is charcoal, not
     black, and that difference is most of why it does not read as a cockpit. */
  :root[data-theme="office"] {
    --bg: #1a1d21;
    --panel: #23272c;
    --panel-raised: #2a2f35;
    --border: rgba(158, 168, 179, 0.26);
    --border-soft: rgba(158, 168, 179, 0.13);
    /* #4a90d9 was the first choice and measured 4.04:1 against --panel-raised — under the bar.
       #5b9ce0 clears it at 4.68 while remaining, by measurement, the QUIETEST accent of the five
       (5.20:1 on its own panel, against 12.55 for Mighty Dark's cyan and 5.4-7.0 for the tech
       accents). Muted is a design goal here; unreadable is not. */
    --cyan: #5b9ce0;
    --cyan-bright: #8cbdec;
    --cyan-dim: #8c9aa8;
    --ink: #e9ebee;
    --ink-soft: #b4bbc3;
    --ink-faint: #949ca5;
    --ink-strong: #f7f8fa;
    --green: #4cc38a;
    --red: #e5736a;
    --gold: #d9a441;
    --on-accent: #0b1420;
    --cyan-glow-rgb: 158, 168, 179;
    --green-rgb: 76, 195, 138;
    --red-rgb: 229, 115, 106;
    --gold-rgb: 217, 164, 65;
    --border-rgb: 158, 168, 179;
    --muted-fill-rgb: 180, 187, 195;
    --overlay-rgb: 10, 12, 14;
    --shadow-rgb: 0, 0, 0;
    --shadow-card: 0 1px 0 rgba(var(--shadow-rgb),0.35);
    --bg-rgb: 26, 29, 33;
    --panel-rgb: 35, 39, 44;
    --panel-raised-rgb: 42, 47, 53;
    --hairline-rgb: 158, 168, 179;
  }

  /* THEME ENGINE V1.2 — placeholders had NO rule at all and fell back to the browser default,
     which is the input's own colour at roughly 54% opacity. The modal audit measured that at
     2.93:1 in Office Dark: exactly the "invisible placeholder" failure the theme brief names.
     Routing them through --ink-faint gives every theme a placeholder that is deliberately faint
     AND measured, instead of accidentally faint and unmeasured. */
  input::placeholder, textarea::placeholder { color: var(--ink-faint); opacity: 1; }

  * { box-sizing: border-box; }
  body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--mono);
    background-image:
      linear-gradient(rgba(var(--border-rgb), 0.05) 1px, transparent 1px),
      linear-gradient(90deg, rgba(var(--border-rgb), 0.05) 1px, transparent 1px);
    background-size: 28px 28px;
  }
  .wrap { max-width: 1180px; margin: 0 auto; padding: 22px 20px 60px; }
  /* ---- Header ---- */
  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-bottom: 1px solid var(--border);
    padding-bottom: 16px;
    margin-bottom: 22px;
    flex-wrap: wrap;
    gap: 14px;
  }
  .brand { display: flex; align-items: center; gap: 14px; }
  .brand-mark {
    width: 30px; height: 30px;
    border: 2px solid var(--cyan);
    transform: rotate(45deg);
    flex-shrink: 0;
    box-shadow: 0 0 10px rgba(var(--cyan-glow-rgb), 0.35);
  }
  .brand-title {
    font-size: 20px; letter-spacing: 0.12em; color: var(--cyan-bright);
    text-shadow: 0 0 12px rgba(var(--cyan-glow-rgb), 0.45);
  }
  .brand-greeting-line { font-size: 10px; letter-spacing: 0.16em; color: var(--cyan-dim); text-transform: uppercase; margin-bottom: 3px; }
  .header-stats { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; }
  select {
    background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink);
    padding: 7px 8px; border-radius: 2px; font-size: 12.5px; font-family: var(--mono);
  }
  select:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  input[type=text], input[type=number], input[type=date], input[type=time], textarea {
    background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink);
    border-radius: 2px; padding: 6px 8px; font-family: var(--mono); font-size: 12px; color-scheme: dark;
  }
  input[type=text]:focus-visible, input[type=number]:focus-visible, input[type=date]:focus-visible, input[type=time]:focus-visible, textarea:focus-visible {
    outline: 2px solid var(--cyan); outline-offset: 1px;
  }
  /* Global fallback focus ring for interactive elements that previously had no
     explicit :focus-visible rule (buttons, links, and elements acting as
     buttons via role="button") — added by consistency audit, matches the
     outline treatment already used everywhere else in this file. */
  button:focus-visible, a:focus-visible, [role="button"]:focus-visible, input[type=checkbox]:focus-visible {
    outline: 2px solid var(--cyan); outline-offset: 2px;
  }
  .stat-label { font-size: 10px; letter-spacing: 0.18em; color: var(--ink-faint); text-transform: uppercase; }
  .stat-value { font-size: 15px; color: var(--ink); margin-top: 2px; letter-spacing: 0.04em; }
  .icon-btn {
    background: var(--panel-raised);
    border: 1px solid var(--border);
    color: var(--cyan);
    width: 34px; height: 34px;
    border-radius: 3px;
    font-size: 15px;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
  }
  .icon-btn:hover { border-color: var(--cyan); box-shadow: 0 0 10px rgba(var(--cyan-glow-rgb), 0.3); }
  .icon-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
  .icon-btn:disabled { opacity: 0.5; cursor: default; }
  .spin {
    width: 12px; height: 12px;
    border: 2px solid var(--ink-faint);
    border-top-color: var(--cyan);
    border-radius: 50%;
    display: inline-block;
    animation: spin 0.8s linear infinite;
  }
  @media (prefers-reduced-motion: reduce) { .spin { animation: none; } }
  @keyframes spin { to { transform: rotate(360deg); } }
  /* ---- Main section tabs (Home / Credit Cards) ---- */
  .main-tab-row { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
  .main-tab-btn {
    background: var(--panel); border: 1px solid var(--border-soft); color: var(--ink-soft);
    font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase;
    padding: 10px 20px; cursor: pointer; position: relative;
  }
  .main-tab-btn::before, .main-tab-btn::after { content: ""; position: absolute; width: 8px; height: 8px; pointer-events: none; }
  .main-tab-btn::before { top: -1px; left: -1px; border-top: 2px solid transparent; border-left: 2px solid transparent; }
  .main-tab-btn::after { bottom: -1px; right: -1px; border-bottom: 2px solid transparent; border-right: 2px solid transparent; }
  .main-tab-btn.active { color: var(--cyan-bright); border-color: var(--cyan); text-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.4); }
  .main-tab-btn.active::before { border-color: var(--cyan); }
  .main-tab-btn.active::after { border-color: var(--cyan); }
  .main-tab-btn:hover { color: var(--cyan-bright); }
  .tab-panel { display: none; }
  .tab-panel.active { display: block; }
  /* ---- Grid layout ---- */
  .grid {
    display: grid;
    grid-template-columns: 320px minmax(280px, 1fr) 320px;
    /* V1.5: the Weather panel is gone (no provider exists), so its named area is gone with it —
       a named area with no item left behind reserves an empty track and reintroduces the dead
       space this column already had too much of. "." is an intentionally empty cell. */
    grid-template-areas:
      "bday core port"
      ".    core sched";
    gap: 18px;
    align-items: start;
  }
  /* Tablet: an intermediate 2-column arrangement, not a straight collapse
     to the mobile single column. "core" (the greeting/status column) stays
     full-width since it's the tallest, most content-variable column; the two
     side panels pair up so the tablet still shows two things side by side. */
  @media (min-width: 641px) and (max-width: 980px) {
    .grid {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
      grid-template-areas: "core core" ". port" "sched sched" "bday bday";
    }
  }
  @media (max-width: 640px) {
    .grid {
      /* minmax(0, 1fr), not bare 1fr: bare 1fr implies a min of "auto",
         which lets any oversized descendant (e.g. an unconstrained
         text input) force this track — and therefore the whole page —
         wider than the viewport. 0 removes that automatic minimum. */
      grid-template-columns: minmax(0, 1fr);
      grid-template-areas: "core" "port" "sched" "bday";
    }
  }
  .area-port { grid-area: port; }
  .area-sched { grid-area: sched; }
  .area-bday { grid-area: bday; }
  .ov-core-col { grid-area: core; display: flex; flex-direction: column; gap: 18px; min-width: 0; }
  /* ---- Panel shell with bracket corners ---- */
  .panel {
    position: relative;
    background: var(--panel);
    border: 1px solid var(--border-soft);
    padding: 16px 18px 18px;
  }
  .panel::before, .panel::after {
    content: ""; position: absolute; width: 12px; height: 12px; pointer-events: none;
  }
  .panel::before { top: -1px; left: -1px; border-top: 2px solid var(--cyan); border-left: 2px solid var(--cyan); }
  .panel::after { bottom: -1px; right: -1px; border-bottom: 2px solid var(--cyan); border-right: 2px solid var(--cyan); }
  .module-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 14px; gap: 10px; }
  .module-tag { font-size: 9px; letter-spacing: 0.2em; color: var(--cyan-dim); text-transform: uppercase; }
  .module-title { font-size: 12.5px; letter-spacing: 0.08em; color: var(--ink); text-transform: uppercase; margin-top: 3px; cursor: default; }
  .module-title.clickable { cursor: pointer; }
  .module-title.clickable:hover { color: var(--cyan-bright); }
  .module-code { font-size: 9px; color: var(--ink-faint); letter-spacing: 0.1em; text-align: right; margin-bottom: 6px; }
  .mini-refresh {
    background: none; border: 1px solid var(--border); color: var(--cyan-dim);
    width: 22px; height: 22px; border-radius: 3px; font-size: 12px;
    display: flex; align-items: center; justify-content: center; cursor: pointer; margin-left: auto;
  }
  .mini-refresh:hover { color: var(--cyan); border-color: var(--cyan); }
  .mini-refresh:disabled { opacity: 0.5; cursor: default; }
  .mini-btn-row { display: flex; gap: 6px; justify-content: flex-end; margin-top: 4px; }
  .mini-btn-row .mini-refresh { margin-left: 0; }
  .empty-hint { color: var(--ink-soft); font-size: 12.5px; line-height: 1.6; padding: 8px 0; }
  .error-text { color: var(--red); font-size: 11.5px; margin-top: 8px; }
  .inline-form { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
  .inline-form input, .add-row input {
    background: var(--panel-raised);
    border: 1px solid var(--border);
    color: var(--ink);
    padding: 7px 10px;
    border-radius: 2px;
    font-size: 12.5px;
    font-family: var(--mono);
  }
  .inline-form input:focus-visible, .add-row input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  .btn {
    background: var(--panel-raised); border: 1px solid var(--border); color: var(--cyan);
    padding: 7px 12px; border-radius: 2px; font-size: 12px; letter-spacing: 0.04em;
    font-family: var(--mono); cursor: pointer;
  }
  .btn:hover { border-color: var(--cyan); }
  /* V1 VISUAL & UX POLISH SPRINT (Part 31): a .btn that MOVES you somewhere rather than creating
     or changing something. Same size, same shape, same hit target — only the emphasis drops, so
     a screen's create action stays the one thing that looks like the create action. */
  .btn-nav { color: var(--ink-soft); border-color: var(--border-soft); background: transparent; }
  .btn-nav:hover { color: var(--cyan); border-color: var(--border); }

  /* ============ V1 VISUAL & UX POLISH SPRINT (Part 27) — ACTION LANGUAGE RULES ============
     The re-audit collected every create-style button label in the OS. They were close to
     consistent already; what was missing was a stated rule, so each new sprint had to guess.
     The rule the existing labels mostly follow, now written down:

       "Add X"   -> create a record you DESCRIBE.       + Add Card, + Add Person, + Add Hotel
       "Log X"   -> record something that HAPPENED at
                    a point in time.                     + Log Activity, + Log Study
       "New X"   -> create a CONTAINER other records
                    attach to.                           + New Trip, + New Template

       Prefix with "+" when the button is a standalone action that opens a modal or starts a
       create flow. Do NOT prefix when the button is the submit control of an inline form that
       is already on screen — there the fields say what is being added, and the label is just
       "Add". Twenty-two buttons already followed this; two ("Add Trip" in Snowboarding, "Add
       Cuisine" in Cooking) sat mid-form spelling out a noun their own input placeholders had
       already given, and were shortened to match.

     This is a naming rule, not a component: it lives here as the place a reader will look. */
  .muted-link { background: none; border: none; color: var(--cyan-dim); font-size: 11px; text-decoration: underline; padding: 0; cursor: pointer; font-family: var(--mono); }
  .muted-link:hover { color: var(--cyan); }
  /* V1 VISUAL & UX POLISH SPRINT (Part 22): one look for destructive controls, wherever they are.
     The Part 1 re-audit found "Clear Demo Data" rendered as an ordinary cyan .muted-link in six
     tabs — visually indistinguishable from "Edit", "Open Schedule →" or "mark want-to-visit".
     Deliberately NOT a filled red button: these are secondary, rarely-wanted actions and giving
     them a loud treatment would make every tab end on an alarm. Red text on the same quiet link
     shape is enough to say "this one removes things" without competing with the page.
     .danger-btn below is the loud treatment those links deliberately refuse: a link at the quiet
     end of a tab is a secondary action, but "Reset everything" inside a modal the user opened on
     purpose IS the action, and it should look like what it does. */
  .danger-link { color: var(--red); }
  .danger-link:hover { color: var(--red); opacity: 0.8; }
  /* V1.1 (Parts 17-20): Data Management. These four rules are the ONLY new component CSS the
     feature needs — the modal itself is the existing .fit-modal shell, and the controls are the
     existing .btn / .input / .inline-form. Every colour is a token, so all six themes are covered
     by construction rather than by six hand-written overrides.
     .danger-btn is the loud treatment .danger-link deliberately refuses (see the note above): a
     link at the quiet end of a tab is a secondary action, but "Reset everything" inside a modal
     the user deliberately opened IS the action, and it should look like what it does. */
     The label is var(--bg), NOT white. Measured across all six palettes: white on these reds
     scores 2.50-3.00:1, which fails WCAG AA for any text size — every one of these themes builds
     its --red as a LIGHT accent for a dark ground, so the readable pairing is the dark ground on
     the red, which scores 5.63-7.58:1. Caught by test_habits_ia.js's six-theme sweep; the
     original `color: #fff` looked right in the one theme it was written in. */
  .danger-btn { background: var(--red); border-color: var(--red); color: var(--bg); }
  .danger-btn:hover:not(:disabled) { opacity: 0.85; }
  .danger-btn:disabled { opacity: 0.4; cursor: not-allowed; }
  .dm-note { color: var(--ink-soft); font-size: 12px; line-height: 1.5; margin: 0 0 10px; }
  .dm-section { border-top: 1px solid var(--border-soft); padding-top: 14px; margin-top: 14px; }
  .dm-section:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }
  .dm-section-title { font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink); margin-bottom: 8px; }
  .dm-section--danger .dm-section-title { color: var(--red); }
  .dm-result { color: var(--ink-soft); font-size: 12px; margin-top: 8px; min-height: 16px; }
  .dm-domain-row { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; padding: 3px 0; font-size: 12px; color: var(--ink-soft); min-width: 0; }
  .dm-domain-row > span:first-child { overflow-wrap: anywhere; }
  .dm-domain-row > span:last-child { color: var(--ink); white-space: nowrap; }
  /* No display property here on purpose — syncDemoDataLinks() clears the inline `display:none`
     back to '' , and these ids sit on both flex rows and bare buttons, which need different
     defaults. Setting one here would force the wrong box type on half of them. */
  .demo-data-row { margin-top: 18px; }

  /* ================= V1 VISUAL & UX POLISH SPRINT (Part 28) — TOUCH TARGET SYSTEM =============
     The Part 1 re-audit measured every visible button in every tab at 390x844. The primary
     actions were fine; the everyday secondary controls were not — .remove-x at 20x16 (96 of
     them), .mini-refresh at 22x22 (56), .reorder-btn at 14x12, .mini-cal-nav at 20x20, and the
     nav pills at 31px tall. Those are the controls people actually poke at all day.

     Fitness Activity V2 fixed its own buttons with an #mainTabFitness-scoped rule and left a
     comment saying app-wide normalisation belonged to the Visual Polish sprint. This is that
     rule, promoted to the shared layer. Two tokens so the numbers stop being scattered magic
     values, and every raise is min-height/min-width plus centering — the GLYPHS do not grow, so
     nothing gets visually louder and no layout is redesigned. Anything already large is
     untouched (min-* cannot shrink a control).

     40px on pointer devices, 44px below 640px where the finger is the pointer. ========== */
  :root { --tap: 40px; --tap-touch: 44px; }

  /* Every .btn gets a pointer-comfortable floor; the primary header action gets the full 40px. */
  .btn { min-height: 32px; }
  /* Primary action in a page header — the single most-used control on each tab. */
  .fin-header .btn { min-height: var(--tap); padding-top: 9px; padding-bottom: 9px; }
  /* Small icon buttons: "+", "↻", "✎", "✕" in module heads and mini rows. Width AND height,
     because a 22px square fails on both axes. */
  .mini-refresh { min-width: var(--tap); min-height: var(--tap);
    display: inline-flex; align-items: center; justify-content: center; }
  /* Row-level delete "✕". Kept narrower than tall on desktop so list rows don't gain width, but
     never below 32px, and full 44px on touch. */
  .remove-x { min-width: 32px; min-height: var(--tap);
    display: inline-flex; align-items: center; justify-content: center; }
  /* Month/period steppers on the calendars. */
  .mini-cal-nav { min-width: 32px; min-height: 32px;
    display: inline-flex; align-items: center; justify-content: center; }
  /* Subtab pills — measured 31px tall in Home, Schedule, Fitness, Finance, Learning, Travel and
     Life. One rule for all seven, since they are the same control wearing four class names. */
  .home-nav-btn, .life-nav-btn, .trav-nav-btn { min-height: 36px; }
  /* Period/range toggles ("Today | Week | Month | Year", "2026 | This Month | ..."). Segmented
     controls: they sit in a tight row, so they get a smaller floor than standalone buttons —
     raising them to 44px on desktop would turn a quiet filter strip into a second toolbar.
     Six class names, one control: found by sweeping the rendered UI rather than by reading the
     stylesheet, which is the only way these turn up. .ib-cat-btn was 24px, .ins-tf-btn 27px. */
  .fin-range-btn, .pv-btn, .ib-cat-btn, .ins-tf-btn, .tab-btn { min-height: 32px; }
  /* ACTION buttons that happen to be small — not filters. These create or open something, so
     they get the full standalone treatment. .trip-quick-btn ("✈️ Flight", "🏨 Hotel",
     "📅 Itinerary" on every trip card) measured 21px tall, the shortest action control left in
     the OS after the first pass; .cc-quick-btn is the Command Center's Quick Actions row, which
     is the fastest path to logging anything and was sitting at 36px. */
  .trip-quick-btn { min-height: var(--tap); }
  .cc-quick-btn { min-height: var(--tap); }
  /* The other row-level delete glyph. Same control as .remove-x under a second class name — the
     duplication itself is logged in the report; the sizes at least now agree. */
  .del-btn { min-width: 32px; min-height: var(--tap);
    display: inline-flex; align-items: center; justify-content: center; }
  /* Text-styled controls ("Clear Demo Data", "Edit", "remove", "Open Schedule →") measured 13px
     tall — they LOOK like prose but behave like buttons. The underline and colour stay exactly as
     they were; only the box around the text grows, so nothing about the visual language changes. */
  .muted-link { min-height: 32px; display: inline-flex; align-items: center; }
  @media (max-width: 640px) {
    .fin-header .btn { min-height: var(--tap-touch); width: 100%; }
    .btn { min-height: var(--tap-touch); }
    .mini-refresh { min-width: var(--tap-touch); min-height: var(--tap-touch); }
    .remove-x { min-width: var(--tap-touch); min-height: var(--tap-touch); }
    .del-btn { min-width: var(--tap-touch); min-height: var(--tap-touch); }

    /* --- Row-embedded control clusters: height yes, width no. ---
       Found by measuring, after the rule above was written. A data row like a Cash Flow entry
       carries FOUR inline controls (▲ ▼ ✎ ✕). Demanding 44px of WIDTH from each asks for 176px
       of controls plus the entry's name and amount on a 390px screen, so the row wrapped onto
       three and four lines — Cash Flow went from 1,784px to 3,343px of scroll, and rows that had
       been 30px tall became 223px. That is a worse experience than the small targets it fixed.

       The insight is that these two situations need different rules. A control standing ALONE
       (the "+" in a module head) is constrained in both axes and needs 44px in both. A control
       inside a horizontal cluster inherits its height from the row, so the only scarce dimension
       is width: 32x44 is a comfortable target and four of them fit on one line with room to
       spare. Height is unchanged at 44px, so nothing gets harder to hit vertically. */
    .acct-row button, .category-row button, .category-row-sub button, .rank-row button,
    .ib-detail-row button, .cs-rotating-row button, .chip button, .habit-row button,
    .hm-row button, .task-row button, li button {
      min-width: 32px;
    }
    /* Even at 32px wide, a Cash Flow row asks a 390px screen for a name, a category, an amount
       and four controls on ONE line. The controls hold their size, so the text spans absorbed
       all the squeeze and wrapped a character at a time — "Transportation" became a 223px row
       while "Dining" stayed 57px, so a tidy list turned into a ragged one.
       Letting the row wrap and giving the NAME its own full-width line fixes the cause rather
       than the symptom: every row is now two predictable lines (name, then category/amount/
       controls) at a consistent height, whatever the name's length. Above 640px nothing changes
       — the single-line row fits comfortably there and is left exactly as it was. */
    .acct-row { flex-wrap: wrap; }
    .acct-row > .acct-name { flex: 1 1 100%; min-width: 0; }
    .mini-cal-nav { min-width: var(--tap-touch); min-height: var(--tap-touch); }
    .home-nav-btn, .life-nav-btn, .trav-nav-btn { min-height: var(--tap-touch); }
    .fin-range-btn, .pv-btn, .ib-cat-btn, .ins-tf-btn, .tab-btn { min-height: 36px; }
    .trip-quick-btn, .cc-quick-btn { min-height: var(--tap-touch); }
    .muted-link { min-height: var(--tap-touch); }
  }
  /* Module visibility rows in the settings menu — a .device-menu-action with a state marker, so
     the menu keeps one control style rather than gaining a second. */
  .module-pref-row { display: flex; align-items: center; gap: 8px; }
  .module-pref-row .fr-module-check { color: var(--border); }
  .module-pref-row.on .fr-module-check { color: var(--accent); }
  /* ---- First run (V1.4, Parts 7-15) ---- */
  /* Sized for the smallest supported screen first: the card is a column that never exceeds the
     viewport, and every control is full-width at 44px so nothing here needs a second layout on
     mobile. The scrim is opaque enough to hide the dashboard behind it — a new user reading
     "Welcome" should not also be reading a stranger's net worth through the glass. */
  /* Above the Apex launcher (400) and the ⚙ toolbar (2000), below nothing: first run is modal, so
     a user who has not chosen anything yet cannot open a conversation about data they do not have,
     or a settings menu describing modules they have not picked. Below .fit-modal-overlay's 500 was
     not enough — measured with the Apex bubble sitting on top of the welcome card. */
  .fr-overlay { position: fixed; inset: 0; z-index: 2100; background: var(--bg);
    display: flex; align-items: center; justify-content: center; padding: 20px; overflow-y: auto; }
  .fr-card { width: 100%; max-width: 520px; background: var(--panel); border: 1px solid var(--border);
    border-radius: 6px; padding: 26px 24px 22px; box-shadow: 0 18px 60px rgba(0,0,0,0.45); }
  .fr-dots { display: flex; gap: 6px; justify-content: center; margin-bottom: 20px; }
  .fr-dot { width: 22px; height: 3px; border-radius: 2px; background: var(--border); }
  .fr-dot.active { background: var(--accent); }
  .fr-mark { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.22em; color: var(--ink-soft);
    text-transform: uppercase; margin-bottom: 10px; }
  .fr-title { font-size: 21px; line-height: 1.25; color: var(--ink); margin: 0 0 10px; font-weight: 600; }
  .fr-lead { font-size: 13.5px; line-height: 1.55; color: var(--ink); margin: 0 0 12px; }
  .fr-note { font-size: 11.5px; line-height: 1.5; color: var(--ink-soft); margin: 10px 0 0; }
  .fr-input { width: 100%; min-height: var(--tap-touch); margin-top: 4px; }
  .fr-actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 20px; flex-wrap: wrap; }
  .fr-actions--stack { flex-direction: column; align-items: stretch; gap: 10px; }
  .fr-primary { min-height: var(--tap-touch); padding: 0 22px; }
  .fr-secondary { min-height: var(--tap-touch); }
  .fr-back { min-height: var(--tap-touch); margin-right: auto; }
  .fr-modules { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; margin-top: 14px; }
  @media (min-width: 480px) { .fr-modules { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  /* The whole row is the control, so the target is the row (>=44px), not a 16px checkbox. */
  .fr-module { display: flex; align-items: center; gap: 10px; min-height: var(--tap-touch);
    padding: 8px 12px; border: 1px solid var(--border); border-radius: 4px; background: var(--panel-raised);
    color: var(--ink-soft); font-size: 12.5px; text-align: left; cursor: pointer; width: 100%; }
  .fr-module.on { border-color: var(--accent); color: var(--ink); }
  .fr-module-check { font-family: var(--mono); font-size: 12px; color: var(--border); flex: 0 0 auto; }
  .fr-module.on .fr-module-check { color: var(--accent); }
  .fr-module-name { flex: 1; min-width: 0; }
  .fr-module-desc { display: block; font-size: 10.5px; color: var(--ink-faint); margin-top: 1px; }
  /* ---- Gauge ---- */
  .gauge-wrap { text-align: center; }
  .gauge-readout { font-size: 30px; font-weight: 600; color: var(--ink); text-shadow: 0 0 10px rgba(var(--cyan-glow-rgb), 0.25); }
  .gauge-sub { font-size: 11.5px; color: var(--ink-soft); margin-top: 2px; }
  .gauge-tickrow { display: flex; justify-content: space-between; font-size: 9.5px; color: var(--ink-faint); margin-top: -4px; padding: 0 4px; }
  .icon-row { display: flex; justify-content: center; margin-bottom: -8px; }
  /* ---- City select row ---- */
  /* ---- Week strip (compact, narrow panel) ---- */
  .week-list { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border-soft); }
  .week-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; font-size: 12px; }
  .week-row.today { color: var(--cyan-bright); }
  .week-day { width: 34px; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.03em; flex-shrink: 0; }
  .week-row.today .week-day { color: var(--cyan-bright); }
  .week-temps { margin-left: auto; font-family: var(--mono); }
  .week-hi { color: var(--ink); }
  .week-lo { color: var(--ink-faint); }
  /* ---- Shared chips, manager rows and remove controls (first built for the retired Portfolio
     panel; the Portfolio-only balance/change rules were removed in V4.2) ---- */
  .chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; justify-content: center; }
  .chip { background: var(--panel-raised); border: 1px solid var(--border); border-radius: 2px; padding: 4px 8px; font-size: 11px; display: flex; gap: 5px; align-items: center; }
  .holdings-mgr { margin-top: 12px; border-top: 1px solid var(--border-soft); padding-top: 10px; }
  .remove-x { background: none; border: none; color: var(--ink-faint); font-size: 14px; padding: 0 4px; cursor: pointer; }
  .remove-x:hover { color: var(--red); }
  /* ---- Notepad (V1.1 multi-note support) ---- */
  /* V1.1 small fix: the shared .del-btn pattern is opacity:0 until :hover, which made each note's
     delete control effectively undiscoverable/unusable on touch devices (no hover state) and easy
     to miss even with a mouse in this compact module — "clear delete action" per spec. Scoped to
     the Notepad list only; every other .del-btn (tasks, events) keeps its existing
     hover-reveal behavior unchanged. */
  /* ---- Journal (V1.2 Sprint 4, Part B) ----
     Deliberately its OWN visual identity, not a copy of Notepad's compact quick-note look:
     Notepad = quick notes (small textarea, flat recency list). Journal = reflective, longer-form,
     date-organized writing. Every class below is Journal-only.
     V1.5: Journal is a top-level destination (#mainTabJournal), not a Life & Interests sub-panel.
     It uses the tab's own width like every other destination; the reading measure is protected
     where it actually belongs — on the prose itself (.journal-page-inner) — rather than by
     capping the whole column. */
  .journal-header { display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 14px; margin-bottom: 18px; }
  .journal-header-copy .journal-title { font-size: 17px; letter-spacing: 0.06em; color: var(--cyan-bright); text-transform: uppercase; text-shadow: 0 0 10px rgba(var(--cyan-glow-rgb), 0.3); }
  .journal-header-copy .journal-tagline { font-size: 12.5px; color: var(--ink-soft); margin-top: 6px; letter-spacing: 0.02em; line-height: 1.6; max-width: 520px; }
  .journal-group-label { font-size: 10px; letter-spacing: 0.16em; color: var(--cyan-dim); text-transform: uppercase; margin: 20px 0 8px; }
  .journal-group-label:first-child { margin-top: 0; }
  .journal-entry-list { display: flex; flex-direction: column; gap: 8px; }
  .journal-entry-card {
    display: flex; flex-direction: column; gap: 5px; padding: 13px 40px 13px 15px; border: 1px solid var(--border);
    border-radius: 3px; background: var(--panel-raised); cursor: pointer; position: relative;
    transition: border-color 0.15s ease;
  }
  .journal-entry-card:hover, .journal-entry-card:focus-visible { border-color: var(--cyan); }
  .journal-entry-card-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
  .journal-entry-title { font-size: 13.5px; font-weight: 600; color: var(--ink); word-break: break-word; }
  .journal-entry-date { font-size: 10px; color: var(--ink-faint); white-space: nowrap; flex-shrink: 0; }
  .journal-entry-preview { font-size: 12px; color: var(--ink-soft); line-height: 1.55; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .journal-entry-card .del-btn { position: absolute; top: 12px; right: 12px; opacity: 0.55; }
  .journal-entry-card .del-btn:hover, .journal-entry-card .del-btn:focus-visible { opacity: 1; color: var(--red); }
  /* ================= JOURNAL V1.3 (Parts 14-18) =================
     THE BOOK METAPHOR IS IN THE STRUCTURE, NOT THE TEXTURE. No paper, no stitching, no fake
     leather — every colour below is an existing token and every control is an existing component.
     What makes it read as a book is the shape: a bound index you turn to a date in, beside a page
     that leads with the day it belongs to. */
  .journal-book { display: grid; grid-template-columns: minmax(210px, 260px) minmax(0, 1fr); gap: 26px; align-items: start; }
  /* The measure lives on the TEXT, not the container: the page grows with the window while the
     prose stays at a readable line length. */
  .journal-page-inner { max-width: 820px; min-width: 0; }
  .journal-index { border-right: 1px solid var(--border-soft); padding-right: 18px; min-width: 0;
    max-height: 720px; overflow-y: auto; }
  .journal-search-row { margin-bottom: 10px; }
  .journal-index-year { margin-bottom: 10px; }
  .journal-index-year-label { font-size: 10px; letter-spacing: 0.16em; color: var(--cyan-dim);
    text-transform: uppercase; margin-bottom: 4px; }
  .journal-index-month-btn { width: 100%; display: flex; justify-content: space-between; align-items: center;
    gap: 8px; background: none; border: 0; color: var(--ink-soft); font: inherit; font-size: 12px;
    padding: 7px 4px; cursor: pointer; text-align: left; border-radius: 4px; min-height: var(--tap); }
  .journal-index-month-btn:hover { background: var(--panel-raised); color: var(--ink); }
  .journal-index-month-btn.open { color: var(--ink); }
  .journal-index-count { font-size: 10px; color: var(--ink-faint); flex: 0 0 auto; }
  .journal-index-entries { display: flex; flex-direction: column; gap: 1px; margin: 2px 0 6px 4px;
    border-left: 1px solid var(--border-soft); padding-left: 8px; }
  .journal-index-entry { display: flex; align-items: baseline; gap: 8px; background: none; border: 0;
    color: var(--ink-soft); font: inherit; font-size: 12px; padding: 7px 6px; cursor: pointer;
    text-align: left; border-radius: 4px; min-width: 0; min-height: var(--tap); }
  .journal-index-entry:hover { background: var(--panel-raised); color: var(--ink); }
  .journal-index-entry.active { background: var(--panel-raised); color: var(--cyan-bright); }
  .journal-index-day { flex: 0 0 auto; font-size: 11px; color: var(--ink-faint); min-width: 16px; }
  .journal-index-entry.active .journal-index-day { color: var(--cyan-bright); }
  .journal-index-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .journal-index-fav { flex: 0 0 auto; color: var(--gold); font-size: 11px; }
  .journal-page { min-width: 0; }
  .journal-page-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
    flex-wrap: wrap; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid var(--border-soft); }
  /* Part 18: the DATE is the heading. On a journal page it is not metadata — it is what you were
     looking for when you turned to this page, so it is the largest thing on it. */
  .journal-page-date { font-size: 16px; color: var(--ink); letter-spacing: 0.02em; }
  .journal-page .journal-textarea { min-height: 420px; }
  .journal-page-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
  .journal-page-nav { min-width: 32px; }
  .journal-page-nav:disabled { opacity: 0.3; cursor: default; }
  .journal-fav-on { color: var(--gold); border-color: var(--gold); }
  /* PART 23 — THE DELETE BUTTON WAS INVISIBLE, AND THIS IS THE SECOND TIME.
     Measured: opacity 0, 54x40, in every theme. `.journal-del` and the shared `.del-btn` have the
     SAME specificity (0,1,0), and .del-btn's `opacity: 0` is declared LATER in this stylesheet —
     so the plain class rule lost the cascade and the control could never appear. The interests
     list hit exactly this in V1.2 and was fixed with a descendant selector, which is why that one
     works; writing the journal rule as a bare class repeated the mistake with a different name.
     Fixed by SPECIFICITY rather than by source order, so it cannot silently regress if these
     blocks are ever reordered: `.journal-page-actions .del-btn` is (0,2,0) and beats .del-btn
     wherever either happens to sit. */
  .journal-page-actions .del-btn, .journal-page-actions .journal-del {
    color: var(--ink-soft); opacity: 1; }
  .journal-page-actions .del-btn:hover, .journal-page-actions .del-btn:focus-visible {
    color: var(--red); border-color: var(--red); opacity: 1; }
  .journal-prompt-line { font-size: 12px; color: var(--ink-soft); font-style: italic;
    border-left: 2px solid var(--cyan-dim); padding-left: 10px; margin: 8px 0 4px; }
  .journal-page-foot { font-size: 10px; color: var(--ink-faint); letter-spacing: 0.06em;
    text-transform: uppercase; margin-top: 10px; text-align: right; }
  .journal-reflect-list { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
  .journal-reflect-row { display: flex; align-items: baseline; gap: 12px; background: none; border: 0;
    border-bottom: 1px solid var(--border-soft); color: var(--ink-soft); font: inherit; font-size: 12.5px;
    padding: 9px 2px; cursor: pointer; text-align: left; width: 100%; min-width: 0; min-height: var(--tap); }
  .journal-reflect-row:hover { color: var(--ink); }
  .journal-reflect-date { flex: 0 0 auto; color: var(--ink-faint); font-size: 11px; min-width: 62px; }
  .journal-reflect-title { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
  .journal-prompt-chip { text-align: left; }
  /* Below the two-column breakpoint the index becomes a band ABOVE the page rather than beside
     it — a 200px sidebar next to a writing area on a 390px screen leaves neither usable. It keeps
     its own scroll so a long index cannot push the page off the bottom of the screen. */
  @media (max-width: 900px) {
    .journal-book { grid-template-columns: minmax(0, 1fr); }
    .journal-index { border-right: 0; border-bottom: 1px solid var(--border-soft);
      padding-right: 0; padding-bottom: 12px; max-height: 260px; }
  }
  .journal-editor-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
  .journal-title-input {
    flex: 1; min-width: 200px; background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink);
    font-family: var(--mono); font-size: 15px; font-weight: 600; padding: 10px 12px; border-radius: 2px;
  }
  .journal-title-input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  .journal-edit-date-label { font-size: 11px; color: var(--ink-faint); letter-spacing: 0.04em; margin: 10px 0 10px; }
  .journal-textarea {
    width: 100%; min-height: 420px; resize: vertical;
    background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink);
    font-family: var(--mono); font-size: 14.5px; line-height: 1.85; padding: 18px 20px;
    border-radius: 3px;
  }
  .journal-textarea:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  @media (max-width: 640px) {
    .journal-textarea { min-height: 320px; padding: 14px 16px; }
  }
  /* ---- Lists ---- */
  .list { list-style: none; margin: 0; padding: 0; }
  .list-item { display: flex; align-items: center; gap: 9px; padding: 7px 0; border-bottom: 1px solid var(--border-soft); font-size: 13px; }
  .list-item:last-child { border-bottom: none; }
  .list-item.done .task-text { color: var(--ink-faint); text-decoration: line-through; }
  .checkbox {
    width: 15px; height: 15px; border: 1px solid var(--ink-faint); border-radius: 2px;
    display: flex; align-items: center; justify-content: center; flex-shrink: 0; cursor: pointer;
    background: var(--panel-raised);
  }
  .checkbox.checked { background: var(--cyan); border-color: var(--cyan); }
  .checkbox.checked::after { content: "✓"; font-size: 10px; color: var(--on-accent); }
  .task-text, .evt-label { flex: 1; word-break: break-word; }
  .evt-time { color: var(--cyan-dim); font-size: 12px; min-width: 62px; }
  .del-btn { background: none; border: none; color: var(--ink-faint); font-size: 14px; opacity: 0; transition: opacity 0.1s; cursor: pointer; }
  .list-item:hover .del-btn { opacity: 1; }
  .del-btn:hover { color: var(--red); }
  .list-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; }
  .add-row { display: flex; gap: 8px; margin-top: 10px; min-width: 0; }
  .add-row input { flex: 1; min-width: 0; }
  .add-row input.evt-time-input { flex: 0 0 82px; min-width: 0; }
  .count-tag { font-size: 10px; color: var(--ink-faint); }
  /* ---- Radar hero ---- */
  @keyframes spin-slow { to { transform: rotate(360deg); } }
  .core-pulse { transform-box: view-box; transform-origin: 110px 110px; animation: core-breathe 3.2s ease-in-out infinite; }
  .core-pulse-inner { transform-box: view-box; transform-origin: 110px 110px; animation: core-breathe-inner 3.2s ease-in-out infinite; }
  @keyframes core-breathe { 0%, 100% { transform: scale(0.88); opacity: 0.7; } 50% { transform: scale(1.18); opacity: 1; } }
  @keyframes core-breathe-inner { 0%, 100% { transform: scale(0.82); } 50% { transform: scale(1.3); } }
  .orbit-ring { transform-box: view-box; transform-origin: 110px 110px; }
  .orbit-ring.ring-a { animation: orbit-spin 7s linear infinite; }
  .orbit-ring.ring-b { animation: orbit-spin-rev 10s linear infinite; }
  .orbit-ring.ring-c { animation: orbit-spin 5s linear infinite; }
  @keyframes orbit-spin { to { transform: rotate(360deg); } }
  @keyframes orbit-spin-rev { to { transform: rotate(-360deg); } }
  @media (prefers-reduced-motion: reduce) {
    .core-pulse, .core-pulse-inner, .orbit-ring.ring-a, .orbit-ring.ring-b, .orbit-ring.ring-c { animation: none; }
  }
  /* V1.1: fills previously-empty vertical space with real, already-available Life OS data */
  /* ---- Segmented filter tabs (Life & Interests lists) ---- */
  .tab-row { display: flex; gap: 6px; margin-bottom: 12px; }
  .tab-btn {
    background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink-soft);
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.04em; padding: 5px 10px;
    cursor: pointer; text-transform: uppercase;
  }
  .tab-btn.active { color: var(--cyan-bright); border-color: var(--cyan); }
  /* ---- Log ---- */
  .log-line { font-size: 11.5px; color: var(--ink-soft); line-height: 1.7; }
  .log-time { color: var(--cyan-dim); }
  /* ---- Mini calendar ---- */
  .mini-cal-nav {
    background: none; border: 1px solid var(--border); color: var(--cyan-dim);
    width: 20px; height: 20px; border-radius: 3px; cursor: pointer; font-size: 12px;
    display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-family: var(--mono);
  }
  .mini-cal-nav:hover { color: var(--cyan); border-color: var(--cyan); }
  /* V1.1: individual dates are now clickable — this calendar is a lightweight preview/nav
     onto the real Daily Schedule data, so cells need an obvious interactive affordance. */
  /* Sprint 2C-2 Part 8: small dot for days inside a trip's date range (reads state.travel.trips
     directly — see tripsOnDate()). Subtle so it doesn't compete with .today/.selected. */
  /* Sprint 9: same decorative-only pattern as .has-trip above, for days with a birthday (reads
     peopleState.people directly via dsPeopleBirthdaysOnDate() — People/Birthdays stays the
     source of truth, nothing duplicated here). Uses --green (not --gold) so it stays visually
     distinct from a trip-day dot when both happen to land on the same date. No click-through —
     matches .has-trip's own decorative-only behavior; the full Schedule -> Birthdays view is
     where a birthday is actually explored. */
  /* Banner shown in the Home Schedule widget when the selected date falls inside a trip. */
  .schedule-travel-banner { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 6px 10px; font-size: 11px; color: var(--gold); margin-bottom: 8px; cursor: pointer; }
  .schedule-travel-banner:hover { border-color: var(--gold); }
  /* ---- Credit Cards tab ---- */
  .cc-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
  /* Collapse only on true mobile widths — tablet keeps the 2-column layout. */
  @media (max-width: 640px) { .cc-grid { grid-template-columns: minmax(0, 1fr); } }
  .cc-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 4px; flex-wrap: wrap; }
  .cc-card-name { font-size: 15px; letter-spacing: 0.05em; color: var(--cyan-bright); text-transform: uppercase; text-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.35); }
  .cc-legacy-tag {
    display: inline-block; font-size: 8.5px; letter-spacing: 0.1em; color: var(--red);
    border: 1px solid rgba(var(--red-rgb), 0.4); padding: 2px 6px; border-radius: 2px; margin-left: 8px;
    text-transform: uppercase; vertical-align: middle;
  }
  .cc-fee-badge {
    font-size: 11px; padding: 4px 10px; border: 1px solid var(--border); border-radius: 2px;
    color: var(--gold); white-space: nowrap; letter-spacing: 0.03em;
  }
  .cc-section-label {
    font-size: 10px; letter-spacing: 0.14em; color: var(--cyan-dim); text-transform: uppercase;
    margin: 14px 0 7px; border-top: 1px solid var(--border-soft); padding-top: 11px;
  }
  .cc-section-label.first { border-top: none; padding-top: 0; margin-top: 10px; }
  .cc-list { list-style: none; margin: 0; padding: 0; font-size: 12.5px; color: var(--ink-soft); line-height: 1.7; }
  .cc-list li { padding-left: 15px; position: relative; margin-bottom: 2px; }
  .cc-list li::before { content: "›"; position: absolute; left: 0; color: var(--cyan-dim); }
  .cc-list li strong { color: var(--ink); font-weight: 600; }
  .cc-note { margin-top: 15px; font-size: 10.5px; color: var(--ink-faint); border-top: 1px solid var(--border-soft); padding-top: 11px; line-height: 1.7; }
  .cc-sources { margin-top: 18px; font-size: 10px; color: var(--ink-faint); line-height: 1.8; }
  .cc-sources a { color: var(--cyan-dim); }
  .cc-sources a:hover { color: var(--cyan); }
  /* ---- Progress tab ---- */
  /* V1 VISUAL & UX POLISH SPRINT (Part 20): .progress-header / .progress-title /
     .progress-subtitle were removed here. Each was used exactly once (the Habits page header)
     and each duplicated the corresponding .fin-* rule declaration for declaration. Habits now
     uses .fin-header / .fin-title / .fin-subtitle like every other tab — see #mainTabProgress. */
  .progress-view-toggle { display: flex; border: 1px solid var(--border); border-radius: 3px; overflow: hidden; }
  .pv-btn { background: var(--panel-raised); border: none; border-right: 1px solid var(--border); color: var(--ink-soft); font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase; padding: 8px 18px; cursor: pointer; }
  .pv-btn:last-child { border-right: none; }
  .pv-btn.active { background: var(--cyan); color: var(--on-accent); font-weight: 700; }
  .progress-section { margin-bottom: 18px; }
  .progress-top-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; align-items: stretch; }
  .progress-top-row > .progress-section { margin-bottom: 0; height: 100%; }
  /* Fitness V2.2 (Part A): a variant of the two-up row that does NOT stretch its panels to equal
     height. Pairing Fitness Insights (~170px of short sentences) with the consistency calendar
     (432px) in a stretch grid inflated the Insights card to 432px with 62% of it empty - measured
     immediately after the reorder. That is the same "giant sparse card" the brief warns about,
     merely relocated from the Score to Insights. Letting each panel take its natural height turns
     that dead space into page background instead of an empty bordered box implying missing
     content. Row 2 (Score | Status) keeps the default stretch, since 309px and 309px already
     match. */
  .progress-top-row--natural { align-items: start; }
  /* V1.1 (Part 9): the Fitness Overview pair puts a COLUMN WRAPPER in the grid, not the panel, so
     stretching the row alone stopped one level short and the card still sat 138px shorter than
     Consistency. The wrapper now fills the row and its panel fills the wrapper — layout behaviour
     only, no filler content and no fixed heights. */
  .progress-top-row > .fit-overview-col { height: 100%; display: flex; flex-direction: column; }
  .progress-top-row > .fit-overview-col > .progress-section { flex: 1 1 auto; }
  /* align-items:start alone is not enough: the rule above sets height:100% on every panel in
     this grid, and a percentage height resolves against the GRID AREA, which still spans the
     full row track. The panel has to opt out of that too. */
  .progress-top-row--natural > .progress-section { height: auto; }
  /* Fitness V2.2: the left Overview column stacks Insights and (when targets exist) Today's
     Macros, so the column has real content rather than the 62% slack the Part A audit measured. */
  .fit-overview-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
  .fit-overview-col > .progress-section { margin-bottom: 0; }
  /* Collapse only on true mobile widths — tablet keeps the 2-column layout. */
  @media (max-width: 640px) { .progress-top-row { grid-template-columns: minmax(0, 1fr); } }
  /* V1.4 (Part 4) — the check-in card's context line. Deliberately quiet: this is a caption on a
     list, not a second header, so it sits at the same 11px/uppercase weight as .module-code above
     it rather than competing with the module title. The manage control reuses .muted-link, which
     is the OS-wide lightweight text button and already carries its own 32px / 44px tap sizing at
     both breakpoints — so this adds a control without adding a control style. */
  .checkin-meta { display: flex; align-items: center; justify-content: space-between;
    gap: 10px; flex-wrap: wrap; margin: 0 0 10px; }
  .checkin-meta-count { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--ink-soft); font-family: var(--mono); }
  .overall-progress-readout { font-size: 44px; font-weight: 700; text-align: center; color: var(--ink); text-shadow: 0 0 16px rgba(var(--cyan-glow-rgb), 0.3); }
  .progress-bar-track { height: 14px; border-radius: 7px; background: var(--panel-raised); border: 1px solid var(--border-soft); overflow: hidden; margin: 14px 0 8px; }
  .progress-bar-fill { height: 100%; border-radius: 7px; width: 0%; background: linear-gradient(90deg, var(--cyan-dim), var(--cyan-bright)); transition: width var(--transition-smooth); }
  .overall-progress-sub { text-align: center; font-size: 12.5px; color: var(--ink-soft); }
  .category-row { margin-bottom: 14px; }
  .category-row:last-child { margin-bottom: 0; }
  .category-row-head { display: flex; justify-content: space-between; font-size: 12.5px; color: var(--ink); margin-bottom: 6px; }
  .category-row-head .cr-pct { color: var(--cyan-bright); font-weight: 600; }
  .category-bar-track { height: 9px; border-radius: 5px; background: var(--panel-raised); border: 1px solid var(--border-soft); overflow: hidden; }
  .category-bar-fill { height: 100%; border-radius: 5px; width: 0%; transition: width var(--transition-smooth); }
  .category-row-sub { font-size: 10.5px; color: var(--ink-faint); margin-top: 4px; }
  .week-chart { display: flex; justify-content: space-between; align-items: flex-end; gap: 8px; height: 150px; margin: 10px 0 4px; padding: 0 2px; }
  .week-chart-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 6px; }
  .week-chart-bar-track { width: 100%; max-width: 34px; height: 100%; display: flex; align-items: flex-end; background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; overflow: hidden; }
  .week-chart-bar-fill { width: 100%; height: 0%; border-radius: 0; transition: height var(--transition-smooth); }
  .week-chart-pct { font-size: 10.5px; color: var(--ink-soft); }
  .week-chart-day { font-size: 10px; color: var(--ink-faint); letter-spacing: 0.06em; text-transform: uppercase; }
  .week-chart-col.is-today .week-chart-day { color: var(--cyan-bright); }
  .key-stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px,1fr)); gap: 10px; }
  .stat-tile { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 12px 14px; }
  .stat-tile-label { font-size: 10px; letter-spacing: 0.08em; color: var(--ink-faint); text-transform: uppercase; margin-bottom: 5px; }
  .stat-tile-value { font-size: 16px; color: var(--ink); word-break: break-word; }
  .cal-nav-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; gap: 10px; flex-wrap: wrap; }
  .cal-nav-title { font-size: 12.5px; letter-spacing: 0.08em; color: var(--ink); text-transform: uppercase; }
  .cal-grid { display: grid; grid-template-columns: repeat(7,1fr); gap: 5px; }
  .cal-weekday-label { text-align: center; font-size: 9.5px; color: var(--ink-faint); letter-spacing: 0.05em; padding-bottom: 4px; }
  .cal-cell { aspect-ratio: 1; border-radius: 4px; display: flex; align-items: center; justify-content: center; font-size: 11px; color: var(--on-accent); cursor: pointer; border: 1px solid transparent; }
  .cal-cell.empty { visibility: hidden; cursor: default; }
  .cal-cell.no-data { background: var(--panel-raised); color: var(--ink-faint); border: 1px solid var(--border-soft); }
  .cal-cell.future { background: transparent; color: var(--ink-faint); border: 1px dashed var(--border-soft); cursor: default; }
  .cal-cell.selected { border-color: var(--cyan-bright); box-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.5); }
  .cal-cell.is-today { outline: 2px solid var(--cyan-bright); outline-offset: 1px; }
  .cal-day-detail { margin-top: 12px; padding: 10px 12px; background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; font-size: 12px; color: var(--ink-soft); line-height: 1.7; }
  .cal-day-detail strong { color: var(--ink); }
  .month-cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px,1fr)); gap: 10px; margin-bottom: 20px; }
  .month-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 12px 14px; }
  .month-card.future { opacity: 0.4; }
  .month-card-name { font-size: 11px; color: var(--ink); letter-spacing: 0.05em; text-transform: uppercase; margin-bottom: 6px; }
  .month-card-pct { font-size: 18px; color: var(--cyan-bright); margin-bottom: 8px; }
  .month-card-bar { height: 6px; border-radius: 3px; background: var(--panel); overflow: hidden; }
  .month-card-bar-fill { height: 100%; border-radius: 3px; transition: width 0.7s ease; }
  .year-heatmap-wrap { overflow-x: auto; padding-bottom: 6px; }
  .year-heatmap { display: grid; grid-auto-flow: column; grid-template-rows: repeat(7, 12px); gap: 3px; width: max-content; }
  .heat-cell { width: 12px; height: 12px; border-radius: 2px; }
  .life-balance-wrap { display: flex; gap: 24px; flex-wrap: wrap; align-items: center; justify-content: center; }
  .life-balance-radar { flex-shrink: 0; }
  .life-balance-legend { display: flex; flex-direction: column; gap: 10px; min-width: 200px; flex: 1; justify-content: center; }
  .lb-legend-row { display: flex; justify-content: space-between; align-items: center; font-size: 12.5px; }
  .lb-legend-name { color: var(--ink); }
  .lb-legend-pct { color: var(--cyan-bright); font-weight: 600; }
  .insight-card { display: block; padding: 10px 0; border-bottom: 1px solid var(--border-soft); font-size: 12.5px; color: var(--ink-soft); line-height: 1.6; }
  .insight-card:last-child { border-bottom: none; }
  .habit-row { display: flex; gap: 8px; align-items: center; margin-bottom: 7px; flex-wrap: wrap; }
  .habit-row .habit-row-name { flex: 1; min-width: 110px; font-size: 12.5px; color: var(--ink); }
  .habit-row select { font-size: 11px; padding: 5px 6px; }
  /* ---------- Habit Tracker: Manage Habits check-in period/category tabs ---------- */
  .hm-tab-row { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
  .hm-tab-btn { background: var(--panel-raised); border: 1px solid var(--border-soft); color: var(--ink-soft); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.03em; padding: 6px 10px; cursor: pointer; border-radius: 3px; transition: border-color 0.15s ease, color 0.15s ease; white-space: nowrap; }
  .hm-tab-btn:hover { color: var(--cyan-bright); }
  .hm-tab-btn.active { color: var(--cyan-bright); border-color: var(--cyan); background: var(--panel); box-shadow: 0 0 6px rgba(var(--cyan-glow-rgb), 0.2); }
  .hm-category-row { margin-bottom: 12px; }
  .habit-row-disabled { opacity: 0.5; }
  .hm-toggle-btn { background: none; border: none; font-size: 13px; padding: 0 3px; cursor: pointer; line-height: 1; }
  .due-badge { font-size: 9.5px; color: var(--ink-faint); letter-spacing: 0.04em; text-transform: uppercase; margin-left: 6px; white-space: nowrap; }
  .habit-drag-handle { cursor: grab; color: var(--ink-faint); font-size: 14px; padding: 0 2px; user-select: none; flex-shrink: 0; touch-action: none; }
  .habit-drag-handle:hover { color: var(--cyan-dim); }
  .habit-drag-handle:active { cursor: grabbing; }
  #dueTodayList .list-item.dragging { opacity: 0.35; }
  #dueTodayList .list-item.drag-over { border-top: 2px solid var(--cyan-bright); }
  #dueTodayList .list-item { cursor: default; }
  .habit-reorder-btns { display: flex; flex-direction: column; gap: 1px; margin-left: 4px; flex-shrink: 0; }
  /* V1 VISUAL & UX POLISH SPRINT (Part 11): these measured 14x12px — the smallest interactive
     targets in the OS, and a pair of them sit 1px apart, so on touch the wrong one was as likely
     to fire as the right one. The GLYPH stays small (this is a secondary control and must not
     start shouting); only the hit box grows, via min-width/min-height + centering.
     Desktop keeps the vertical stack — 40x20 each, so the pair still occupies one 40px row and
     no habit row gets taller. Below 640px the stack turns horizontal so each arrow can reach a
     full 44x44 without doubling row height. */
  .reorder-btn { background: none; border: none; color: var(--ink-faint); font-size: 8px; line-height: 1;
    padding: 0; cursor: pointer; min-width: 40px; min-height: 20px;
    display: flex; align-items: center; justify-content: center; }
  .reorder-btn:hover:not(:disabled) { color: var(--cyan); }
  .reorder-btn:disabled { opacity: 0.2; cursor: default; }
  @media (max-width: 640px) {
    .habit-reorder-btns { flex-direction: row; gap: 2px; }
    .reorder-btn { min-width: 44px; min-height: 44px; font-size: 10px; }
  }
  @media (max-width: 640px) {
    .overall-progress-readout { font-size: 34px; }
    .week-chart { height: 120px; }
    .life-balance-wrap { flex-direction: column; }
    .pv-btn { padding: 8px 10px; font-size: 10px; }
  }
  /* ---- Finance tab ---- */
  .fin-header { display: flex; justify-content: space-between; align-items: flex-end; flex-wrap: wrap; gap: 16px; margin-bottom: 20px; }
  .fin-title { font-size: 22px; letter-spacing: 0.08em; color: var(--cyan-bright); text-transform: uppercase; text-shadow: 0 0 12px rgba(var(--cyan-glow-rgb), 0.4); }
  .fin-subtitle { font-size: 12px; color: var(--ink-soft); margin-top: 6px; letter-spacing: 0.02em; max-width: 620px; line-height: 1.6; }
  /* V1 VISUAL & UX POLISH SPRINT (Part 20): the level BELOW a page header — a named section
     inside a tab that is not itself a destination. Deliberately one clear step down from
     .fin-title (16px vs 22px, --ink rather than the glowing --cyan-bright) so a reader can tell
     at a glance which heading names the screen and which names a part of it. */
  .sub-header { margin-bottom: 18px; }
  .sub-header-title { font-size: 16px; letter-spacing: 0.08em; color: var(--ink); text-transform: uppercase; }
  .kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 18px; }
  @media (max-width: 900px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 520px) { .kpi-grid { grid-template-columns: minmax(0, 1fr); } }
  .kpi-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 14px 16px; }
  .kpi-label { font-size: 9.5px; letter-spacing: 0.1em; color: var(--ink-faint); text-transform: uppercase; margin-bottom: 8px; }
  /* ============ V1 VISUAL & UX POLISH SPRINT (Part 24) — KPI TYPOGRAPHY SCALE ============
     The Part 1 re-audit found .kpi-value rendering at EIGHT different sizes across the OS:
     12.5, 13, 14, 16, 20, 21, 22 and 26px — every one of them an inline style:font-size except
     the 21px base. Seven of the eight were within a few pixels of each other, so they read as
     accidental drift rather than as hierarchy: a number was not bigger because it mattered
     more, it was bigger because of which function happened to render it.

     Three deliberate steps now, and a rule for choosing between them:

       --kpi-fs-hero  26px  ONE figure per screen, the headline the screen exists to show.
                            Currently only the Net Worth Tracker's current-net-worth readout.
       --kpi-fs-base  21px  The primary KPI grid of a tab. Finance Overview, Fitness Progress.
       --kpi-fs-sec   16px  Secondary/summary tiles inside a module. Life, Travel, Fitness macros.
       --kpi-fs-text  13px  Tiles whose value is a WORD or a DATE, not a magnitude ("Completed",
                            "Mar 3 – Mar 9"). These never competed with the numbers; they were
                            just being shrunk ad hoc to fit, at 12.5, 13 and 14px.

     Sizes moved by at most 3px anywhere, and only toward an existing neighbour, so no screen is
     redesigned — the point is that the next person adding a KPI has three named choices instead
     of a free-form number. */
  :root { --kpi-fs-hero: 26px; --kpi-fs-base: 21px; --kpi-fs-sec: 16px; --kpi-fs-text: 13px; }
  .kpi-value { font-size: var(--kpi-fs-base); color: var(--ink); font-weight: 600; word-break: break-word; }
  .kpi-value--hero { font-size: var(--kpi-fs-hero); }
  .kpi-value--sec { font-size: var(--kpi-fs-sec); }
  .kpi-value--text { font-size: var(--kpi-fs-text); font-weight: 500; }
  .kpi-value.neg { color: var(--red); }
  /* V1 Polish (Part 8): the untracked em-dash keeps the KPI grid's row rhythm (same font-size, so
     cards stay the same height) but recedes, so a screen of dashes reads as "nothing here yet"
     rather than as a screen of real figures. */
  .kpi-value--untracked { color: var(--ink-faint); font-weight: 500; }
  .kpi-delta { font-size: 10.5px; margin-top: 6px; display: flex; align-items: center; gap: 5px; }
  .kpi-delta.up { color: var(--green); }
  .kpi-delta.down { color: var(--red); }
  .kpi-delta.flat { color: var(--ink-faint); }
  .fin-section-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; align-items: start; }
  /* Collapse only on true mobile widths — tablet keeps the 2-column layout. */
  @media (max-width: 640px) { .fin-section-row { grid-template-columns: minmax(0, 1fr); } }
  .fin-range-toggle { display: flex; border: 1px solid var(--border); border-radius: 3px; overflow: hidden; flex-wrap: wrap; }
  .fin-range-btn { background: var(--panel-raised); border: none; border-right: 1px solid var(--border); color: var(--ink-soft); font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.04em; text-transform: uppercase; padding: 6px 11px; cursor: pointer; }
  .fin-range-btn:last-child { border-right: none; }
  .fin-range-btn.active { background: var(--cyan); color: var(--on-accent); font-weight: 700; }
  .month-select-row { display: flex; align-items: center; gap: 8px; }
  .nw-chart-wrap { margin-top: 10px; }
  /* V1.7 Sprint (Net Worth Data-First Layout, Part 4): reserves a fixed line so tapping a chart
     point doesn't shift layout when the readout text appears; empty by default. */
  .nw-chart-readout { min-height: 15px; padding: 4px 0 0; color: var(--cyan-bright); font-size: 11px; }
  .nw-svg-wrap { width: 100%; overflow-x: auto; }
  .accounts-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
  @media (max-width: 700px) { .accounts-cols { grid-template-columns: minmax(0, 1fr); } }
  .accounts-col-label { font-size: 10px; letter-spacing: 0.14em; color: var(--cyan-dim); text-transform: uppercase; margin-bottom: 8px; }
  .acct-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border-soft); font-size: 12.5px; }
  .acct-row:last-child { border-bottom: none; }
  /* V1.1 Sprint 2A Part 7: highlights the entry currently loaded into the edit form below. */
  .cf-row-editing { background: var(--panel-raised); border-radius: 3px; }
  .acct-name { flex: 1; color: var(--ink); word-break: break-word; }
  .acct-cat { font-size: 9.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.03em; white-space: nowrap; }
  .acct-balance { color: var(--ink-soft); white-space: nowrap; min-width: 74px; text-align: right; }
  .acct-total-row { display: flex; justify-content: space-between; padding-top: 10px; margin-top: 4px; border-top: 1px solid var(--border); font-size: 13px; color: var(--ink); font-weight: 600; }
  .acct-edit-name { flex: 1; min-width: 90px; }
  .acct-edit-cat { width: 128px; flex-shrink: 0; }
  .acct-edit-balance { width: 92px; flex-shrink: 0; text-align: right; }
  .fin-add-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr auto; gap: 8px; margin-top: 10px; }
  @media (max-width: 700px) { .fin-add-grid { grid-template-columns: 1fr 1fr; } }
  .fin-add-grid select, .fin-add-grid input { width: 100%; }
  .donut-legend-wrap { display: flex; gap: 20px; flex-wrap: wrap; align-items: center; justify-content: center; }
  .donut-legend { display: flex; flex-direction: column; gap: 8px; min-width: 160px; }
  .donut-legend-row { display: flex; align-items: center; gap: 8px; font-size: 12px; }
  .donut-swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
  .donut-legend-name { flex: 1; color: var(--ink-soft); }
  .donut-legend-pct { color: var(--ink); font-weight: 600; }
  /* V1.1 Sprint 2A Part 8: table-layout:fixed + explicit column widths (via <col> below) so the
     Category column's inner progress bar can no longer inflate its column and push Budget/
     Actual/Difference/Status further right than intended — the classic auto-table-layout trap
     where a block-level child with a min-width gets treated as that column's minimum content
     width. Calculations/data model are untouched; this is layout-only. */
  .budget-table { width: 100%; border-collapse: collapse; font-size: 12.5px; table-layout: fixed; }
  .budget-table th { text-align: left; font-size: 9.5px; letter-spacing: 0.08em; color: var(--ink-faint); text-transform: uppercase; padding: 0 6px 8px; border-bottom: 1px solid var(--border-soft); }
  /* V1.9 Sprint (Budget alignment audit, Part 7/8): real rendered-UI measurement at 1366px found
     every header cell was left-aligned via the rule above, while Budget/Actual/Difference DATA
     cells are right-aligned (td.num below) — so each numeric header sat far to the left of the
     values it labeled (e.g. "ACTUAL" flush against Category while "$620" sat flush against the
     right edge of that same column), which is exactly the "looks off" complaint. Category and
     Status headers were already correctly left-aligned to match their (left-aligned) data, so
     only the three numeric headers need the fix — done by class rather than by touching the
     shared .budget-table th rule everything else still relies on. */
  .budget-table th.num { text-align: right; }
  .budget-table td { padding: 8px 6px; border-bottom: 1px solid var(--border-soft); vertical-align: middle; overflow: hidden; }
  .budget-table td.num { text-align: right; white-space: nowrap; }
  /* title attribute (set in renderBudgetSection) supplies the full name on hover/long-press when
     text-overflow: ellipsis below has to truncate a long category label — otherwise a truncated
     name has no way to be read in full, which is its own quiet form of "clipped text". */
  .budget-cat-name { color: var(--ink); display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .budget-status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 4px; }
  .budget-bar-track { height: 6px; border-radius: 3px; background: var(--panel-raised); border: 1px solid var(--border-soft); overflow: hidden; margin-top: 5px; width: 100%; min-width: 0; }
  .budget-bar-fill { height: 100%; border-radius: 3px; }
  .budget-table td.status-cell { white-space: nowrap; }
  /* V1.9 Sprint (Budget alignment audit, Part 7/8): the ≤480px override below used to only shave
     Category/Budget column widths, keeping the same 5-column <table>. A real screenshot at
     390x844 with realistic data showed that isn't enough — "DIFFERENCE" and "STATUS" headers
     visually collided, "+$2,000" got clipped mid-digit, and long category names truncated with
     no way to see the full name. That's exactly the "unusable microscopic table" Part 9 warns
     against, so narrow phones now get the same stacked-card treatment already used for the
     Historical Net Worth table: each <tr> becomes a labeled key/value stack instead of 5 cramped
     columns, using the same data-th/::before convention (data-th attributes set in
     renderBudgetSection) so no markup duplication or new data model is needed. */
  @media (max-width: 480px) {
    .budget-table thead { display: none; }
    .budget-table, .budget-table tbody, .budget-table tr { display: block; width: 100%; }
    .budget-table tr { padding: 10px 0; border-bottom: 1px solid var(--border-soft); }
    .budget-table td { display: flex; justify-content: space-between; align-items: center; gap: 10px; border-bottom: none; padding: 3px 0; text-align: right; white-space: normal; }
    .budget-table td::before { content: attr(data-th); color: var(--ink-faint); font-size: 9px; letter-spacing: 0.05em; text-transform: uppercase; flex-shrink: 0; }
    .budget-table td:first-child { display: block; text-align: left; padding: 0 0 6px; }
    .budget-table td:first-child::before { content: none; }
  }
  .fin-summary-strip { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 14px; }
  .fin-summary-chip { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 8px 14px; font-size: 11.5px; color: var(--ink-soft); flex: 1; min-width: 130px; }
  .fin-summary-chip strong { color: var(--ink); display: block; font-size: 15px; margin-top: 3px; }
  .goal-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 14px 16px; margin-bottom: 12px; }
  .goal-card-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
  .goal-name { font-size: 13px; color: var(--ink); letter-spacing: 0.03em; }
  .goal-type-tag { font-size: 9px; color: var(--cyan-dim); text-transform: uppercase; letter-spacing: 0.06em; margin-top: 3px; }
  .goal-amounts { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
  .goal-amounts strong { color: var(--ink); }
  .goal-bar-track { height: 10px; border-radius: 5px; background: var(--panel); border: 1px solid var(--border-soft); overflow: hidden; margin: 8px 0; }
  .goal-bar-fill { height: 100%; border-radius: 5px; background: linear-gradient(90deg, var(--cyan-dim), var(--cyan-bright)); transition: width var(--transition-smooth); }
  .goal-meta-row { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--ink-faint); flex-wrap: wrap; gap: 6px; }
  /* Finance V2 (Parts 16/18): priority and status stay deliberately subtle — small, uppercase,
     inline with the type tag — so a card still reads in about two seconds and no goal shouts. */
  .goal-card { cursor: pointer; }
  .goal-card-done { opacity: 0.72; }
  .goal-prio-tag, .goal-status-tag { font-size: 8.5px; letter-spacing: 0.06em; text-transform: uppercase; padding: 1px 5px; border-radius: 2px; margin-left: 5px; white-space: nowrap; }
  .goal-prio-high { background: rgba(var(--red-rgb), 0.14); color: var(--red); }
  /* V1 Polish (Part 30): was `var(--amber, #e8b23d)`. --amber has never been declared anywhere in
     this file, so this always resolved to the fallback — and that fallback is, digit for digit,
     the value of --gold. Renamed to the token that actually exists. Identical rendered colour. */
  .goal-prio-medium { background: rgba(var(--gold-rgb), 0.14); color: var(--gold); }
  .goal-prio-low { background: var(--panel); color: var(--ink-faint); }
  .goal-status-paused { background: var(--panel); color: var(--ink-faint); }
  .goal-status-done { background: rgba(var(--green-rgb), 0.14); color: var(--green); }
  .goal-linked-tag { color: var(--cyan-dim); }
  .goal-card-foot { display: flex; justify-content: flex-end; margin-top: 6px; }
  /* ---- Learning (V1.1) — reuses goal-bar-track/fill, fin-add-grid, review-field, fin-modal
     patterns already defined above/below; these are the few genuinely new pieces. ---- */
  /* V2.1 Sprint (Part 2): the goal's type and status. Deliberately quiet — same faint colour and
     letter-spacing as the decorative .module-code it replaced — so no single Learning type reads
     as more important than another, but it is never hidden, including on mobile. */
  .lrn-goal-meta { font-size: 9.5px; color: var(--ink-faint); letter-spacing: 0.1em; text-transform: uppercase; text-align: right; margin-bottom: 6px; }
  /* Goal switcher pill: name on top, type underneath, so a list of several goals stays readable
     when the names alone ("Biology 101", "Series 65", "Spanish") don't say what kind of thing
     each one is. Wrapping is handled by .fin-range-toggle's existing flex-wrap. */
  .lrn-goal-pill-type { display: block; font-size: 8.5px; letter-spacing: 0.08em; opacity: 0.7; margin-top: 2px; text-transform: uppercase; }
  .lrn-stats-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin-bottom: 14px; }
  .lrn-stat-label { font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 4px; }
  .lrn-stat-value { font-size: 15px; color: var(--ink); }
  .lrn-stat input[type="date"], .lrn-stat input[type="text"] { width: 100%; }
  .lrn-progress-row { display: flex; align-items: center; gap: 8px; }
  .lrn-progress-row input[type="number"] { width: 64px; flex-shrink: 0; }
  .lrn-last-session { font-size: 12px; color: var(--ink-soft); margin-bottom: 10px; }
  .lrn-next-row { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 10px 12px; margin-bottom: 14px; }
  .lrn-next-row input[type="text"] { width: 100%; margin-top: 4px; }
  .lrn-weekly-goal { border-top: 1px solid var(--border-soft); padding-top: 12px; margin-bottom: 14px; }
  .lrn-weekly-goal-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .lrn-weekly-goal-row input[type="number"] { width: 70px; }
  .lrn-history-day { font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-faint); margin: 12px 0 4px; }
  .lrn-history-day:first-child { margin-top: 0; }
  .lrn-history-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border-soft); cursor: pointer; }
  .lrn-history-row:last-child { border-bottom: none; }
  .lrn-history-row:hover { background: var(--panel-raised); }
  .lrn-history-main { flex: 1; font-size: 12.5px; color: var(--ink); }
  .lrn-history-meta { font-size: 10.5px; color: var(--ink-faint); }
  .lrn-test-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border-soft); }
  .lrn-test-row:last-child { border-bottom: none; }
  /* V1.5 Sprint (Finance Dashboard Refinement, Part 1/2): the old card-based debt layout
     (.debt-card/.debt-card-head/.debt-apr-tag/.debt-edit-apr/.debt-meta-grid) is retired along
     with the standalone Debt & Liabilities module — Debt & Liabilities now renders in the same
     .acct-row layout as Assets. .debt-edit-name/.debt-edit-cat/.debt-edit-balance are kept as
     class hooks (for styling/tests to target debt rows specifically) but now sized to match
     their .acct-edit-* counterparts exactly, since they share the same row layout. */
  .debt-edit-name { flex: 1; min-width: 90px; }
  .debt-edit-cat { width: 128px; flex-shrink: 0; }
  .debt-edit-balance { width: 92px; flex-shrink: 0; text-align: right; }
  .health-score-wrap { display: flex; gap: 24px; flex-wrap: wrap; align-items: center; }
  .health-score-gauge { flex-shrink: 0; text-align: center; }
  .health-score-readout { font-size: 40px; font-weight: 700; color: var(--ink); text-shadow: 0 0 14px rgba(var(--cyan-glow-rgb), 0.3); }
  .health-score-sub { font-size: 11px; color: var(--ink-soft); margin-top: 2px; }
  /* V1.6 Sprint (Intelligent Financial Health, Part 4): score TRANSPARENCY, not a report — a short
     Drivers/Watch readout replaces the old per-factor weighted-bar breakdown (.hc-row/.hc-editable,
     retired along with the manual weight editor they belonged to). */
  .health-drivers { flex: 1; min-width: 200px; display: flex; flex-direction: column; gap: 10px; }
  .hc-drivers-group { display: flex; flex-direction: column; gap: 4px; }
  .hc-drivers-label { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 2px; }
  .hc-driver-pos { font-size: 12.5px; color: var(--green); }
  .hc-driver-watch { font-size: 12.5px; color: var(--gold); }
  .health-score-empty { padding: 6px 0; }
  /* V1.7 Sprint's Cash Flow Health module (and its .cfh-* rules that lived here) was replaced by
     Financial Insights in the V1.8 Sprint — Financial Insights reuses .health-score-empty above
     plus the shared .insight-card rows (Habits' Insights module CSS, ~line 595) rather than
     needing any new CSS of its own. */
  /* V1.6 Sprint (Cash Flow sorting/reordering): a compact sort control row above each Cash Flow
     list (Income/Expenses) — see cfSortControlsHtml. */
  .cf-sort-row { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; flex-wrap: wrap; }
  .cf-sort-row select { width: auto; font-size: 11px; padding: 4px 6px; }
  .cf-move-btns { display: flex; gap: 4px; }
  /* V1.6 Sprint (Net Worth transparency, Parts 11-13): the compact Month/Assets/Debt/Net Worth
     table under the Net Worth Trend chart — a plain 4-column grid, not another chart. Horizontal
     scroll (not wrap) keeps narrow phones from crushing the number columns unreadably. */
  .nw-table-wrap { margin-top: 10px; max-height: 260px; overflow-y: auto; }
  .nw-table-scroll { width: 100%; overflow-x: auto; }
  /* V1.8 Sprint (Historical Net Worth clipping audit, Part 2/3): a real audit across 14 viewport
     widths (320-1920px) plus adversarial data (8-digit dollar values, 12+ months) found no
     reproducible clipping in this table with realistic data — see the Final Report for the
     methodology. This is nonetheless a deliberate hardening pass so any future extreme value fails
     SAFE rather than silently: cells get their own ellipsis/title fallback (min-width:0 lets a
     column shrink instead of forcing the whole row wider), and nwTableScrollHint below makes any
     remaining horizontal scroll a visible, deliberate affordance instead of an invisible one — the
     brief's own distinction between "deliberate and usable" and "accidental clipping". */
  .nw-table-row { display: grid; grid-template-columns: 1.1fr 1fr 1fr 1fr 0.7fr; gap: 8px; padding: 5px 0; border-bottom: 1px solid var(--border-soft); font-size: 11.5px; color: var(--ink-soft); white-space: nowrap; min-width: 380px; align-items: center; }
  .nw-table-row:last-child { border-bottom: none; }
  .nw-table-row span:not(:first-child) { text-align: right; }
  .nw-table-row span:not(.nw-table-action) { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  .nw-table-scroll-hint { font-size: 9.5px; color: var(--ink-faint); text-align: right; margin-top: 4px; letter-spacing: 0.03em; }
  .nw-table-head { color: var(--ink-faint); font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; border-bottom: 1px solid var(--border); }
  .nw-table-live-badge { font-size: 9px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--cyan-bright); border: 1px solid var(--cyan-bright); border-radius: 8px; padding: 1px 6px; white-space: nowrap; }
  .nw-table-edit { cursor: pointer; display: inline-flex; align-items: center; justify-content: flex-end; min-height: 32px; }
  .nw-table-action { display: flex; justify-content: flex-end; }
  /* Part 7: "convert rows into compact stacked cards" on narrow phones — the grid becomes a
     labeled key/value stack per row instead of 5 cramped columns. data-th attributes (set in
     renderNwHistoryTable) supply the label via ::before, so no markup duplication is needed. */
  @media (max-width: 480px) {
    .nw-table-row:not(.nw-table-head) {
      display: flex; flex-direction: column; gap: 4px; min-width: 0; white-space: normal; padding: 10px 0;
    }
    .nw-table-row:not(.nw-table-head) span { display: flex; justify-content: space-between; text-align: left; gap: 10px; }
    .nw-table-row:not(.nw-table-head) span::before { content: attr(data-th); color: var(--ink-faint); font-size: 9px; letter-spacing: 0.05em; text-transform: uppercase; }
    .nw-table-row.nw-table-head { display: none; }
  }
  .review-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
  @media (max-width: 700px) { .review-grid { grid-template-columns: minmax(0, 1fr); } }
  .review-field-label { font-size: 10.5px; color: var(--ink-soft); margin-bottom: 5px; letter-spacing: 0.02em; }
  .review-field textarea, .review-field input {
    width: 100%; background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink);
    border-radius: 2px; padding: 8px 10px; font-size: 12.5px; font-family: var(--mono); resize: vertical;
  }
  .review-field textarea:focus-visible, .review-field input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  .review-field { margin-bottom: 12px; }
  .fin-mini-btn { background: none; border: 1px solid var(--border); color: var(--cyan-dim); font-size: 10.5px; padding: 4px 9px; border-radius: 2px; cursor: pointer; font-family: var(--mono); }
  .fin-mini-btn:hover { color: var(--cyan); border-color: var(--cyan); }
  .fin-collapse { margin-top: 10px; border-top: 1px solid var(--border-soft); padding-top: 10px; }
  .alloc-input-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
  .alloc-input-row label { flex: 1; font-size: 12px; color: var(--ink-soft); display: flex; align-items: center; gap: 6px; }
  .alloc-input-row input { width: 60px; }
  .invest-row { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border-soft); font-size: 12px; flex-wrap: wrap; }
  .invest-row:last-child { border-bottom: none; }
  .invest-name { flex: 1; min-width: 100px; color: var(--ink); }
  .invest-gain { min-width: 70px; text-align: right; }
  .fin-progress-readout { font-size: 34px; font-weight: 700; text-align: center; color: var(--ink); text-shadow: 0 0 14px rgba(var(--cyan-glow-rgb), 0.3); }
  /* ---- Life & Interests tab ---- */
  /* .life-nav-btn/.home-nav-btn/.trav-nav-btn (defined below) are one shared sub-tab-nav look; grouped so the style only needs to change in one place. */
  .life-nav-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
  .life-nav-btn, .home-nav-btn, .trav-nav-btn { background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink-soft); font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; padding: 8px 14px; cursor: pointer; border-radius: 3px; transition: border-color 0.15s ease, color 0.15s ease; }
  .life-nav-btn.active, .home-nav-btn.active, .trav-nav-btn.active { color: var(--cyan-bright); border-color: var(--cyan); box-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.25); }
  .life-nav-btn:hover, .home-nav-btn:hover, .trav-nav-btn:hover { color: var(--cyan-bright); }
  .life-sub-panel, .home-sub-panel, .trav-sub-panel { display: none; }
  .life-sub-panel.active, .home-sub-panel.active, .trav-sub-panel.active { display: block; }
  .home-nav-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
  /* ---------- Daily Schedule ---------- */
  .ds-header { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 14px; margin-bottom: 16px; }
  .ds-date-label { font-size: 20px; color: var(--cyan-bright); margin-top: 4px; letter-spacing: 0.01em; }
  .ds-header-nav { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
  .ds-date-picker { background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink); border-radius: 3px; padding: 7px 10px; font-family: var(--mono); font-size: 11px; }
  .ds-now-chip { display: none; align-items: center; gap: 6px; font-size: 11px; color: var(--red); background: var(--panel-raised); border: 1px solid var(--border-soft); padding: 4px 10px; border-radius: 12px; }
  .ds-week-strip { display: flex; gap: 6px; overflow-x: auto; margin-bottom: 16px; padding-bottom: 2px; }
  .ds-week-day { flex: 1; min-width: 64px; background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 8px 4px; text-align: center; cursor: pointer; color: var(--ink-soft); font-family: var(--mono); }
  .ds-week-day.active { border-color: var(--cyan); color: var(--cyan-bright); box-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.25); }
  .ds-week-day-name { font-size: 9.5px; letter-spacing: 0.08em; text-transform: uppercase; }
  .ds-week-day-num { font-size: 15px; margin: 3px 0; }
  .ds-week-day-trip { font-size: 9px; vertical-align: super; }
  .ds-week-day-dots { font-size: 10px; color: var(--cyan); min-height: 12px; }
  .ds-summary-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; align-items: start; }
  @media (max-width: 700px) { .ds-summary-row { grid-template-columns: minmax(0, 1fr); } }
  .ds-smart-summary { font-size: 12.5px; color: var(--ink-soft); margin: 8px 0 12px; line-height: 1.5; }
  .ds-progress-line { font-size: 11px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 4px; }
  .ds-progress-stats { display: flex; gap: 14px; flex-wrap: wrap; font-size: 11px; color: var(--ink-soft); margin-top: 6px; }
  .ds-nextup-empty { color: var(--green); font-size: 13px; padding: 10px 0; }
  .ds-nextup-body { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
  .ds-nextup-icon { font-size: 22px; }
  .ds-nextup-title { font-size: 14px; color: var(--ink); }
  .ds-nextup-time { font-size: 11px; color: var(--ink-soft); }
  .ds-nextup-eta { font-size: 11px; color: var(--gold); margin-top: 2px; }
  .ds-priority-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
  .ds-priority-num { color: var(--cyan-dim); font-size: 12px; width: 16px; flex-shrink: 0; }
  .ds-priority-input { flex: 1; }
  .ds-view-toggle { display: flex; gap: 6px; }
  .ds-add-btn { margin: 4px 0 16px; }
  .ds-timeline-wrap { position: relative; }
  .ds-timeline-grid { position: relative; display: flex; }
  .ds-hour-rows { width: 56px; flex-shrink: 0; }
  .ds-hour-row { border-top: 1px solid var(--border-soft); box-sizing: border-box; padding-top: 2px; }
  .ds-hour-label { font-size: 10px; color: var(--ink-faint); letter-spacing: 0.04em; }
  .ds-timeline-track { position: relative; flex: 1; border-left: 1px solid var(--border-soft); background-image: repeating-linear-gradient(to bottom, transparent, transparent 59px, var(--border-soft) 60px); }
  .ds-item-card { position: absolute; box-sizing: border-box; background: var(--panel-raised); border: 1px solid var(--border); border-left: 3px solid var(--cyan); border-radius: 4px; padding: 5px 8px; overflow: hidden; cursor: pointer; transition: box-shadow 0.15s ease; }
  .ds-item-card:hover { box-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.25); }
  .ds-item-card.ds-item-completed { opacity: 0.55; }
  .ds-item-card.ds-item-inprogress { box-shadow: 0 0 0 1px var(--gold); }
  .ds-item-time { font-size: 9.5px; color: var(--ink-faint); }
  .ds-item-title { font-size: 12px; color: var(--ink); margin-top: 2px; }
  .ds-item-completed .ds-item-title { text-decoration: line-through; color: var(--ink-faint); }
  .ds-item-status { font-size: 9.5px; color: var(--green); margin-top: 2px; }
  .ds-current-time-line { position: absolute; left: 0; right: 0; height: 0; border-top: 2px solid var(--red); z-index: 5; }
  .ds-current-time-dot { position: absolute; left: -5px; top: -5px; width: 10px; height: 10px; border-radius: 50%; background: var(--red); box-shadow: 0 0 6px var(--red); }
  .ds-current-time-label { position: absolute; left: 10px; top: -9px; font-size: 10px; color: var(--red); background: var(--bg); padding: 0 4px; }
  .ds-timeline-empty { margin-top: 16px; }
  .ds-list-wrap { display: flex; flex-direction: column; gap: 4px; }
  .ds-list-group-label { font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--cyan-dim); margin: 12px 0 6px; }
  .ds-list-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--border-soft); border-radius: 4px; cursor: pointer; background: var(--panel-raised); }
  .ds-list-item:hover { border-color: var(--border); }
  .ds-list-status { font-size: 13px; }
  .ds-list-cat-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
  .ds-list-time { font-size: 11px; color: var(--ink-soft); width: 78px; flex-shrink: 0; }
  .ds-list-title { font-size: 12.5px; color: var(--ink); flex: 1; }
  .ds-field-label { display: block; font-size: 10.5px; color: var(--ink-soft); margin: 12px 0 5px; letter-spacing: 0.02em; text-transform: uppercase; }
  .ds-field-label:first-child { margin-top: 0; }
  .ds-optional { color: var(--ink-faint); text-transform: none; letter-spacing: 0; }
  .ds-field-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }
  @media (max-width: 560px) { .ds-field-row { grid-template-columns: minmax(0, 1fr); } }
  .ds-custom-days { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
  .ds-day-chip { display: flex; flex-direction: column; align-items: center; gap: 3px; font-size: 9.5px; color: var(--ink-soft); background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 6px 8px; cursor: pointer; }
  .ds-status-toggle { display: flex; gap: 4px; }
  .ds-status-toggle button.active { color: var(--cyan-bright); border-color: var(--cyan); }
  #dsOpenSourceRow { margin-top: 14px; }
  /* ---------- Daily Schedule: Daily/Weekly/Monthly/Yearly view switcher ---------- */
  .ds-mainview-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
  .ds-main-view-panel { display: none; }
  .ds-main-view-panel.active { display: block; }
  .ds-nextup-row { margin-bottom: 10px; }
  .ds-nextup-row:last-child { margin-bottom: 0; }
  .ds-nextup-row-label { font-size: 10.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }
  /* ---------- Daily Schedule: Weekly view ---------- */
  .ds-weekly-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; align-items: start; }
  .ds-weekly-day-col { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 8px 6px; min-height: 90px; }
  .ds-weekly-day-today { border-color: var(--cyan); box-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.2); }
  .ds-weekly-day-head { text-align: center; cursor: pointer; padding-bottom: 6px; border-bottom: 1px solid var(--border-soft); margin-bottom: 6px; }
  .ds-weekly-day-name { font-size: 9.5px; letter-spacing: 0.08em; color: var(--ink-soft); }
  .ds-weekly-day-num { font-size: 14px; color: var(--ink); margin-top: 2px; }
  .ds-weekly-chip-stack { display: flex; flex-direction: column; gap: 4px; }
  .ds-weekly-empty { font-size: 10.5px; color: var(--ink-faint); text-align: center; padding: 6px 0; }
  .ds-chip { border-left: 2px solid var(--cyan); background: var(--panel); border-radius: 3px; padding: 4px 6px; cursor: pointer; overflow: hidden; }
  .ds-chip-time { display: block; font-size: 9px; color: var(--ink-faint); }
  .ds-chip-title { display: block; font-size: 10.5px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* ---------- Daily Schedule: Monthly view ---------- */
  .ds-month-weekday-labels { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin-bottom: 6px; }
  .ds-month-weekday-label { font-size: 9.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); text-align: center; }
  .ds-month-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
  .ds-month-cell { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 6px; min-height: 78px; min-width: 0; cursor: pointer; transition: border-color 0.15s ease; box-sizing: border-box; overflow: hidden; }
  .ds-month-cell:hover { border-color: var(--border); }
  .ds-month-cell-outside { opacity: 0.35; }
  .ds-month-cell-today { border-color: var(--cyan); box-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.2); }
  .ds-month-cell-date { font-size: 11px; color: var(--ink-soft); margin-bottom: 4px; }
  .ds-month-cell-events { display: flex; flex-direction: column; gap: 2px; }
  .ds-month-event-pill { font-size: 9px; border-left: 2px solid var(--cyan); background: var(--panel); border-radius: 2px; padding: 1px 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .ds-month-more { font-size: 9px; color: var(--cyan-dim); padding-left: 2px; }
  /* ---------- Daily Schedule: Yearly view ---------- */
  .ds-routines-summary-panel { margin-bottom: 16px; }
  .ds-routine-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border-soft); font-size: 12px; flex-wrap: wrap; }
  .ds-routine-row:last-child { border-bottom: none; }
  .ds-routine-icon { font-size: 15px; }
  .ds-routine-title { color: var(--ink); flex: 1; min-width: 100px; }
  .ds-routine-time { color: var(--ink-soft); font-family: var(--mono); font-size: 11px; }
  .ds-routine-freq { color: var(--cyan-dim); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em; }
  .ds-year-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-top: 16px; }
  .ds-year-month-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 5px; padding: 12px; cursor: pointer; min-height: 90px; transition: border-color 0.15s ease, transform 0.15s ease; box-sizing: border-box; }
  .ds-year-month-card:hover { border-color: var(--border); transform: translateY(-2px); }
  .ds-year-month-current { border-color: var(--cyan); box-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.2); }
  .ds-year-month-title { font-size: 11.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--cyan-bright); margin-bottom: 8px; }
  .ds-year-month-event { font-size: 10.5px; color: var(--ink-soft); margin-bottom: 3px; display: flex; justify-content: space-between; gap: 6px; }
  .ds-year-month-event-date { color: var(--ink-faint); flex-shrink: 0; }
  .ds-year-month-empty { font-size: 10px; color: var(--ink-faint); }
  @media (max-width: 900px) {
    .ds-year-grid { grid-template-columns: repeat(2, 1fr); }
  }
  @media (max-width: 700px) {
    .ds-header { flex-direction: column; align-items: flex-start; }
    .ds-item-card { position: static !important; width: 100% !important; left: 0 !important; top: auto !important; height: auto !important; margin-bottom: 8px; }
    .ds-timeline-track { background-image: none; border-left: none; }
    .ds-hour-rows { display: none; }
    .ds-timeline-grid { display: block; height: auto !important; }
    .ds-timeline-track { height: auto !important; }
    .ds-current-time-line { display: none; }
    .ds-add-btn { width: 100%; }
    .ds-weekly-grid { grid-template-columns: minmax(0, 1fr); }
    .ds-year-grid { grid-template-columns: minmax(0, 1fr); }
  }
  @media (max-width: 640px) {
    .ds-month-grid, .ds-month-weekday-labels { gap: 2px; }
    .ds-month-cell { min-height: 54px; padding: 4px; }
    .ds-month-cell-date { font-size: 9.5px; }
    .ds-month-event-pill { font-size: 8px; }
  }
  .life-city-grid { grid-template-columns: repeat(3, 1fr); }
  /* Tablet: 2 columns instead of jumping straight from 3 to 1. */
  @media (min-width: 641px) and (max-width: 980px) { .life-city-grid { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 640px) { .life-city-grid { grid-template-columns: minmax(0, 1fr); } }
  .life-city-card { display: flex; flex-direction: column; }
  .life-entry-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 10px 12px; margin-bottom: 8px; transition: border-color 0.15s ease; }
  .life-entry-card:hover { border-color: var(--border); }
  .life-entry-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); flex-wrap: wrap; margin-bottom: 6px; }
  .life-entry-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 11.5px; color: var(--ink-soft); }
  .life-entry-meta input, .life-entry-meta select { font-size: 11px; padding: 4px 6px; }
  .life-entry-notes { margin-top: 6px; font-size: 11.5px; color: var(--ink-faint); line-height: 1.5; }
  .life-entry-card textarea { width: 100%; margin-top: 6px; font-size: 11.5px; }
  .life-place-list { max-height: 280px; overflow-y: auto; margin-bottom: 4px; padding-right: 2px; }
  .rank-row-list { display: flex; flex-direction: column; gap: 8px; }
  .rank-row { display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--ink-soft); flex-wrap: wrap; }
  .rank-row .medal { font-size: 18px; }
  .rank-row strong { color: var(--ink); }
  .rank-row select { flex: 1; min-width: 160px; }
  .rank-detail { color: var(--gold); }
  .memory-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; }
  .memory-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 6px; overflow: hidden; transition: transform 0.15s ease, box-shadow 0.15s ease; }
  .memory-card:hover { transform: translateY(-3px); box-shadow: 0 6px 18px rgba(var(--shadow-rgb),0.35); }
  .memory-photo { width: 100%; height: 130px; background-size: cover; background-position: center; display: flex; align-items: center; justify-content: center; font-size: 34px; background-color: var(--panel); }
  .memory-body { padding: 9px 11px; }
  .memory-caption { font-size: 12px; color: var(--ink); margin-bottom: 4px; }
  .memory-meta { font-size: 10px; color: var(--ink-faint); display: flex; justify-content: space-between; gap: 6px; align-items: center; margin-top: 3px; }
  .fav-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
  .fav-card { background: linear-gradient(160deg, var(--panel-raised), var(--panel)); border: 1px solid var(--border); border-radius: 6px; padding: 14px 16px; transition: box-shadow 0.15s ease, transform 0.15s ease; }
  .fav-card:hover { box-shadow: 0 0 14px rgba(var(--cyan-glow-rgb), 0.2); transform: translateY(-2px); }
  .fav-card-label { font-size: 10.5px; letter-spacing: 0.08em; color: var(--cyan-dim); text-transform: uppercase; margin-bottom: 8px; }
  .fav-card input { width: 100%; background: transparent; border: none; border-bottom: 1px solid var(--border-soft); color: var(--ink); font-size: 13.5px; padding: 4px 0; }
  .fav-card input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; border-bottom-color: var(--cyan); }
  .pr-badge-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; margin-bottom: 14px; }
  .pr-badge { background: var(--panel-raised); border: 1px solid var(--gold); border-radius: 4px; padding: 12px 14px; text-align: center; position: relative; }
  .pr-badge-label { font-size: 10px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 6px; display: flex; justify-content: center; }
  .pr-badge-value { font-size: 18px; color: var(--gold); font-weight: 700; display: flex; align-items: baseline; justify-content: center; gap: 4px; }
  .wrapped-stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px,1fr)); gap: 10px; margin-bottom: 16px; }
  .wrapped-stat { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 12px; font-size: 13px; display: flex; gap: 8px; align-items: center; }
  .wrapped-stat-icon { font-size: 18px; }
  .wrapped-highlights { display: flex; flex-direction: column; gap: 2px; }
  .wrapped-highlight-row { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; color: var(--ink-soft); border-bottom: 1px solid var(--border-soft); padding: 7px 0; flex-wrap: wrap; }
  .wrapped-highlight-row strong { color: var(--cyan-bright); }
  .anime-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; margin-top: 4px; }
  .anime-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 6px; overflow: hidden; transition: transform 0.15s ease; }
  .anime-card:hover { transform: translateY(-2px); }
  .anime-cover { width: 100%; height: 140px; background-size: cover; background-position: center; background-color: var(--panel); display: flex; align-items: center; justify-content: center; font-size: 36px; }
  .anime-card-body { padding: 9px 11px; }
  .movie-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; margin-top: 4px; }
  .movie-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 6px; overflow: hidden; transition: transform 0.15s ease; }
  .movie-card:hover { transform: translateY(-2px); }
  .movie-cover { width: 100%; height: 140px; background-size: cover; background-position: center; background-color: var(--panel); display: flex; align-items: center; justify-content: center; font-size: 36px; }
  .movie-card-body { padding: 9px 11px; }
  .cuisine-chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
  /* ---------- Fitness Dashboard ---------- */
  .fit-modal-overlay { position: fixed; inset: 0; background: rgba(var(--overlay-rgb), 0.72); display: flex; align-items: center; justify-content: center; z-index: 500; padding: 20px; }
  .fit-modal { background: var(--panel); border: 1px solid var(--border); border-radius: 6px; width: 100%; max-width: 640px; max-height: 88vh; display: flex; flex-direction: column; box-shadow: 0 10px 40px rgba(var(--shadow-rgb),0.5); }
  /* .fit-modal-head/body/foot and .trav-modal-head/body/foot (defined below) share one identical ruleset each. */
  .fit-modal-head, .trav-modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--border-soft); flex-shrink: 0; }
  .fit-modal-body, .trav-modal-body { padding: 16px 18px; overflow-y: auto; flex: 1; }
  .fit-modal-foot, .trav-modal-foot { display: flex; align-items: center; justify-content: flex-end; gap: 14px; padding: 12px 18px; border-top: 1px solid var(--border-soft); flex-shrink: 0; }
  .act-cat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
  .act-cat-chip { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 10px 6px; text-align: center; font-size: 10.5px; color: var(--ink-soft); cursor: pointer; font-family: var(--mono); line-height: 1.4; }
  .act-cat-chip .act-cat-emoji { font-size: 18px; display: block; margin-bottom: 4px; }
  .act-cat-chip.active { border-color: var(--cyan-bright); color: var(--cyan-bright); background: rgba(var(--cyan-glow-rgb), 0.08); }
  /* ---------- Fitness: "Recent" preview row — grid stretch so all three cards share the tallest card's height ---------- */
  .fit-recent-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-bottom: 18px; align-items: stretch; }
  .fit-recent-row > .progress-section { margin-bottom: 0; height: 100%; display: flex; flex-direction: column; }
  .fit-recent-row > .progress-section > .muted-link { margin-top: auto; align-self: flex-start; }
  /* 3 cards intentionally don't drop to a 2-column tier: a 2-col wrap leaves one card alone on its own
     row, and CSS grid can only stretch items to match within the same row — defeating the equal-height
     requirement above. Going straight from 3 columns to a single stacked column keeps every card's
     height consistent at every width. */
  /* Held at 3 columns down through tablet widths — going straight from 3 to 1
     (skipping a 2-column tier) is what keeps every card's stretched height
     consistent, per the equal-height note above; only true mobile collapses. */
  @media (max-width: 640px) { .fit-recent-row { grid-template-columns: minmax(0, 1fr); } }
  /* ---------- Fitness: Activity Calendar + Exercise Consistency row — side-by-side "when did I exercise"
     (calendar) and "how consistently" (ring) cards. Calendar keeps its own grid/cell classes, never
     shared with .cal-grid/.cal-cell (Habit Tracker) or .kpi-grid. Sized to roughly half the footprint of
     the original single-column calendar: smaller cells, tighter gaps/padding, no oversized headings. ---------- */
  .act-cal-row, .fit-week-row { display: grid; grid-template-columns: minmax(0, 0.78fr) minmax(0, 1fr); gap: 14px; margin-bottom: 18px; align-items: stretch; }
  /* Sprint 2C-2 Part 9/10: Weekly Training Calendar panel is hidden, leaving only Weekly Goal
     Progress in this row — give it the full width instead of a half-empty grid. */
  .fit-week-row--single { grid-template-columns: 1fr; }
  .act-cal-row > .progress-section, .fit-week-row > .progress-section { margin-bottom: 0; }
  /* Collapse only on true mobile widths — tablet keeps the calendar and its
     companion card side by side (there's comfortably enough room by 641px). */
  @media (max-width: 640px) {
    .act-cal-row, .fit-week-row { grid-template-columns: minmax(0, 1fr); }
    /* 18px cells were never tappable. Mobile stays stacked (Part 15: do not improve desktop by
       making mobile worse) and simply gets cells you can actually hit. */
    .act-cal-cell { min-height: 40px; font-size: 11px; }
    .act-cal-grid { max-width: none; }
  }
  /* Calendar and Consistency card share a row height (align-items:stretch above), but the calendar's own
     content varies a lot across Daily/Weekly/Monthly/Yearly (a 7-day strip vs a 12-month grid) while the
     ring card stays roughly constant — so on short-content views the calendar would otherwise be stretched
     with a big blank gap below its content. Making the panel a flex column and letting its body grow +
     center vertically means any extra stretched height reads as breathing room around the content, not a
     dead gap after it — same fix mirrored in the Consistency card via its existing flex body. */
  .act-cal-panel { padding: 12px 14px 14px; display: flex; flex-direction: column; }
  .act-cal-panel > #fitActCalBody { flex: 1; display: flex; flex-direction: column; justify-content: center; }
  .act-cal-panel .module-head { margin-bottom: 6px; }
  .act-cal-panel .module-title { font-size: 11px; }
  .act-cal-nav-row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
  .act-cal-nav-row .cal-nav-title { flex: 1; text-align: center; font-size: 11px; }
  .act-cal-today-btn { flex-shrink: 0; font-size: 10.5px; }
  .act-cal-stats-row { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
  .act-cal-stat-chip { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 3px; padding: 2px 6px; font-size: 9.5px; color: var(--ink-soft); white-space: nowrap; }
  .act-cal-legend { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; font-size: 9px; color: var(--ink-soft); }
  .act-cal-legend-item { display: flex; align-items: center; gap: 3px; }
  .act-cal-legend-dot { width: 5px; height: 5px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
  /* ===== REAL-WORLD USAGE POLISH V1.1 (Parts 14/15) — THE ACTIVITY CALENDAR "SQUISHED" FIX.
     MEASURED FIRST, because the obvious answer was wrong. At 1920 and 1366 the row splits
     563px/563px and the day cells came out 74px WIDE by 18px TALL — a 4:1 letterbox. Widening
     the calendar column, which is what "make it bigger" would normally mean, would have made
     each cell *wider still* against an 18px height and left it looking more squashed, not less.
     Mobile cells measured 46x18 — better proportioned than desktop, which is the tell.

     So the fix is cell GEOMETRY, not column ratio:
       - the grid gets a max-width and centres, so cells stop stretching to fill 533px
       - cells get a real height (18px -> 38px desktop, 40px on touch, where 18px was also
         an unusable tap target)
     Result: roughly 64x38 on desktop instead of 74x18. The calendar column is nudged to ~56%
     as a secondary adjustment, which the max-width then prevents from re-stretching the cells. */
  .act-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; max-width: 460px; margin: 0 auto; width: 100%; }
  .act-cal-weekday-label { font-size: 9px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-faint); text-align: center; padding-bottom: 3px; }
  .act-cal-cell { min-height: 38px; border-radius: 3px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; font-size: 10.5px; color: var(--ink); cursor: pointer; border: 1px solid var(--border-soft); background: var(--panel-raised); padding: 2px 0; }
  .act-cal-cell.empty { visibility: hidden; cursor: default; }
  .act-cal-cell.future { color: var(--ink-faint); border-style: dashed; cursor: default; background: transparent; }
  .act-cal-cell.is-today { outline: 2px solid var(--cyan-bright); outline-offset: 1px; }
  .act-cal-cell.selected { border-color: var(--cyan-bright); box-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.5); }
  .act-cal-dots { display: flex; gap: 1px; flex-wrap: wrap; justify-content: center; max-width: 100%; }
  .act-cal-dot { width: 3px; height: 3px; border-radius: 50%; display: inline-block; }
  .act-cal-more { font-size: 6px; line-height: 3px; color: var(--ink-faint); font-family: var(--mono); }
  .act-cal-day-detail { margin-top: 6px; padding: 6px 8px; border: 1px solid var(--border-soft); border-radius: 4px; background: var(--panel-raised); font-size: 11px; }
  .act-cal-week-strip { display: flex; gap: 4px; }
  .act-cal-week-day { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 5px 2px; border-radius: 4px; border: 1px solid var(--border-soft); background: var(--panel-raised); cursor: pointer; font-size: 8.5px; color: var(--ink-soft); min-width: 0; }
  .act-cal-week-day.is-today { outline: 2px solid var(--cyan-bright); outline-offset: 1px; }
  .act-cal-week-day.selected { border-color: var(--cyan-bright); }
  .act-cal-week-day.future { opacity: 0.4; cursor: default; }
  .act-cal-week-label { text-transform: uppercase; letter-spacing: 0.04em; }
  .act-cal-week-num { font-size: 11px; color: var(--ink); font-weight: 600; }
  .act-cal-dash { color: var(--ink-faint); font-size: 10px; }
  .act-cal-year-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
  @media (max-width: 700px) { .act-cal-year-grid { grid-template-columns: repeat(2, 1fr); } }
  .act-cal-year-month { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 5px 7px; font-size: 9px; color: var(--ink-soft); }
  .act-cal-year-month.future { opacity: 0.4; }
  .act-cal-year-month-label { display: block; margin-bottom: 3px; text-transform: uppercase; letter-spacing: 0.04em; }
  .act-cal-year-bar-track { height: 4px; background: var(--border-soft); border-radius: 3px; overflow: hidden; }
  .act-cal-year-bar-fill { height: 100%; border-radius: 3px; }
  /* ---------- Fitness: Exercise Consistency card — ring is the dominant visual, breakdown stays secondary ---------- */
  /* Fitness V2 (Part 11): the compact Exercise Consistency row that replaced the ~300px ring
     panel. No fixed heights, no margin-top:auto stretching, no centred dead space. */
  .fit-consistency-panel { padding: 12px 14px 14px; }
  .fit-consistency-compact { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
  .fit-consistency-main { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
  .fit-consistency-fraction { font-size: 15px; color: var(--ink); font-family: var(--mono); }
  .fit-consistency-fraction span { font-size: 11px; color: var(--ink-faint); }
  .fit-consistency-dots { display: flex; gap: 5px; align-items: center; flex-wrap: wrap; }
  .fit-dot { width: 11px; height: 11px; border-radius: 50%; border: 1px solid var(--border); background: var(--panel); flex-shrink: 0; }
  .fit-dot-on { background: var(--cyan-bright); border-color: var(--cyan-bright); }
  .fit-dot-extra { font-size: 10px; color: var(--cyan-dim); margin-left: 2px; }
  .fit-consistency-minibar { width: 180px; max-width: 100%; height: 8px; border-radius: 4px; background: var(--panel); border: 1px solid var(--border-soft); overflow: hidden; }
  .fit-consistency-minibar-fill { height: 100%; background: var(--cyan-bright); }
  .fit-consistency-pct-big { font-size: 26px; font-weight: 700; color: var(--ink); font-family: var(--mono); line-height: 1; white-space: nowrap; }
  .fit-consistency-pct-big span { font-size: 10px; color: var(--ink-faint); font-weight: 400; }
  .fit-consistency-inline-meta { font-size: 10.5px; color: var(--ink-faint); margin-top: 8px; }
  /* Fitness V2.1 (Parts 2/6/26/27): the consistency calendar. Constrained max-width on purpose —
     Part 27 wants a compact calendar, not a wall-sized one stretched across a 1920px screen. */
  .fit-cal-head { display: flex; align-items: flex-start; gap: 18px; flex-wrap: wrap; margin-bottom: 8px; }
  .fit-cal-metric { min-width: 0; }
  .fit-cal-metric-label { font-size: 9px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.07em; margin-bottom: 2px; }
  .fit-cal-metric-value { font-size: 19px; color: var(--ink); font-family: var(--mono); line-height: 1.15; }
  .fit-cal-metric-value span { font-size: 10.5px; color: var(--ink-faint); }
  .fit-cal-metric-sub { font-size: 10px; color: var(--cyan-dim); margin-top: 2px; }
  .fit-cal-viewtoggle { margin-left: auto; align-self: center; }
  .fit-cal-nav { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 2px 0 6px; max-width: 288px; }
  .fit-cal-nav-title { font-size: 11px; color: var(--cyan-bright); text-transform: uppercase; letter-spacing: 0.08em; min-width: 130px; text-align: center; }
  .fit-cal-nav-btn { background: none; border: none; color: var(--ink-soft); font-size: 15px; cursor: pointer; min-width: 32px; min-height: 32px; line-height: 1; }
  .fit-cal-nav-btn-off { opacity: 0.25; cursor: default; }
  .fit-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; max-width: 288px; }
  .fit-cal-dow { font-size: 8.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.04em; text-align: center; padding-bottom: 2px; }
  .fit-cal-day { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; font-size: 10.5px; font-family: var(--mono); color: var(--ink-soft); border: 1px solid var(--border-soft); border-radius: 50%; background: var(--panel); }
  .fit-cal-day-outside { opacity: 0.18; border-color: transparent; }
  .fit-cal-day-future { opacity: 0.32; }
  /* Active days use the existing Mighty Life OS accent, not the reference screenshot's yellow. */
  .fit-cal-day-active { background: var(--cyan-bright); border-color: var(--cyan-bright); color: var(--on-accent); font-weight: 700; cursor: pointer; }
  .fit-cal-day-today { box-shadow: 0 0 0 2px var(--gold); }
  .fit-cal-foot { font-size: 10.5px; color: var(--ink-faint); margin-top: 6px; }
  .fit-cal-empty { font-size: 11.5px; color: var(--ink-soft); padding: 10px 0 4px; }
  .fit-year-grid { display: flex; align-items: flex-end; gap: 6px; max-width: 420px; height: 78px; }
  .fit-year-col { flex: 1; display: flex; flex-direction: column; align-items: center; height: 100%; min-width: 0; }
  .fit-year-bar { flex: 1; width: 100%; display: flex; align-items: flex-end; background: var(--panel); border: 1px solid var(--border-soft); border-radius: 2px; overflow: hidden; }
  .fit-year-bar-fill { width: 100%; background: var(--cyan-dim); min-height: 2px; }
  .fit-year-bar-best { background: var(--cyan-bright); }
  .fit-year-bar-future { background: transparent; }
  .fit-year-label { font-size: 7.5px; color: var(--ink-faint); margin-top: 3px; letter-spacing: 0.02em; }
  @media (max-width: 480px) {
    .fit-cal-grid, .fit-cal-nav { max-width: 100%; }
    .fit-cal-head { gap: 12px; }
    .fit-cal-viewtoggle { margin-left: 0; }
    .fit-year-grid { max-width: 100%; gap: 3px; }
    .fit-cal-nav-btn { min-width: 44px; min-height: 44px; }
  }
  /* Fitness V2 (Part 16): insights as a short scannable list, not a bulleted paragraph block. */
  .fit-insight-list { display: flex; flex-direction: column; gap: 7px; }
  .fit-insight-row { display: flex; gap: 8px; align-items: flex-start; font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; }
  .fit-insight-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--cyan-bright); margin-top: 7px; flex-shrink: 0; }
  /* Fitness Score V2 explanation + honest empty state (Parts 7/9). */
  .fit-score-band { font-size: 10.5px; color: var(--cyan-dim); letter-spacing: 0.04em; margin-top: 2px; }
  .fit-score-explain-btn { min-height: 32px; font-size: 11px; margin-top: 6px; }
  .fit-score-explain { margin-top: 4px; }
  .fit-score-rows { display: flex; flex-direction: column; gap: 9px; }
  .fit-score-row-head { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--ink-soft); margin-bottom: 3px; }
  .fit-score-row-points { color: var(--cyan-bright); font-weight: 600; font-family: var(--mono); }
  .fit-score-row-detail { font-size: 9.5px; color: var(--ink-faint); margin-top: 2px; }
  .fit-score-total { display: flex; justify-content: space-between; font-size: 12px; color: var(--ink); border-top: 1px solid var(--border-soft); margin-top: 10px; padding-top: 8px; font-family: var(--mono); }
  .fit-score-empty { text-align: center; padding: 18px 8px; }
  .fit-score-empty-title { font-size: 14px; color: var(--ink); margin-bottom: 6px; }
  .fit-score-empty-sub { font-size: 11.5px; color: var(--ink-faint); line-height: 1.6; max-width: 420px; margin: 0 auto; }
  /* Core Polish sprint (Part A): Today's Progress lays its four daily-target bars out two-up
     instead of four full-width stacked rows. Collapses to one column on narrow screens so the
     labels and "12 / 20" readouts never squeeze. */
  /* Fitness Activity V2: the "+ More details" disclosure inside the canonical activity modal, and
     comfortable tap targets on the Today / Recent Activity rows that open it. */
  /* ===== Fitness V2.2: Gym Day Templates ===== */
  .fit-tpl-row { min-height: 44px; }
  .fit-tpl-row .acct-cat { color: var(--cyan-dim); }
  .fit-tpl-picker { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 8px 0 4px; }
  @media (max-width: 560px) { .fit-tpl-picker { grid-template-columns: minmax(0, 1fr); } }
  .fit-tpl-choice {
    display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
    min-height: 56px; padding: 11px 13px; text-align: left; cursor: pointer;
    background: var(--panel); border: 1px solid var(--border); border-radius: 0;
    color: var(--ink); font-family: inherit;
  }
  .fit-tpl-choice:hover, .fit-tpl-choice:focus-visible { border-color: var(--cyan); }
  .fit-tpl-choice-name { font-size: 13px; color: var(--ink); }
  .fit-tpl-choice-meta { font-size: 10.5px; color: var(--ink-faint); }
  .fit-tpl-blank { display: block; min-height: 40px; margin-top: 4px; font-size: 12px; }
  .fit-tpl-ex { border: 1px solid var(--border-soft); padding: 10px 12px; margin-top: 10px; }
  .fit-tpl-ex-head { display: flex; align-items: center; gap: 8px; }
  .fit-tpl-ex-num { font-family: var(--mono); font-size: 11px; color: var(--cyan-dim); min-width: 14px; }
  .fit-tpl-ex-select { flex: 1; min-width: 0; }
  .fit-tpl-ex-actions { display: flex; gap: 4px; flex-shrink: 0; }
  /* Part 10: reorder controls at a real tap size. The whole-OS audit flagged 12x14px arrows
     elsewhere in the app; these are 40px, 44px on touch widths, and disabled at the ends. */
  .fit-tpl-move {
    min-width: 40px; min-height: 40px; background: none; cursor: pointer;
    border: 1px solid var(--border-soft); color: var(--ink-soft); font-size: 14px; line-height: 1;
  }
  .fit-tpl-move:hover:not(:disabled) { color: var(--cyan-bright); border-color: var(--cyan); }
  .fit-tpl-move:disabled { opacity: 0.25; cursor: default; }
  .fit-tpl-remove { color: var(--red); }
  .tpl-diff-from { color: var(--ink-faint); text-decoration: line-through; }
  .tpl-diff-to { color: var(--cyan-bright); }
  @media (max-width: 640px) {
    .fit-tpl-move { min-width: 44px; min-height: 44px; }
    .fit-tpl-ex-head { flex-wrap: wrap; }
    .fit-tpl-ex-select { flex-basis: 100%; order: 2; }
    .fit-tpl-ex-actions { margin-left: auto; }
  }
  /* ===== Fitness V2.2: Today's Macros ===== */
  .fit-macro-rows { display: flex; flex-direction: column; gap: 9px; }
  .fit-macro-row-head { display: flex; justify-content: space-between; align-items: baseline; font-size: 11.5px; color: var(--ink-soft); margin-bottom: 3px; }
  .fit-macro-value { font-family: var(--mono); color: var(--ink); }
  .fit-macro-value .fit-macro-target { color: var(--ink-faint); font-size: 10.5px; }
  .fit-macro-unlogged { color: var(--ink-faint); font-size: 11px; font-style: normal; }
  .fit-macro-foot { font-size: 10.5px; color: var(--ink-faint); margin-top: 10px; }
  /* ===== V1.1 (Parts 7/8/9) — stacked macro rows beside ONE compact composition chart.
     The rows come first and take the larger share, because actual-vs-target is the primary
     information; the donut is supporting and is deliberately small. Below 700px the chart moves
     under the rows rather than squeezing them. */
  .fit-macro-split { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 20px; align-items: start; }
  .fit-macro-row { padding: 2px 0; }
  .fit-macro-label { letter-spacing: 0.06em; text-transform: uppercase; font-size: 10.5px; }
  .fit-macro-bar-line { display: flex; align-items: center; gap: 10px; }
  .fit-macro-bar-line .category-bar-track { flex: 1; min-width: 0; }
  .fit-macro-pct { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); min-width: 34px; text-align: right; }
  .fit-macro-chart-title { font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 6px; }
  .fit-macro-donut { max-width: 150px; margin: 0 auto; }
  .fit-macro-donut svg { width: 100%; height: auto; display: block; }
  .fit-macro-legend { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; font-size: 11px; color: var(--ink-soft); }
  .fit-macro-legend-row { display: flex; align-items: center; gap: 7px; }
  .fit-macro-legend-pct { margin-left: auto; font-family: var(--mono); color: var(--ink); }
  .fit-macro-swatch { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; }
  .fit-macro-chart-note { font-size: 9.5px; color: var(--ink-faint); line-height: 1.5; margin-top: 8px; }
  /* ===== V1.1 (Parts 10-13) — the optional target estimator. Presented as a quiet inline panel
     rather than a modal: it is a calculator the user opted into, not a step in a flow. */
  .macro-est-panel { margin-top: 16px; padding: 14px; border: 1px solid var(--border-soft); border-radius: var(--radius-md); background: var(--panel-raised); }
  .macro-est-head { font-size: 11.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink); margin-bottom: 8px; }
  .macro-est-preview { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border-soft); }
  .macro-est-preview-title { font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--cyan); margin-bottom: 8px; }
  .macro-est-preview-rows { display: flex; gap: 20px; flex-wrap: wrap; font-size: 12px; color: var(--ink-soft); }
  .macro-est-preview-rows > div { display: flex; flex-direction: column; gap: 2px; }
  .macro-est-preview-rows strong { font-family: var(--mono); font-size: 16px; color: var(--ink); font-weight: 600; }

  /* ===== LEARNING ACCOUNTABILITY V2 (Phase 3) ===== */
  .lrn-countdown { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--border-soft); }
  .lrn-count-label { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-soft); }
  .lrn-count-date { font-family: var(--mono); font-size: 13px; color: var(--ink); }
  .lrn-count-days { margin-left: auto; font-family: var(--mono); font-size: 18px; font-weight: 600; color: var(--cyan-bright); }
  .lrn-count-days.lrn-count-past { color: var(--ink-faint); font-size: 13px; }
  .lrn-count-empty { font-size: 11.5px; color: var(--ink-soft); padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--border-soft); }
  .lrn-acct-block { display: flex; flex-direction: column; gap: 12px; }
  .lrn-acct-row { display: flex; flex-direction: column; gap: 5px; }
  .lrn-acct-head { display: flex; justify-content: space-between; align-items: baseline; font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); }
  .lrn-acct-val { font-family: var(--mono); text-transform: none; letter-spacing: 0; color: var(--ink); font-size: 12px; }
  .lrn-acct-bar { display: flex; align-items: center; gap: 10px; }
  .lrn-acct-bar .category-bar-track { flex: 1; min-width: 0; }
  .lrn-acct-pct { font-family: var(--mono); font-size: 11px; color: var(--ink-soft); min-width: 34px; text-align: right; }
  .lrn-acct-days { display: flex; gap: 5px; flex-wrap: wrap; }
  .lrn-day-chip { font-size: 10px; font-family: var(--mono); padding: 3px 7px; border-radius: 3px; border: 1px solid var(--border-soft); color: var(--ink-faint); }
  .lrn-day-chip.met { color: var(--green); border-color: rgba(var(--green-rgb), 0.45); background: rgba(var(--green-rgb), 0.10); }
  .lrn-day-chip.missed { color: var(--ink-soft); border-color: var(--border-soft); }
  .lrn-day-chip.upcoming { color: var(--cyan-dim); }
  .lrn-day-picker { display: flex; gap: 6px; flex-wrap: wrap; }
  .lrn-day-toggle { font-family: var(--mono); font-size: 11px; padding: 8px 10px; min-height: 40px; min-width: 46px;
    border-radius: var(--radius-md); border: 1px solid var(--border-soft); background: var(--panel-raised);
    color: var(--ink-soft); cursor: pointer; }
  .lrn-day-toggle.active { color: var(--cyan-bright); border-color: var(--cyan); background: rgba(var(--cyan-glow-rgb), 0.12); }
  @media (max-width: 640px) { .lrn-day-toggle { min-height: 44px; } }
  .lrn-acct-plain { display: flex; gap: 22px; flex-wrap: wrap; font-size: 12px; color: var(--ink-soft); }
  .lrn-acct-plain strong { font-family: var(--mono); font-size: 17px; color: var(--ink); font-weight: 600; display: block; }
  .lrn-today { margin-top: 12px; padding: 8px 10px; border-radius: var(--radius-md); background: var(--panel-raised); border: 1px solid var(--border-soft); font-size: 11.5px; color: var(--ink-soft); display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  .lrn-today-done { color: var(--green); border-color: rgba(var(--green-rgb), 0.35); }
  .lrn-streak { margin-top: 10px; font-size: 11.5px; color: var(--ink-soft); }
  .lrn-insights { margin-top: 12px; display: flex; flex-direction: column; gap: 5px; }
  .lrn-insight { font-size: 11.5px; color: var(--cyan); line-height: 1.55; }
  .lrn-practice { margin-top: 10px; font-size: 11px; color: var(--ink-faint); font-family: var(--mono); }
  /* The study calendar reuses the Activity Calendar's cell system rather than a second one. */
  .lrn-cal-cell { position: relative; }
  .lrn-cal-studied { background: rgba(var(--cyan-glow-rgb), 0.30); border-color: var(--cyan-dim); color: var(--ink); }
  .lrn-cal-missed { border-style: dashed; border-color: rgba(var(--gold-rgb), 0.40); }
  .lrn-cal-today { outline: 1px solid var(--cyan); outline-offset: -1px; }
  #lrnStudyCalPanel .act-cal-grid { max-width: 420px; }
  @media (max-width: 640px) {
    .lrn-count-days { margin-left: 0; }
    #lrnStudyCalPanel .act-cal-grid { max-width: none; }
  }
  @media (max-width: 700px) {
    .fit-macro-split { grid-template-columns: minmax(0, 1fr); gap: 16px; }
    .fit-macro-donut { max-width: 132px; }
  }
  .fit-macro-day { min-height: 40px; }
  .fit-macro-day .acct-cat { font-family: var(--mono); color: var(--ink-soft); }
  @media (max-width: 640px) { .fit-macro-day { min-height: 44px; } }
  .act-more-btn { display: block; width: 100%; text-align: left; margin-top: 12px; min-height: 40px; font-size: 12px; }
  /* Fitness Activity V2 (Parts 4/23): the canonical "+ Log Activity" button measured 30px tall —
     under the 32px floor and well under the ~44px the brief asks for, on the single most frequent
     action in the whole Fitness domain. Scoped deliberately to Fitness's log buttons rather than
     changing the app-wide .btn: normalising every button in Mighty Life OS is a Visual Polish
     sprint decision (it is already logged as P1-3/P2 in the whole-OS audit), not something to
     slip in here. 40px on desktop, a full 44px on touch-sized screens.

     V1 VISUAL & UX POLISH SPRINT (Part 28): that app-wide rule now exists — see the TOUCH TARGET
     SYSTEM block near .btn — and it covers `.fin-header .btn` for every tab including this one.
     What remains here is only `#fitSubActivity .btn`, which is NOT inside a .fin-header and so
     is not reached by the shared rule. Fitness's measured sizes are unchanged (the shared rule
     produces the identical 40px/44px), which is what keeps the frozen Fitness suites green. */
  #fitSubActivity .btn { min-height: 40px; padding-top: 9px; padding-bottom: 9px; }
  @media (max-width: 640px) {
    #fitSubActivity .btn { min-height: 44px; width: 100%; }
  }
  .fit-today-row .acct-cat { color: var(--cyan-dim); }
  #fitTodayWorkoutBody .acct-row, #fitRecentActivityBody .acct-row { min-height: 40px; }
  @media (max-width: 640px) {
    /* Part 23: these rows ARE the edit affordance for every logged session, so on a phone they get
       the full 44px. Measured at 42-43px before this rule. */
    #fitTodayWorkoutBody .acct-row, #fitRecentActivityBody .acct-row { min-height: 44px; }
    #fitActivityFullBtn, #fitHistoryFullBtn { min-height: 44px !important; }
  }
  .fit-today-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 20px; }
  @media (max-width: 560px) { .fit-today-grid { grid-template-columns: minmax(0, 1fr); } }
  .fit-consistency-panel .module-head { margin-bottom: 6px; }
  .fit-consistency-panel .module-title { font-size: 11px; }
  /* Fitness V2 (Part 11): was a centred column that forced the old ring into the middle of a
     tall box with dead space either side. The compact row lays itself out now. */
  .fit-consistency-body { display: block; }
  .fit-consistency-ring-wrap { position: relative; width: 100px; height: 100px; margin: 2px 0 8px; flex-shrink: 0; }
  .fit-consistency-ring-wrap svg { width: 100%; height: 100%; transform: rotate(-90deg); }
  .fit-consistency-ring-track { fill: none; stroke: var(--border-soft); }
  .fit-consistency-ring-fill { fill: none; stroke: var(--cyan-bright); stroke-linecap: round; transition: stroke-dashoffset 0.4s ease; }
  .fit-consistency-ring-pct { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 21px; font-weight: 700; color: var(--ink); font-family: var(--mono); }
  .fit-consistency-sub { font-size: 10.5px; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2px; }
  .fit-consistency-days-line { font-size: 11.5px; color: var(--ink); margin-bottom: 6px; }
  .fit-consistency-metrics-row { display: flex; gap: 16px; justify-content: center; margin-bottom: 8px; }
  .fit-consistency-metric-value { font-size: 13px; color: var(--ink); font-weight: 600; font-family: var(--mono); }
  .fit-consistency-metric-label { font-size: 8.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.04em; }
  .fit-consistency-breakdown { width: 100%; margin-top: auto; text-align: left; }
  .fit-consistency-breakdown-label { font-size: 9px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 4px; }
  .fit-consistency-breakdown-row { display: flex; justify-content: space-between; align-items: center; font-size: 11px; color: var(--ink-soft); padding: 2px 0; }
  .fit-consistency-empty { font-size: 11.5px; color: var(--ink-soft); margin: 16px 0; }
  .fit-consistency-daily-status { font-size: 15px; font-weight: 700; margin: 4px 0 8px; }
  @media (max-width: 640px) {
    .fit-modal-overlay { padding: 0; align-items: flex-end; }
    .fit-modal { max-width: 100%; max-height: 94vh; border-radius: 6px 6px 0 0; }
    .act-cat-grid { grid-template-columns: repeat(3, 1fr); }
  }
  /* ---------- Fitness: Health & Recovery (smart display — only rendered when real data exists) ---------- */
  .fit-health-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; margin-top: 8px; }
  /* ---------- Travel Dashboard ---------- */
  .trav-nav-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
  .trav-stat-row { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; margin-bottom: 18px; }
  @media (max-width: 1100px) { .trav-stat-row { grid-template-columns: repeat(3, 1fr); } }
  @media (max-width: 640px) { .trav-stat-row { grid-template-columns: repeat(2, 1fr); } }
  .trav-stat-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 5px; padding: 14px 12px; text-align: center; }
  .trav-stat-icon { font-size: 20px; margin-bottom: 6px; }
  .trav-stat-value { font-size: 22px; font-weight: 700; color: var(--cyan-bright); font-family: var(--mono); }
  .trav-stat-label { font-size: 9.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; margin-top: 3px; }
  .trav-map-wrap { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
  .trav-map-pin { position: relative; background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 5px; padding: 12px 10px; text-align: center; transition: border-color 0.15s ease, transform 0.15s ease; }
  .trav-map-pin:hover { transform: translateY(-2px); border-color: var(--border); }
  .trav-map-pin.visited { border-color: rgba(var(--green-rgb), 0.4); }
  .trav-map-pin.upcoming { border-color: rgba(var(--gold-rgb), 0.5); }
  .trav-map-pin.favorite::after { content: '★'; position: absolute; top: 4px; right: 6px; color: var(--gold); font-size: 11px; }
  .trav-map-flag { font-size: 22px; margin-bottom: 4px; }
  .trav-map-name { font-size: 11.5px; color: var(--ink); font-weight: 600; }
  .trav-map-sub { font-size: 9.5px; color: var(--ink-faint); margin-top: 2px; }
  .trav-map-count { font-size: 9.5px; color: var(--cyan-bright); margin-top: 3px; font-family: var(--mono); }
  .trip-filter-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
  .trip-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
  .trip-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 6px; overflow: hidden; cursor: pointer; transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease; }
  .trip-card:hover { transform: translateY(-3px); box-shadow: 0 6px 18px rgba(var(--shadow-rgb),0.35); border-color: var(--border); }
  .trip-card-cover { width: 100%; height: 110px; background-size: cover; background-position: center; display: flex; align-items: center; justify-content: center; font-size: 38px; position: relative; }
  .trip-card-status { position: absolute; top: 8px; right: 8px; font-size: 9px; text-transform: uppercase; letter-spacing: 0.05em; padding: 3px 7px; border-radius: 3px; font-family: var(--mono); font-weight: 700; }
  /* Same look as .trip-card-status but without absolute positioning — for status badges sitting inline
     next to text (e.g. the Upcoming Trips list), where .trip-card-status would otherwise escape to the
     nearest positioned ancestor (the enclosing .panel) and land in the module's top-right corner. */
  .status-badge-inline { display: inline-block; font-size: 9px; text-transform: uppercase; letter-spacing: 0.05em; padding: 3px 7px; border-radius: 3px; font-family: var(--mono); font-weight: 700; vertical-align: middle; }
  .trip-card-body { padding: 11px 13px; }
  .trip-card-name { font-size: 13.5px; font-weight: 700; color: var(--ink); margin-bottom: 3px; }
  .trip-card-dest { font-size: 11px; color: var(--ink-soft); margin-bottom: 6px; }
  .trip-card-dates { font-size: 10px; color: var(--ink-faint); font-family: var(--mono); }
  .trip-card-countdown { font-size: 10.5px; color: var(--cyan-bright); font-family: var(--mono); margin-top: 6px; }
  /* Sprint 2C-2 Part 5 — QUICK ACCESS chips (Flight/Hotel/Itinerary) on each trip card. */
  .trip-card-quick { display: flex; gap: 6px; margin-top: 9px; flex-wrap: wrap; }
  .trip-quick-btn { background: var(--panel); border: 1px solid var(--border-soft); color: var(--ink-soft); font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.03em; padding: 4px 8px; border-radius: 3px; cursor: pointer; }
  .trip-quick-btn:hover { border-color: var(--cyan); color: var(--cyan-bright); }
  .status-badge-planning { background: rgba(var(--gold-rgb), 0.18); color: var(--gold); }
  .status-badge-upcoming { background: rgba(var(--cyan-glow-rgb), 0.18); color: var(--cyan-bright); }
  .status-badge-currently-traveling { background: rgba(var(--green-rgb), 0.22); color: var(--green); }
  .status-badge-completed { background: rgba(var(--muted-fill-rgb),0.18); color: var(--ink-soft); }
  .status-badge-cancelled { background: rgba(var(--red-rgb), 0.18); color: var(--red); }
  .trav-modal-overlay { position: fixed; inset: 0; background: rgba(var(--overlay-rgb), 0.78); display: flex; align-items: center; justify-content: center; z-index: 550; padding: 20px; }
  .trav-modal { background: var(--panel); border: 1px solid var(--border); border-radius: 6px; width: 100%; max-width: 780px; max-height: 90vh; display: flex; flex-direction: column; box-shadow: 0 10px 40px rgba(var(--shadow-rgb),0.5); }
  @media (max-width: 640px) {
    .trav-modal-overlay { padding: 0; align-items: flex-end; }
    .trav-modal { max-width: 100%; max-height: 94vh; border-radius: 6px 6px 0 0; }
  }
  .trav-modal-sub-nav { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
  .trav-modal-sub-btn { background: var(--panel-raised); border: 1px solid var(--border-soft); color: var(--ink-soft); font-family: var(--mono); font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; padding: 6px 10px; cursor: pointer; border-radius: 3px; }
  .trav-modal-sub-btn.active { color: var(--cyan-bright); border-color: var(--cyan); }
  .trav-modal-sub-pane { display: none; }
  .trav-modal-sub-pane.active { display: block; }
  .itin-day-group { margin-bottom: 16px; }
  .itin-day-head { font-size: 11.5px; color: var(--cyan-bright); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; margin-bottom: 8px; padding-bottom: 4px; border-bottom: 1px solid var(--border-soft); display: flex; justify-content: space-between; align-items: center; }
  .itin-item { display: flex; align-items: flex-start; gap: 10px; background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 9px 11px; margin-bottom: 6px; }
  .itin-item-time { font-family: var(--mono); font-size: 10.5px; color: var(--cyan-bright); min-width: 56px; padding-top: 1px; }
  .itin-item-body { flex: 1; }
  .itin-item-title { font-size: 12px; color: var(--ink); font-weight: 600; }
  .itin-item-sub { font-size: 10px; color: var(--ink-faint); margin-top: 2px; }
  .itin-item-actions { display: flex; flex-direction: column; gap: 1px; }
  .passport-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; margin-bottom: 8px; }
  .passport-badge { background: var(--panel-raised); border: 1px solid var(--gold); border-radius: 5px; padding: 12px 8px; text-align: center; }
  .passport-badge.locked { border-color: var(--border-soft); opacity: 0.45; }
  .passport-badge-flag { font-size: 24px; margin-bottom: 4px; }
  .passport-badge-name { font-size: 10.5px; color: var(--ink); font-weight: 600; }
  .passport-goal-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
  .wrapped-hero { background: linear-gradient(135deg, rgba(var(--cyan-glow-rgb), 0.14), rgba(var(--gold-rgb), 0.10)); border: 1px solid var(--border); border-radius: 8px; padding: 26px 20px; text-align: center; margin-bottom: 18px; }
  .wrapped-hero-year { font-family: var(--mono); font-size: 12px; color: var(--ink-faint); letter-spacing: 0.1em; text-transform: uppercase; }
  .wrapped-hero-headline { font-size: 26px; font-weight: 800; color: var(--cyan-bright); margin: 8px 0; }
  .wrapped-hero-sub { font-size: 12.5px; color: var(--ink-soft); }
  .wrapped-stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 18px; }
  @media (max-width: 900px) { .wrapped-stat-grid { grid-template-columns: repeat(2, 1fr); } }
  .wrapped-stat-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 6px; padding: 16px 14px; text-align: center; }
  .wrapped-stat-big { font-size: 28px; font-weight: 800; color: var(--gold); font-family: var(--mono); }
  .wrapped-stat-label-sm { font-size: 10px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; margin-top: 4px; }
  .trav-connect-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 6px; }
  .trav-connect-chip { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 8px 12px; font-size: 11px; color: var(--ink-soft); }
  .trav-connect-chip strong { color: var(--cyan-bright); }
  .trav-list-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 10px 12px; margin-bottom: 7px; }
  .trav-list-item-main { flex: 1; min-width: 0; }
  .trav-list-item-title { font-size: 12.5px; color: var(--ink); font-weight: 600; }
  .trav-list-item-sub { font-size: 10.5px; color: var(--ink-faint); margin-top: 2px; }
  .trav-list-item-actions { display: flex; gap: 8px; flex-shrink: 0; }
  /* ---- Command Center ---- */
  /* .cc-pulse-* (REMOVED V4.2.1): was renderLifePulse()'s markup only — that renderer wrote into
     #ccPulseGrid, which index.html hasn't had since the Life Command Center sub-tab was retired.
     No other element used these classes. */
  .cc-status-pill { font-size: 9px; letter-spacing: 0.06em; text-transform: uppercase; padding: 3px 7px; border-radius: 10px; border: 1px solid; white-space: nowrap; }
  .cc-status-green { color: var(--green); border-color: var(--green); background: rgba(var(--green-rgb), 0.08); }
  .cc-status-yellow { color: var(--gold); border-color: var(--gold); background: rgba(var(--gold-rgb), 0.08); }
  .cc-status-red { color: var(--red); border-color: var(--red); background: rgba(var(--red-rgb), 0.08); }
  .cc-quick-actions { display: flex; flex-wrap: wrap; gap: 10px; }
  .cc-quick-btn { background: var(--panel-raised); border: 1px solid var(--border); color: var(--cyan); padding: 10px 16px; border-radius: 3px; font-size: 12px; letter-spacing: 0.03em; font-family: var(--mono); cursor: pointer; transition: all 0.15s ease; display: flex; align-items: center; gap: 6px; }
  .cc-quick-btn:hover { border-color: var(--cyan-bright); color: var(--cyan-bright); background: var(--panel); transform: translateY(-1px); }
  .cc-dash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }
  .cc-dash-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-left: 3px solid var(--cyan-dim); border-radius: 4px; padding: 16px; display: flex; flex-direction: column; gap: 10px; transition: border-color 0.15s ease, transform 0.15s ease; }
  .cc-dash-card:hover { border-left-color: var(--cyan-bright); transform: translateY(-2px); }
  .cc-dash-card-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
  .cc-dash-card-title { font-size: 12.5px; letter-spacing: 0.05em; color: var(--ink); text-transform: uppercase; font-weight: 600; }
  .cc-dash-card-stats { display: flex; flex-direction: column; gap: 6px; font-size: 11.5px; color: var(--ink-soft); min-width: 0; }
  /* V1.1 (Part 4) — LONG LABELS MUST WRAP, NOT ESCAPE.
     Measured: "Curated Hotel Collection Credit (2026-12-31)" broke 153px outside its card at every
     viewport. Two causes, both classic flex traps, and both fixed in the LAYOUT rather than by
     shortening the canonical benefit name (which is real data the user needs to recognise):
       1. the value was `white-space: nowrap`, so it could never wrap however narrow the card got;
       2. flex children default to `min-width: auto`, which refuses to shrink below content width,
          so the row pushed straight through the card's edge instead of compressing.
     `overflow-wrap: anywhere` is used rather than `break-word` because these values contain long
     unbroken runs (dates, hyphenated names) that `break-word` alone will not split. */
  .cc-dash-stat-row { display: flex; justify-content: space-between; gap: 8px; min-width: 0; align-items: baseline; }
  .cc-dash-stat-label { min-width: 0; overflow-wrap: anywhere; }
  .cc-dash-stat-value { color: var(--ink); min-width: 0; text-align: right; overflow-wrap: anywhere; }
  /* The same protection for the other long-text surfaces Part 4 names — card benefits, module
     titles, navigation and action labels — so one long name anywhere cannot break a card. */
  .cc-dash-card, .cc-dash-card-head, .cc-dash-card-title { min-width: 0; }
  .cc-dash-card-title, .cc-dash-open-btn { overflow-wrap: anywhere; }
  .module-title, .module-head > div { min-width: 0; overflow-wrap: anywhere; }
  .cc-dash-open-btn { margin-top: 2px; align-self: flex-start; }
  .cc-highlight-row { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border-soft); cursor: pointer; transition: background 0.15s ease; }
  .cc-highlight-row:last-child { border-bottom: none; }
  .cc-highlight-row:hover { background: var(--panel-raised); }
  .cc-highlight-icon { font-size: 16px; flex-shrink: 0; width: 22px; text-align: center; }
  .cc-highlight-title { font-size: 12.5px; color: var(--ink); }
  .cc-highlight-meta { font-size: 10.5px; color: var(--ink-faint); margin-top: 2px; }
  .cc-focus-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border-soft); flex-wrap: wrap; }
  .cc-focus-row:last-child { border-bottom: none; }
  .cc-focus-icon { font-size: 15px; width: 20px; text-align: center; flex-shrink: 0; }
  .cc-focus-label { font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-faint); width: 84px; flex-shrink: 0; }
  .cc-focus-input { flex: 1; min-width: 160px; background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink); padding: 6px 9px; border-radius: 2px; font-size: 12px; font-family: var(--mono); }
  .cc-focus-input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  .cc-upcoming-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border-soft); cursor: pointer; }
  .cc-upcoming-row:last-child { border-bottom: none; }
  .cc-upcoming-row:hover { background: var(--panel-raised); }
  .cc-upcoming-count { font-size: 11px; color: var(--cyan-bright); font-weight: 600; white-space: nowrap; }
  .cc-insight-row { display: flex; gap: 9px; align-items: flex-start; padding: 7px 0; border-bottom: 1px solid var(--border-soft); font-size: 12.5px; color: var(--ink-soft); line-height: 1.5; }
  .cc-insight-row:last-child { border-bottom: none; }
  /* ---- Card Strategy styles (.cs- prefix). V4.1.2: the Credit Cards area was removed; .cs-section and .cs-collapse-btn are still shared by other Finance/Travel panels, the rest is inert. ---- */
  .cs-subtitle { font-size: 12px; color: var(--ink-faint); margin: -6px 0 16px; }
  .cs-snapshot-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 18px; }
  .cs-section { margin-bottom: 22px; }
  /* V1 VISUAL & UX POLISH SPRINT (Part 6): Credit Cards measured 11,167px of scroll across 17
     panels at 390x844 — by a wide margin the deepest screen in the OS, roughly thirteen phone
     screens to reach the bottom. Nine reference sections now start collapsed behind this
     control. Nothing was deleted and no second strategy engine was added: the same renderers
     write into the same containers, which are simply display:none until asked for.
     Sized as a real touch target (the "Clear Demo Data"-style 13px muted-link was itself one of
     the offenders this sprint is fixing), and right-aligned by .module-head's existing
     space-between so it reads as the panel's own control rather than as content. */
  .cs-collapse-btn { flex-shrink: 0; min-height: 40px; min-width: 44px; text-align: right; }
  @media (max-width: 640px) { .cs-collapse-btn { min-height: 44px; } }
  .cs-section-title { font-size: 12.5px; letter-spacing: 0.08em; color: var(--ink); text-transform: uppercase; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
  .cs-section-sub { font-size: 11.5px; color: var(--ink-faint); margin: -6px 0 12px; }
  /* Quick tool */
  .cs-quick-tool-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; margin-bottom: 12px; }
  .cs-quick-btn { background: var(--panel-raised); border: 1px solid var(--border-soft); color: var(--ink-soft); border-radius: 4px; padding: 12px 8px; font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.03em; cursor: pointer; transition: all 0.15s ease; text-align: center; }
  .cs-quick-btn:hover { border-color: var(--cyan); color: var(--cyan-bright); background: var(--panel); transform: translateY(-1px); }
  .cs-quick-result { background: linear-gradient(135deg, rgba(var(--cyan-glow-rgb), 0.10), var(--panel-raised)); border: 1px solid var(--cyan-dim); border-radius: 6px; padding: 16px 18px; text-align: center; }
  .cs-quick-result-label { font-size: 9.5px; letter-spacing: 0.18em; color: var(--cyan-dim); text-transform: uppercase; margin-bottom: 6px; }
  .cs-quick-result-card { font-size: 19px; color: var(--ink); font-weight: 600; margin-bottom: 4px; }
  .cs-quick-result-rate { font-size: 22px; color: var(--cyan-bright); margin-bottom: 8px; }
  .cs-quick-result-why { font-size: 11.5px; color: var(--ink-soft); }
  /* My Cards visual grid */
  .cs-my-cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
  .cs-card-visual { background: linear-gradient(160deg, var(--panel-raised), var(--panel)); border: 1px solid var(--border-soft); border-radius: 8px; padding: 16px 18px; position: relative; overflow: hidden; }
  .cs-card-visual::before { content: ''; position: absolute; top: -40%; right: -20%; width: 160px; height: 160px; background: radial-gradient(circle, rgba(var(--cyan-glow-rgb), 0.10), transparent 70%); pointer-events: none; }
  .cs-card-visual-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 10px; }
  .cs-card-visual-name { font-size: 14px; color: var(--ink); font-weight: 600; letter-spacing: 0.01em; }
  .cs-card-visual-issuer { font-size: 10px; color: var(--ink-faint); margin-top: 2px; text-transform: uppercase; letter-spacing: 0.06em; }
  .cs-card-visual-fee { font-size: 10.5px; color: var(--gold); white-space: nowrap; }
  .cs-card-visual-rate { font-size: 24px; color: var(--cyan-bright); margin-bottom: 10px; }
  .cs-card-visual-rate span { font-size: 10px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; margin-left: 6px; }
  .cs-card-visual-row { font-size: 11.5px; color: var(--ink-soft); margin-bottom: 6px; line-height: 1.5; }
  .cs-card-visual-label { color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; font-size: 9.5px; margin-right: 6px; }
  .cs-card-visual-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-soft); font-size: 10px; }
  .cs-card-visual-status { color: var(--green); text-transform: uppercase; letter-spacing: 0.05em; }
  .cs-verify-tag { color: var(--gold); font-size: 10px; }
  /* ---- Card Strategy: Add Card / Configure Card modals (Sprint 4, Part D/Task 60) ---- */
  .cs-add-card-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border-soft); cursor: pointer; }
  .cs-add-card-row:last-child { border-bottom: none; }
  .cs-add-card-name { font-size: 13px; color: var(--ink); font-weight: 600; }
  .cs-add-card-meta { font-size: 11px; color: var(--ink-faint); margin-top: 2px; }
  .cs-use-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px 14px; }
  .cs-use-chip { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--ink-soft); cursor: pointer; }
  .cs-use-chip input[type=checkbox] { width: 14px; height: 14px; accent-color: var(--cyan); cursor: pointer; }
  /* Audit: staleness + per-field confidence badges */
  .cs-stale-badge { font-size: 9.5px; letter-spacing: 0.03em; padding: 2px 7px; border-radius: 10px; white-space: nowrap; }
  .cs-stale-green { color: var(--green); background: rgba(var(--green-rgb), 0.12); }
  .cs-stale-yellow { color: var(--gold); background: rgba(var(--gold-rgb), 0.12); }
  .cs-stale-red { color: var(--red); background: rgba(var(--red-rgb), 0.12); }
  .cs-confidence-badge { font-size: 10px; margin-right: 4px; }
  .cs-confidence-verified { color: var(--green); }
  .cs-confidence-secondary { color: var(--gold); }
  .cs-confidence-unverified { color: var(--red); }
  .cs-src-link { font-size: 9.5px; color: var(--cyan-dim); text-decoration: underline; }
  .cs-audit-row { padding: 8px 0; border-bottom: 1px solid var(--border-soft); font-size: 11.5px; }
  .cs-audit-row:last-child { border-bottom: none; }
  .cs-audit-field { color: var(--ink-soft); }
  .cs-audit-existing { color: var(--red); text-decoration: line-through; opacity: 0.75; }
  .cs-audit-verified { color: var(--green); font-weight: 600; }
  .cs-audit-status-tag { font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.05em; padding: 1px 6px; border-radius: 8px; margin-left: 6px; }
  .cs-usage-select { font-size: 10px; margin-left: 8px; }
  /* Category recommendation cards */
  .cs-rec-row { display: flex; gap: 12px; flex-wrap: wrap; }
  .cs-rec-card { flex: 1; min-width: 180px; background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 6px; padding: 14px 16px; }
  .cs-rec-0 { border-color: var(--gold); background: linear-gradient(135deg, rgba(var(--gold-rgb), 0.10), var(--panel-raised)); }
  .cs-rec-medal { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 6px; }
  .cs-rec-0 .cs-rec-medal { color: var(--gold); }
  .cs-rec-name { font-size: 13.5px; color: var(--ink); font-weight: 600; margin-bottom: 4px; }
  .cs-rec-rate { font-size: 18px; color: var(--cyan-bright); margin-bottom: 6px; }
  .cs-rec-why { font-size: 11px; color: var(--ink-soft); line-height: 1.5; }
  /* Travel matchmaker form */
  .cs-trip-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }
  .cs-trip-budget-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 6px; }
  .cs-trip-budget-field { display: flex; flex-direction: column; gap: 4px; }
  .cs-trip-budget-label { font-size: 10.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.04em; }
  /* Trip recommendation rows */
  .cs-trip-rec-grid { display: flex; flex-direction: column; gap: 8px; }
  .cs-trip-rec-row { display: grid; grid-template-columns: 1.2fr 1.3fr 0.7fr 1.3fr 2fr; gap: 10px; align-items: center; padding: 10px 12px; background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; font-size: 11.5px; }
  .cs-trip-rec-seg { color: var(--ink); font-weight: 600; }
  .cs-trip-rec-card { color: var(--cyan-bright); }
  .cs-trip-rec-rate { color: var(--gold); text-align: center; }
  .cs-trip-rec-est { color: var(--ink-soft); }
  .cs-trip-rec-why { color: var(--ink-faint); font-size: 10.5px; }
  @media (max-width: 900px) { .cs-trip-rec-row { grid-template-columns: 1fr 1fr; } }
  /* Estimated trip rewards summary */
  .cs-summary-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 10px; }
  .cs-summary-tile { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 12px 14px; }
  .cs-summary-label { font-size: 9.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; }
  .cs-summary-value { font-size: 18px; color: var(--ink); }
  .cs-point-value-row { font-size: 11.5px; color: var(--ink-soft); background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 10px 14px; }
  .cs-point-value-note { display: block; margin-top: 4px; font-size: 10.5px; color: var(--ink-faint); }
  /* Benefit maximizer */
  .cs-benefit-progress-head { font-size: 11px; letter-spacing: 0.08em; color: var(--ink-faint); text-transform: uppercase; margin-bottom: 6px; }
  .cs-benefit-progress-readout { font-size: 20px; color: var(--ink); margin-bottom: 4px; }
  .cs-benefit-progress-bar { font-family: var(--mono); color: var(--cyan-bright); font-size: 13px; letter-spacing: 1px; margin-bottom: 4px; }
  .cs-benefit-progress-remaining { font-size: 11.5px; color: var(--gold); }
  .cs-benefit-row { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border-soft); }
  .cs-benefit-row-compact { padding: 7px 0; }
  .cs-benefit-row-compact .cs-benefit-notes { margin-top: 2px; }
  .cs-benefit-row:last-child { border-bottom: none; }
  .cs-benefit-check { font-size: 16px; cursor: pointer; user-select: none; }
  .cs-benefit-main { flex: 1; }
  .cs-benefit-name { font-size: 12.5px; color: var(--ink); }
  .cs-benefit-card-tag { font-size: 9.5px; color: var(--cyan-dim); border: 1px solid var(--border-soft); border-radius: 3px; padding: 1px 6px; margin-left: 6px; text-transform: uppercase; letter-spacing: 0.04em; }
  .cs-benefit-meta { font-size: 10.5px; color: var(--ink-faint); margin-top: 3px; }
  .cs-benefit-notes { font-size: 11px; color: var(--ink-soft); margin-top: 3px; }
  .cs-benefit-remaining { font-size: 11px; color: var(--ink-soft); white-space: nowrap; }
  /* Rotating categories */
  .cs-rotating-row { display: grid; grid-template-columns: 1.2fr 2fr 1fr 1fr; gap: 10px; align-items: center; padding: 9px 0; border-bottom: 1px solid var(--border-soft); font-size: 12px; }
  .cs-rotating-row:last-child { border-bottom: none; }
  .cs-rotating-card { color: var(--ink); }
  .cs-rotating-cats { color: var(--ink-soft); }
  .cs-rotating-activate { cursor: pointer; color: var(--cyan-bright); }
  .cs-rotating-exp { color: var(--ink-faint); font-size: 10.5px; }
  @media (max-width: 700px) { .cs-rotating-row { grid-template-columns: 1fr 1fr; } }
  /* Travel benefits comparison */
  .cs-travel-benefits-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
  .cs-travel-benefit-row { display: flex; gap: 8px; font-size: 11.5px; padding: 6px 0; border-bottom: 1px solid var(--border-soft); }
  .cs-travel-benefit-row:last-child { border-bottom: none; }
  .cs-travel-benefit-label { color: var(--ink-faint); min-width: 90px; flex-shrink: 0; }
  .cs-travel-benefit-val { color: var(--ink-soft); }
  /* Card stack */
  .cs-stack-row { display: flex; align-items: center; gap: 14px; padding: 12px 0; border-bottom: 1px solid var(--border-soft); }
  .cs-stack-row:last-child { border-bottom: none; }
  .cs-stack-medal { font-size: 22px; }
  .cs-stack-main { flex: 1; }
  .cs-stack-label { font-size: 9.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; }
  .cs-stack-card { font-size: 14px; color: var(--ink); margin: 2px 0; }
  .cs-stack-use { font-size: 11px; color: var(--ink-soft); }
  /* Rewards strategy */
  .cs-rewards-row { padding: 10px 0; border-bottom: 1px solid var(--border-soft); font-size: 12px; }
  .cs-rewards-row:last-child { border-bottom: none; }
  .cs-rewards-card { color: var(--ink); font-weight: 600; margin-bottom: 3px; }
  .cs-rewards-currency, .cs-rewards-best, .cs-rewards-balance { color: var(--ink-soft); font-size: 11px; margin-top: 2px; }
  /* Next trip strategy */
  .cs-next-trip-head { font-size: 14px; color: var(--ink); margin-bottom: 4px; }
  .cs-next-trip-sub { font-size: 11.5px; color: var(--ink-faint); margin-bottom: 12px; }
  .cs-note { font-size: 11px; color: var(--ink-faint); margin-top: 10px; font-style: italic; }
  /* Compare tool */
  .cs-compare-check { font-size: 11.5px; color: var(--ink-soft); margin-right: 14px; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
  @media (max-width: 900px) {
    .cs-snapshot-row { grid-template-columns: repeat(2, 1fr); }
    .cs-trip-form-grid { grid-template-columns: minmax(0, 1fr); }
    .cs-summary-grid { grid-template-columns: repeat(2, 1fr); }
  }
  @media (max-width: 520px) {
    .cs-snapshot-row { grid-template-columns: minmax(0, 1fr); }
    .cs-quick-tool-grid { grid-template-columns: repeat(3, 1fr); }
    .cs-summary-grid { grid-template-columns: minmax(0, 1fr); }
  }
  /* ---- Home: Today sub-tab (additive, td- prefixed — does not alter any existing rule above) ---- */
  .td-top-row { display: grid; grid-template-columns: 260px minmax(280px, 1fr); gap: 16px; margin-bottom: 16px; }
  .td-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; }
  .td-progress-readout { font-size: 32px; font-weight: 600; color: var(--ink); text-align: center; margin-bottom: 10px; }
  .td-progress-breakdown { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; font-size: 11.5px; color: var(--ink-soft); }
  .td-scorecard-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
  .td-score-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 12px 14px; cursor: pointer; transition: transform 0.15s ease, border-color 0.15s ease; }
  .td-score-card:hover { transform: translateY(-2px); border-color: var(--cyan); }
  .td-score-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 11.5px; color: var(--ink); }
  .td-score-big { font-size: 18px; color: var(--ink); font-weight: 600; word-break: break-word; }
  .td-score-sub { font-size: 10.5px; color: var(--ink-soft); margin-top: 4px; line-height: 1.5; }
  .td-snapshot-summary { font-size: 11px; color: var(--ink-soft); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.04em; }
  .td-snapshot-stats { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; font-size: 11.5px; color: var(--ink-soft); }
  .td-stat-row { display: flex; justify-content: space-between; gap: 8px; }
  .td-stat-row strong { color: var(--ink); white-space: nowrap; }
  .td-sched-status { flex-shrink: 0; }
  .td-add-row { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
  .td-priority-select, .td-due-input, .td-category-input, .td-task-input {
    background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink);
    padding: 7px 8px; border-radius: 2px; font-size: 12px; font-family: var(--mono);
  }
  .td-priority-select { flex: 0 0 88px; }
  .td-due-input { flex: 0 0 96px; color-scheme: dark; }
  .td-category-input { flex: 0 0 120px; min-width: 100px; }
  .td-task-input { flex: 1; min-width: 140px; }
  .td-priority-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; display: inline-block; }
  .td-priority-high { background: var(--red); }
  .td-priority-medium { background: var(--gold); }
  .td-priority-low { background: var(--cyan-dim); }
  .td-attn-row { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border-soft); }
  .td-attn-row:last-child { border-bottom: none; }
  .td-attn-row[onclick] { cursor: pointer; }
  .td-attn-row[onclick]:hover { background: var(--panel-raised); }
  .td-attn-icon { font-size: 15px; flex-shrink: 0; width: 20px; text-align: center; }
  .td-attn-text { font-size: 12.5px; color: var(--ink); }
  .td-attn-meta { font-size: 10.5px; color: var(--ink-faint); margin-top: 2px; }
  /* V1.1 Sprint 2A Part 5: condensed category-count rows + the "Show details" disclosure. */
  .td-attn-summary-row .td-attn-text { font-weight: 600; }
  .td-attn-icon-warn { color: var(--gold); }
  .td-attn-details { margin-top: 4px; }
  .td-attn-details summary { cursor: pointer; font-size: 11px; padding: 6px 0; list-style: none; }
  .td-attn-details summary::-webkit-details-marker { display: none; }
  .td-attn-details summary::before { content: '▸ '; }
  .td-attn-details[open] summary::before { content: '▾ '; }
  .td-attn-detail-list { margin-top: 2px; }
  .td-done-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--border-soft); font-size: 12.5px; }
  .td-done-row:last-child { border-bottom: none; }
  .td-done-icon { font-size: 14px; flex-shrink: 0; width: 18px; text-align: center; }
  .td-done-text { flex: 1; color: var(--ink); }
  @media (max-width: 720px) {
    .td-top-row { grid-template-columns: minmax(0, 1fr); }
  }
  /* ---- Home: Inbox sub-tab (additive, ib- prefixed — does not alter any existing rule above) ---- */
  .ib-header-panel { margin-bottom: 16px; }
  .ib-header-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 14px; margin-bottom: 14px; }
  .ib-subtitle { font-size: 11.5px; color: var(--ink-soft); margin-top: 4px; }
  .ib-summary-row { display: flex; gap: 18px; flex-wrap: wrap; }
  .ib-metric { display: flex; flex-direction: column; align-items: center; min-width: 56px; }
  .ib-metric strong { font-size: 18px; color: var(--ink); font-weight: 600; }
  .ib-metric span { font-size: 9.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; margin-top: 2px; white-space: nowrap; }
  .ib-toolbar { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; border-top: 1px solid var(--border-soft); padding-top: 12px; }
  .ib-cats { display: flex; flex-wrap: wrap; gap: 6px; }
  .ib-cat-btn { background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink-soft); padding: 5px 10px; border-radius: 3px; font-size: 10.5px; letter-spacing: 0.03em; font-family: var(--mono); cursor: pointer; white-space: nowrap; }
  .ib-cat-btn:hover { color: var(--cyan); border-color: var(--cyan-dim); }
  .ib-cat-btn.active { background: var(--cyan); border-color: var(--cyan); color: var(--on-accent); }
  .ib-controls { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
  .ib-search-input, .ib-sort-select { background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink); padding: 7px 9px; border-radius: 2px; font-size: 12px; font-family: var(--mono); }
  .ib-search-input { min-width: 160px; }
  .ib-layout { display: grid; grid-template-columns: minmax(280px, 1.3fr) minmax(240px, 1fr); gap: 16px; align-items: start; }
  .ib-list-panel { max-height: 640px; overflow-y: auto; }
  /* Connected Accounts placeholder (Part 5) — compact, non-interactive, no affordance to click. */
  /* My Interests (V1.1, Part 10) */
  /* V1.2 (Part G) — the interest row. The previous version put four 44px icon buttons on every
     row (188px of controls beside an emoji and a word) and one of them was invisible. Now the row
     is a single large target that OPENS the interest, plus two labelled actions. */
  /* V1.3 (Part 1): the collapsed My Habits summary. */
  .hm-summary-line { font-size: 12px; color: var(--ink); }
  .hm-summary-sub { color: var(--ink-soft); }
  /* V1.3 (Part 31): the custom-favorite label row carries its own Remove, so the label and the
     control share a line rather than the control needing a row of its own. */
  .fav-card-label { display: flex; justify-content: space-between; align-items: center; gap: 8px; flex-wrap: wrap; }
  .fav-remove { font-size: 10px; padding: 4px 8px; min-height: 28px; }
  .fav-card--add { border-style: dashed; }
  /* V1.3 (Part 6): the nutrition-context line. Quiet, small, present wherever macros are — it is
     context, not a warning banner, and it must never read as advice. */
  /* Privacy controls read as controls, not as quiet metadata. Same button, clearer ink. */
  .mini-refresh--privacy { color: var(--ink-soft); }
  .mini-refresh--privacy:hover, .mini-refresh--privacy:focus-visible { color: var(--cyan-bright); }
  .interest-form-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
  .interest-form-name { flex: 1 1 200px; min-width: 0; }
  .interest-form-icon { flex: 0 0 92px; }
  .interest-form-more { display: inline-flex; margin-top: 12px; }
  .macro-context { font-size: 11px; color: var(--ink-soft); line-height: 1.6; margin-top: 14px;
    padding-top: 12px; border-top: 1px solid var(--border-soft); }
  .interest-list { display: flex; flex-direction: column; gap: 2px; }
  .interest-open { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 10px;
    background: none; border: 0; padding: 4px 0; text-align: left; cursor: pointer; color: inherit; font: inherit; }
  .interest-open:hover .interest-name { color: var(--cyan-bright); }
  .interest-btn { background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink-soft);
    border-radius: 6px; padding: 6px 10px; font-size: 11px; cursor: pointer; min-height: var(--tap);
    white-space: nowrap; }
  .interest-btn:hover { color: var(--ink); border-color: var(--cyan); }
  /* PART A — THE REPORTED BUG, AND IT WAS WORSE THAN REPORTED.
     The remove control carries .del-btn, whose shared contract is `opacity: 0` revealed by
     `.list-item:hover .del-btn`. An interest row is .interest-row, NOT .list-item — so there was
     no rule that could ever reveal it. Measured: opacity 0, 44x44px, on desktop, on touch, in all
     six themes. It was not hard to discover; it was impossible to see, while still occupying the
     widest slot on the row.
     Scoped here rather than by changing .del-btn globally, because tasks/events rows
     deliberately keep the hover-reveal treatment; this follows the precedent
     .journal-entry-card already set. The canonical deleteInterest(id) path is untouched. */
  .interest-del, .interest-actions .del-btn { opacity: 1; color: var(--ink-soft); }
  .interest-del:hover, .interest-del:focus-visible,
  .interest-actions .del-btn:hover, .interest-actions .del-btn:focus-visible {
    opacity: 1; color: var(--red); border-color: var(--red); }
  .interest-reorder { display: inline-flex; gap: 2px; }
  .interest-detail-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
  .interest-detail-title { color: var(--ink-soft); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; }
  .interest-detail-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
  .interest-detail-icon { font-size: 30px; }
  .interest-detail-name { font-size: 18px; color: var(--ink); overflow-wrap: anywhere; }
  .interest-detail-type { font-size: 11px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; }
  .interest-detail-field { margin-bottom: 12px; color: var(--ink); font-size: 13px; overflow-wrap: anywhere; }
  .interest-detail-label { font-size: 11px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 3px; }
  .interest-row { display: flex; align-items: center; gap: 10px; min-width: 0;
    padding: 8px 0; border-bottom: 1px solid var(--border-soft); min-height: var(--tap-touch); }
  .interest-row:last-child { border-bottom: none; }
  .interest-icon { flex: 0 0 auto; font-size: 15px; }
  .interest-name { flex: 1 1 auto; min-width: 0; color: var(--ink); overflow-wrap: anywhere;
    display: flex; flex-direction: column; gap: 2px; }
  .interest-notes { font-size: 11px; color: var(--ink-faint); }
  .interest-actions { flex: 0 0 auto; display: flex; gap: 4px; }
  /* --tap-touch (44px), not --tap (40px): these are the mobile floor the OS-wide consistency
     audit enforces, and the first version used the desktop token and failed it. */
  /* Compact on a pointer, and only grown to the touch floor where a finger actually needs it —
     the blanket 44px minimum was half of why this row read as developer tooling. The touch rule
     lives with the other coarse-pointer overrides further down. */
  .interest-actions .icon-btn { min-width: 30px; min-height: var(--tap); padding: 0 4px; }
  .interest-actions .icon-btn[disabled] { opacity: 0.35; cursor: default; }
  /* V1.2 (Part G) — touch sizing, and it lives HERE on purpose. The first version of this block
     sat with the other max-width:640px overrides ~1,600 lines earlier in the stylesheet, where
     `.interest-actions .icon-btn` (same specificity, earlier in source) simply lost to the
     compact desktop rule above it. Measured at 390px: 34x40, not the 44x44 it claimed to set.
     Cascade order is not a detail you can assume — a rule that loses is a rule that isn't there.
     Behaviour: the row follows the .acct-row precedent — the name takes its own full-width line
     and the controls sit below on one line — so each control gets the 44px a finger needs without
     four of them demanding 44px of WIDTH from a 390px screen and forcing the row to wrap raggedly. */
  @media (max-width: 640px) {
    .interest-row { flex-wrap: wrap; }
    .interest-open { flex: 1 1 100%; min-height: var(--tap-touch); }
    .interest-actions { flex: 1 1 100%; justify-content: flex-end; }
    .interest-actions .icon-btn, .interest-btn, .interest-del, .interest-actions .del-btn {
      min-height: var(--tap-touch); min-width: var(--tap-touch); }
  }
  .interest-suggest-label { font-size: 11px; color: var(--ink-faint); margin-bottom: 6px; }
  .interest-suggest-row { display: flex; flex-wrap: wrap; gap: 6px; }
  .interest-chip { background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink-soft);
    border-radius: 999px; padding: 0 12px; min-height: var(--tap-touch); font-size: 12px; cursor: pointer; }
  .interest-chip:hover { color: var(--ink); border-color: var(--cyan); }
  .ib-list-item { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
  .ib-list-item:hover { background: var(--panel-raised); }
  .ib-list-item.ib-selected { background: var(--panel-raised); border-left: 2px solid var(--cyan); padding-left: 7px; margin-left: -9px; }
  .ib-priority-icon { flex-shrink: 0; font-size: 11px; margin-top: 3px; }
  .ib-item-body { flex: 1; min-width: 0; }
  .ib-item-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
  .ib-item-subject { font-size: 12.5px; color: var(--ink-soft); }
  .ib-item-subject.ib-unread { color: var(--ink); font-weight: 700; }
  .ib-item-time { font-size: 10px; color: var(--ink-faint); white-space: nowrap; flex-shrink: 0; }
  .ib-item-preview { font-size: 11px; color: var(--ink-soft); margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ib-item-meta { font-size: 9.5px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.04em; margin-top: 4px; }
  .ib-zero { text-align: center; padding: 40px 0; font-size: 14px; line-height: 1.8; }
  .ib-detail-title { font-size: 14px; color: var(--ink); letter-spacing: 0.03em; margin-bottom: 12px; text-transform: uppercase; }
  .ib-detail-row { display: flex; justify-content: space-between; gap: 10px; font-size: 11.5px; color: var(--ink-soft); padding: 5px 0; border-bottom: 1px solid var(--border-soft); }
  .ib-detail-label { color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; font-size: 10px; }
  .ib-detail-message { font-size: 12px; color: var(--ink); line-height: 1.6; margin: 12px 0; padding: 10px; background: var(--panel-raised); border-radius: 3px; border: 1px solid var(--border-soft); }
  .ib-detail-linked { font-size: 11px; color: var(--green); margin-bottom: 10px; }
  .ib-detail-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
  /* Collapse only on true mobile widths — tablet keeps list + detail side by side. */
  @media (max-width: 640px) {
    .ib-layout { grid-template-columns: minmax(0, 1fr); }
    .ib-list-panel { max-height: none; }
  }
  /* ---- Home: Insights sub-tab (additive, ins- prefixed — does not alter any existing rule above) ---- */
  .ins-header-panel { margin-bottom: 16px; }
  .ins-header-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 14px; }
  .ins-subtitle { font-size: 11.5px; color: var(--ink-soft); margin-top: 4px; }
  .ins-tf-nav { display: flex; gap: 6px; flex-wrap: wrap; }
  .ins-tf-btn { background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink-soft); padding: 6px 12px; border-radius: 3px; font-size: 11px; font-family: var(--mono); cursor: pointer; white-space: nowrap; }
  .ins-tf-btn:hover { color: var(--cyan); border-color: var(--cyan-dim); }
  .ins-tf-btn.active { background: var(--cyan); border-color: var(--cyan); color: var(--on-accent); }
  .ins-section { margin-bottom: 16px; }
  .ins-top-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border-soft); }
  .ins-top-row:last-child { border-bottom: none; }
  .ins-top-text { font-size: 12.5px; color: var(--ink); flex: 1; }
  .ins-card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; margin-bottom: 16px; align-items: stretch; }
  .ins-card { display: flex; flex-direction: column; gap: 6px; }
  .ins-card .muted-link { margin-top: auto; align-self: flex-start; padding-top: 6px; }
  .ins-card-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 10.5px; letter-spacing: 0.04em; color: var(--ink-soft); }
  .ins-card-headline { font-size: 15px; color: var(--ink); font-weight: 600; margin-top: 4px; }
  .ins-card-sub { font-size: 11px; color: var(--ink-soft); line-height: 1.5; margin-bottom: 4px; }
  .ins-card-trend { font-size: 9.5px; letter-spacing: 0.04em; padding: 2px 6px; border-radius: 8px; border: 1px solid; white-space: nowrap; }
  .ins-trend-up { color: var(--green); border-color: var(--green); background: rgba(var(--green-rgb), 0.08); }
  .ins-trend-down { color: var(--red); border-color: var(--red); background: rgba(var(--red-rgb), 0.08); }
  .ins-trend-stable { color: var(--gold); border-color: var(--gold); background: rgba(var(--gold-rgb), 0.08); }
  .ins-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; align-items: stretch; }
  .ins-grid-2 > .panel { display: flex; flex-direction: column; }
  .ins-balance-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; }
  .ins-balance-label { font-size: 11.5px; color: var(--ink-soft); width: 96px; flex-shrink: 0; }
  .ins-balance-track { flex: 1; height: 9px; border-radius: 5px; background: var(--panel-raised); border: 1px solid var(--border-soft); overflow: hidden; }
  .ins-balance-fill { height: 100%; border-radius: 5px; transition: width 0.6s cubic-bezier(0.22,1,0.36,1); }
  .ins-balance-value { font-size: 11px; color: var(--ink); width: 64px; text-align: right; flex-shrink: 0; }
  .ins-attn-row, .ins-win-row { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border-soft); }
  .ins-attn-row:last-child, .ins-win-row:last-child { border-bottom: none; }
  .ins-attn-icon, .ins-win-icon { font-size: 15px; flex-shrink: 0; width: 20px; text-align: center; }
  .ins-attn-text, .ins-win-text { font-size: 12.5px; color: var(--ink); flex: 1; }
  .ins-trend-row { display: flex; justify-content: space-between; align-items: center; padding: 7px 0; border-bottom: 1px solid var(--border-soft); font-size: 12px; color: var(--ink-soft); }
  .ins-trend-row:last-child { border-bottom: none; }
  .ins-trend-badge { font-size: 10.5px; padding: 2px 8px; border-radius: 8px; border: 1px solid; white-space: nowrap; }
  .ins-scorecard-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; }
  .ins-score-card { background: var(--panel-raised); border: 1px solid var(--border-soft); border-radius: 4px; padding: 12px; text-align: center; }
  .ins-score-label { font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 6px; }
  .ins-score-value { font-size: 18px; color: var(--ink); font-weight: 600; }
  .ins-formulas { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border-soft); }
  .ins-formula-row { font-size: 11px; color: var(--ink-soft); line-height: 1.6; margin-bottom: 4px; }
  .ins-formula-row strong { color: var(--ink); }
  /* Collapse only on true mobile widths — tablet keeps the 2-column layout. */
  @media (max-width: 640px) {
    .ins-grid-2 { grid-template-columns: minmax(0, 1fr); }
  }

  /* =====================================================================
     DEVICE COMPATIBILITY / RESPONSIVE AUDIT — additive fixes only.
     No new features, no layout redesign, no data/architecture changes.
     Scope: nav crowding on narrow screens, chart/element overflow,
     touch-target sizing on touch devices (iPhone + Tesla touchscreen),
     iOS Safari input zoom, and iPhone safe-area (notch/home-indicator).
     ===================================================================== */

  /* Safety net: nothing should be able to force page-level horizontal
     scroll. Root overflow causes are fixed at the source (see chart fix,
     nav fix below); this just guarantees the page itself never grows a
     horizontal scrollbar even if something upstream misbehaves. */
  html, body { overflow-x: hidden; }
  img, svg { max-width: 100%; }

  /* ---- Primary / sub navigation: switch from wrapping to horizontal
     scroll below tablet width. Wrapping 8 main tabs + 5 home tabs stacks
     into 4-6 rows on an iPhone, pushing "Today" and other priority
     screens far below the fold. A single scrollable row keeps all tabs
     reachable in one motion and keeps content visible immediately. ---- */
  @media (max-width: 700px) {
    .main-tab-row, .home-nav-row, .life-nav-row, .trav-nav-row {
      flex-wrap: nowrap;
      overflow-x: auto;
      overflow-y: hidden;
      -webkit-overflow-scrolling: touch;
      scroll-snap-type: x proximity;
      padding-bottom: 4px;
      margin-bottom: 16px;
      scrollbar-width: thin;
    }
    .main-tab-row::-webkit-scrollbar, .home-nav-row::-webkit-scrollbar,
    .life-nav-row::-webkit-scrollbar, .trav-nav-row::-webkit-scrollbar { height: 4px; }
    .main-tab-row::-webkit-scrollbar-thumb, .home-nav-row::-webkit-scrollbar-thumb,
    .life-nav-row::-webkit-scrollbar-thumb, .trav-nav-row::-webkit-scrollbar-thumb {
      background: var(--border); border-radius: 4px;
    }
    /* V1 VISUAL & UX POLISH SPRINT (Part 29) — SUBTAB SCROLL AFFORDANCE.
       These rows already scrolled horizontally below 700px, but the only cue was a 4px
       scrollbar, which mobile browsers hide until a scroll is already in progress. The Part 1
       re-audit measured Finance at 761px of pills inside a 362px row and Home at 510px: four of
       Finance's seven subtabs (Investments, Goals, Credit Cards and half of Net Worth) were
       simply invisible with nothing on screen suggesting they existed.
       The fade is applied by syncNavScrollAffordance() ONLY while a row actually overflows and
       only on the side that has more content, so a row that fits is never dimmed at its edge —
       which is why this is a JS-toggled class rather than a static mask. */
    .nav-fade-end { mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent 100%);
      -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent 100%); }
    .nav-fade-start { mask-image: linear-gradient(to right, transparent 0, #000 32px);
      -webkit-mask-image: linear-gradient(to right, transparent 0, #000 32px); }
    .nav-fade-start.nav-fade-end {
      mask-image: linear-gradient(to right, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
      -webkit-mask-image: linear-gradient(to right, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%); }
    .main-tab-btn, .home-nav-btn, .life-nav-btn, .trav-nav-btn {
      flex-shrink: 0;
      scroll-snap-align: start;
      white-space: nowrap;
    }
    /* Mobile Home priority order: Today / Schedule / Inbox / Insights /
       Overview — a pure visual reorder (flex `order`), same buttons, same
       onclick handlers, same underlying tab markup/behavior. Desktop and
       tablet keep the original Overview-first order untouched. */
    #homeNavTodayBtn { order: 1; }
    #homeNavCommandBtn { order: 2; }
    #homeNavInboxBtn { order: 3; }
    #homeNavInsightsBtn { order: 4; }
    #homeNavOverviewBtn { order: 5; }
  }

  /* ---- Touch targets: comfortable tap size on touch devices only
     (iPhone Safari and Tesla's touchscreen both report as coarse
     pointers). Mouse/trackpad users on desktop are unaffected, so the
     desktop baseline is unchanged. ---- */
  @media (hover: none) and (pointer: coarse) {
    .main-tab-btn, .home-nav-btn, .life-nav-btn, .trav-nav-btn,
    .btn, .fin-range-btn, .trav-modal-sub-btn, .trip-quick-btn {
      min-height: 44px;
      padding-top: 11px;
      padding-bottom: 11px;
    }
    .icon-btn, .mini-refresh { width: 44px; height: 44px; }
    .mini-refresh { font-size: 14px; }
    input[type=checkbox] { width: 20px; height: 20px; }
    /* Custom checkbox (.checkbox div) stays visually the same size — this
       only enlarges its invisible hit area so it's comfortable to tap
       without changing how dense/compact the lists look. V4.2.1: -13px gave
       a 41px hit area, one pixel under the 44px floor — bumped to -15px
       (15px checkbox + 2×15px = 45px). */
    .checkbox { position: relative; }
    .checkbox::before {
      content: "";
      position: absolute;
      inset: -15px;
    }
  }
  /* Identical rule, keyed off a class instead of real hardware — lets the
     Device Mode Preview tool (see body) accurately simulate a touch device
     from a mouse-driven dev machine, where (pointer: coarse) never fires. */
  html.force-touch .main-tab-btn, html.force-touch .home-nav-btn, html.force-touch .life-nav-btn, html.force-touch .trav-nav-btn,
  html.force-touch .btn, html.force-touch .fin-range-btn, html.force-touch .trav-modal-sub-btn, html.force-touch .trip-quick-btn,
  html.force-touch-large .main-tab-btn, html.force-touch-large .home-nav-btn, html.force-touch-large .life-nav-btn, html.force-touch-large .trav-nav-btn,
  html.force-touch-large .btn, html.force-touch-large .fin-range-btn, html.force-touch-large .trav-modal-sub-btn, html.force-touch-large .trip-quick-btn {
    min-height: 44px;
    padding-top: 11px;
    padding-bottom: 11px;
  }
  html.force-touch .icon-btn, html.force-touch .mini-refresh,
  html.force-touch-large .icon-btn, html.force-touch-large .mini-refresh { width: 44px; height: 44px; }
  html.force-touch .mini-refresh, html.force-touch-large .mini-refresh { font-size: 14px; }
  html.force-touch input[type=checkbox], html.force-touch-large input[type=checkbox] { width: 20px; height: 20px; }
  html.force-touch .checkbox, html.force-touch-large .checkbox { position: relative; }
  html.force-touch .checkbox::before, html.force-touch-large .checkbox::before {
    content: "";
    position: absolute;
    inset: -15px;
  }

  /* ---- iOS Safari zooms the whole page on focusing any input/select/
     textarea rendered below 16px. Bumping to 16px on touch-width
     viewports prevents that jarring zoom without changing desktop
     typography. ---- */
  @media (max-width: 700px) {
    input[type=text], input[type=number], input[type=date], input[type=time],
    textarea, select {
      font-size: 16px;
    }
  }

  /* ---- iPhone safe areas: keep content and modal action buttons clear
     of the notch/Dynamic Island and the home-indicator bar. ---- */
  .wrap {
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
  }
  /* Below the existing mobile breakpoints, both modal families become a
     full-bleed bottom sheet (padding:0 on the overlay, flush to the
     viewport edges) — that behavior is intentional and left as-is. The
     one gap on notched iPhones is the sheet's action-button row sitting
     flush against the home-indicator bar, so only that gets safe-area
     clearance. */
  @media (max-width: 720px) {
    .fit-modal-foot, .trav-modal-foot {
      padding-bottom: max(12px, env(safe-area-inset-bottom));
    }
  }

  /* =====================================================================
     TRUE MOBILE PRESENTATION — genuinely mobile, not a shrunk desktop.
     Desktop values above are the untouched baseline; these rules only
     trim the outer chrome (page/panel padding) and hide low-value
     decorative labels so cards can use the full width on a phone. No
     card size, spacing, or typography changes carry over to tablet/desktop
     — everything here is scoped to <=640px. ===================================================================== */
  @media (max-width: 640px) {
    .wrap {
      padding-top: 14px;
      padding-bottom: 40px;
      padding-left: max(14px, env(safe-area-inset-left));
      padding-right: max(14px, env(safe-area-inset-right));
    }
    .header { padding-bottom: 12px; margin-bottom: 16px; }
    .panel { padding: 13px 14px 15px; }
    /* Purely decorative micro-labels (e.g. "Forecast", "Holdings",
       "Sector Map") — dropping them on a phone declutters the module
       header without losing any information or control. */
    .module-code { display: none; }
  }

  /* =====================================================================
     LARGE TOUCHSCREEN (Tesla-class and similar large in-dash/kiosk
     displays) — glanceable, touch-friendly, low-friction. Detected purely
     by viewport characteristics (large + landscape + touch-primary), never
     by device name or user-agent, so this applies equally to any display
     that matches — not just Tesla. A big phone in landscape is excluded by
     the height/width floor; a touch laptop or large monitor used with a
     mouse is excluded by (hover: none) and (pointer: coarse). This is the
     SAME multi-column desktop layout underneath (nothing below re-stacks
     it) — only spacing and touch-target sizing change, on top of the
     touch-target rule above. ===================================================================== */
  @media (hover: none) and (pointer: coarse) and (orientation: landscape) and (min-width: 1100px) and (min-height: 650px) {
    .wrap { max-width: 1500px; }
    .grid { gap: 24px; }
    .panel { padding: 20px 22px 22px; }
    .module-head { margin-bottom: 18px; }
    .main-tab-row, .home-nav-row, .life-nav-row, .trav-nav-row { gap: 12px; }
    .main-tab-btn, .home-nav-btn, .life-nav-btn, .trav-nav-btn {
      padding-top: 13px;
      padding-bottom: 13px;
      padding-left: 20px;
      padding-right: 20px;
      font-size: 12.5px;
    }
    .btn, .fin-range-btn, .trav-modal-sub-btn { padding-top: 11px; padding-bottom: 11px; }
    .icon-btn, .mini-refresh { width: 48px; height: 48px; }
    .mini-refresh { font-size: 15px; }
    .act-cal-cell { min-height: 26px; }
    .act-cal-week-day { padding: 8px 4px; }
  }
  /* Same rule again, keyed off the class the Device Mode Preview iframe
     applies to itself (via ?devicePreview=touch-large) — the real query
     above needs actual touch hardware, which a dev machine previewing the
     layout usually doesn't have; the iframe's real 1280×800 size already
     satisfies the width/height/orientation part on its own. */
  html.force-touch-large .wrap { max-width: 1500px; }
  html.force-touch-large .grid { gap: 24px; }
  html.force-touch-large .panel { padding: 20px 22px 22px; }
  html.force-touch-large .module-head { margin-bottom: 18px; }
  html.force-touch-large .main-tab-row, html.force-touch-large .home-nav-row,
  html.force-touch-large .life-nav-row, html.force-touch-large .trav-nav-row { gap: 12px; }
  html.force-touch-large .main-tab-btn, html.force-touch-large .home-nav-btn,
  html.force-touch-large .life-nav-btn, html.force-touch-large .trav-nav-btn {
    padding-top: 13px;
    padding-bottom: 13px;
    padding-left: 20px;
    padding-right: 20px;
    font-size: 12.5px;
  }
  html.force-touch-large .act-cal-cell { min-height: 26px; }
  html.force-touch-large .act-cal-week-day { padding: 8px 4px; }

  /* =====================================================================
     DEVICE MODE PREVIEW — toolbar, dropdown, and the device-frame stage.
     Fixed-position, sits above the app; independent of app layout/data.
     ===================================================================== */
  #devicePreviewToolbar { position: fixed; top: 14px; right: 14px; z-index: 2000; }
  #deviceModeMenu {
    display: none; position: absolute; top: 40px; right: 0; min-width: 240px;
    background: var(--panel); border: 1px solid var(--border); border-radius: 4px;
    padding: 8px; box-shadow: 0 10px 30px rgba(var(--shadow-rgb),0.5);
    /* Part 21/22: never wider than the viewport, never taller than it, and scrolls internally
       rather than pushing the page sideways. Stays compact on desktop via max-width. */
    width: max-content; max-width: min(300px, calc(100vw - 28px));
    max-height: calc(100vh - 70px); overflow-y: auto; overscroll-behavior: contain;
  }
  .device-mode-menu-label { font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); padding: 4px 8px 8px; }
  /* V1.1 (Part 17): .device-menu-action shares .device-mode-opt's look but NOT its meaning.
     .device-mode-opt identifies a DEVICE PREVIEW option — setDeviceModePreview() toggles `active`
     across every element carrying that class, and the theme suite counts them to assert the six
     preview controls survived. Giving the Data Management entry that class would have made it a
     seventh preview mode to both. It is a menu action, so it says so. */
  .device-mode-opt, .device-menu-action {
    display: block; width: 100%; text-align: left; background: none; border: none; color: var(--ink-soft);
    font-family: var(--mono); font-size: 12px; padding: 8px; border-radius: 3px; cursor: pointer;
  }
  .device-mode-opt:hover, .device-menu-action:hover { background: var(--panel-raised); color: var(--ink); }
  /* ---- Appearance section (Theme Engine V1). Compact by design: this is the lightweight gear,
     not a settings page (Part 2), and it must fit a 390px viewport without horizontal scroll
     (Part 21) while staying small on desktop (Part 22). ---- */
  .appearance-divider { height: 1px; background: var(--border-soft); margin: 8px 4px; }
  .display-name-row { display: flex; gap: 6px; align-items: center; padding: 2px 4px 0; }
  .display-name-row .input { flex: 1 1 auto; min-width: 0; font-size: 12px; }
  .theme-opt {
    display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    background: none; border: 1px solid transparent; color: var(--ink-soft);
    font-family: var(--mono); font-size: 12px; padding: 7px 8px; border-radius: 4px;
    cursor: pointer; min-height: var(--tap);
  }
  .theme-opt:hover { background: var(--panel-raised); color: var(--ink); }
  .theme-opt.active { color: var(--cyan-bright); border-color: var(--border); background: var(--panel-raised); }
  .theme-opt:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  /* The swatch is a small two-colour chip, not a screenshot (Part 23): surface + accent dot is
     enough to tell the four presets apart at a glance and costs nothing to render. */
  .theme-swatch {
    flex: 0 0 auto; width: 22px; height: 22px; border-radius: 4px; border: 1px solid;
    display: flex; align-items: center; justify-content: center;
  }
  .theme-swatch-dot { width: 8px; height: 8px; border-radius: 50%; display: block; }
  .theme-opt-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
  .theme-opt-label { font-size: 12px; }
  /* --ink-soft, not --ink-faint: the audit measured --ink-faint at 3.03:1 in Mighty Dark, which
     is a PRE-EXISTING V1 value this sprint must not redesign (Part 6) — but new markup should not
     ship unreadable in the default theme either. --ink-soft clears 4.5:1 in all four. */
  .theme-opt-hint { font-size: 10px; color: var(--ink-soft); white-space: normal; line-height: 1.3; }
  .theme-opt-check { flex: 0 0 auto; width: 12px; color: var(--cyan-bright); font-size: 12px; }
  .device-mode-opt.active { color: var(--cyan-bright); }
  #devicePreviewStage {
    display: none; position: fixed; inset: 0; z-index: 1900; background: var(--bg);
    flex-direction: column; align-items: center;
  }
  #devicePreviewBar {
    display: flex; align-items: center; justify-content: center; gap: 16px; width: 100%;
    padding: 14px; border-bottom: 1px solid var(--border-soft); font-size: 12px; color: var(--ink-soft);
    letter-spacing: 0.04em; flex-shrink: 0;
  }
  #devicePreviewFrameOuter { margin-top: 24px; flex-shrink: 0; }
  #devicePreviewFrame { border: 1px solid var(--border); border-radius: 4px; display: block; transform-origin: top center; }

  /* ================= APEX — floating AI assistant (isolated, additive) =================
     New CSS only — no existing selector above is modified. Reuses the same
     design tokens (--panel, --border, --cyan, --mono, etc.) defined above so
     Apex matches the rest of Mighty Life OS visually. Class names kept as
     `.ai-*` for the message-list/input internals (still driven by the
     unchanged aiRenderMessages/aiSubmit JS); `.apex-*` is only the new
     floating button + panel chrome around it. */
  .ai-shell { display: flex; flex-direction: column; height: 100%; min-height: 0; }
  .ai-topbar { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 14px; gap: 10px; flex-wrap: wrap; }
  .ai-topbar-actions { display: flex; align-items: center; gap: 10px; }
  /* V1.3 (Parts 11/12): the status chip sits WITH the name rather than in the action cluster —
     it is identity, not an action, and grouping it with buttons is what made the topbar read as
     a toolbar. The dot is the calm signal; the word carries the meaning. */
  .ai-topbar-id { display: flex; align-items: baseline; gap: 8px; min-width: 0; flex-wrap: wrap; }
  .ai-provider-pill--local { border-color: var(--border-soft); color: var(--ink-soft); display: inline-flex; align-items: center; gap: 5px; }
  .ai-provider-pill--local::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--green); flex: 0 0 auto; }
  .ai-provider-pill { font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-faint); border: 1px solid var(--border-soft); padding: 3px 8px; border-radius: 2px; white-space: nowrap; }
  .ai-messages { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; border: 1px solid var(--border-soft); background: var(--panel-raised); padding: 14px; border-radius: 4px; display: flex; flex-direction: column; gap: 12px; }
  .ai-empty-state { margin: auto; text-align: center; max-width: 380px; }
  .ai-empty-greeting { font-size: 16px; color: var(--cyan-bright); margin-bottom: 6px; text-shadow: 0 0 8px rgba(var(--cyan-glow-rgb), 0.3); }
  .ai-empty-sub { font-size: 12px; color: var(--ink-soft); line-height: 1.5; }
  .ai-msg { max-width: 84%; }
  .ai-msg-user { align-self: flex-end; }
  .ai-msg-assistant { align-self: flex-start; }
  .ai-msg-meta { display: flex; justify-content: space-between; gap: 12px; font-size: 10px; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 3px; }
  .ai-msg-bubble { font-size: 13px; line-height: 1.55; padding: 10px 12px; border-radius: 4px; white-space: pre-wrap; }
  .ai-msg-user .ai-msg-bubble { background: var(--panel); border: 1px solid var(--border-soft); color: var(--ink); }
  .ai-msg-assistant .ai-msg-bubble { background: var(--panel); border-left: 2px solid var(--cyan); color: var(--ink); }
  .ai-msg-pending .ai-msg-bubble { color: var(--ink-faint); font-style: italic; }
  .ai-suggested-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0; }
  .ai-chip { background: var(--panel-raised); border: 1px solid var(--border-soft); color: var(--cyan-dim); font-family: var(--mono); font-size: 11px; padding: 6px 10px; border-radius: 2px; cursor: pointer; }
  .ai-chip:hover { border-color: var(--cyan); color: var(--cyan-bright); }
  .ai-input-row { display: flex; gap: 10px; }
  .ai-input { flex: 1; background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink); font-family: var(--mono); font-size: 13px; padding: 10px 12px; border-radius: 2px; }
  .ai-input:focus { outline: none; border-color: var(--cyan); }
  .ai-disclaimer { margin-top: 10px; font-size: 10px; color: var(--ink-faint); text-align: center; }

  /* ---- Apex Actions — Confirm/Cancel (V1.2 Sprint 1, Part 4) ----
     Rendered only on the one message currently proposing an action (see aiMessageHtml).
     min-height 44px unconditionally (not gated behind a touch media query) since this is
     the one place Apex can actually change data — it should always be comfortable to tap,
     not just on detected touch hardware. */
  .ai-action-buttons { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
  .ai-action-btn {
    min-height: 44px; min-width: 92px; padding: 8px 16px; border-radius: 4px;
    font-family: var(--mono); font-size: 12px; font-weight: 600; letter-spacing: 0.02em;
    cursor: pointer; transition: border-color var(--transition-fast), color var(--transition-fast), background var(--transition-fast);
  }
  .ai-action-confirm { background: var(--cyan); border: 1px solid var(--cyan); color: var(--bg); }
  .ai-action-confirm:hover { background: var(--cyan-bright); border-color: var(--cyan-bright); }
  .ai-action-confirm:focus-visible, .ai-action-cancel:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
  .ai-action-cancel { background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink-soft); }
  .ai-action-cancel:hover { border-color: var(--ink-faint); color: var(--ink); }

  /* ---- Apex habit-completion celebration (V1.2 Sprint 1, Part 13) ----
     Deliberately subtle: a brief glow pulse on the bubble that just confirmed the
     completion, plus a small checkmark badge — no confetti, no sound (see final report). */
  .ai-msg-celebrate .ai-msg-bubble { animation: apexCelebratePulse 900ms ease-out; }
  .ai-msg-celebrate-badge { margin-left: 6px; color: var(--cyan-bright); font-weight: 700; }

  /* ---- Apex Undo link (V1.2 Sprint, Part 2) ----
     Deliberately NOT a second button pair like Confirm/Cancel — Undo is a quiet, low-emphasis
     "in case you need it" affordance, not a decision Apex is asking the user to make. Still
     kept comfortably tappable (Part 17: 44px touch target) via padding, without looking like a
     full button. */
  .ai-undo-row { margin-top: 6px; }
  .ai-undo-link {
    display: inline-flex; align-items: center; min-height: 32px; padding: 4px 2px;
    font-family: var(--mono); font-size: 12px; color: var(--ink-soft); text-decoration: underline;
    cursor: pointer;
  }
  .ai-undo-link:hover, .ai-undo-link:focus-visible { color: var(--cyan-bright); }
  .ai-undo-link:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
  @keyframes apexCelebratePulse {
    0% { box-shadow: 0 0 0 0 rgba(var(--cyan-glow-rgb), 0.0); }
    30% { box-shadow: 0 0 0 4px rgba(var(--cyan-glow-rgb), 0.25); }
    100% { box-shadow: 0 0 0 0 rgba(var(--cyan-glow-rgb), 0); }
  }

  /* ---- Apex home view (Daily Routine UI Simplification) ----
     Shown instead of the message list whenever there's no active conversation yet — see
     apexUpdatePanelMode(). Reuses the same tokens/typography as the rest of Apex/Life OS;
     no new visual language. */
  .apex-home-view { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; justify-content: flex-start; gap: 14px; padding: 4px 2px; }
  .apex-home-greeting { text-align: center; margin-bottom: 2px; }
  .apex-home-question { font-size: 14px; color: var(--ink); margin-top: 6px; }
  .apex-home-actions { display: flex; flex-direction: column; gap: 8px; }
  .apex-routine-btn {
    display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
    background: var(--panel-raised); border: 1px solid var(--border); color: var(--ink);
    font-family: var(--mono); font-size: 13px; text-align: left;
    padding: 12px 14px; border-radius: 4px; cursor: pointer;
    transition: border-color var(--transition-fast), color var(--transition-fast);
  }
  .apex-routine-btn:hover { border-color: var(--cyan); color: var(--cyan-bright); }
  .apex-routine-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
  .apex-conversation-view { display: flex; flex-direction: column; flex: 1; min-height: 0; }

  /* ---- Apex floating button ---- */
  /* z-index 400: above ordinary dashboard content, but intentionally BELOW
     the existing modal overlays (.fit-modal-overlay: 500, .trav-modal-overlay:
     550) so an open modal always visually wins and Apex never blocks it. */
  /* Cross-tab staleness notice (PHASE 0, Part 5). Bottom-LEFT so it never collides with the
     Apex FAB (bottom-right, z-index 400); z-index 400 likewise, so modals still win. */
  #staleTabNotice {
    position: fixed; left: 22px; bottom: 22px; z-index: 400; display: none; max-width: 330px;
    background: var(--panel-raised); border: 1px solid rgba(var(--gold-rgb), 0.45);
    border-radius: 10px; padding: 12px 14px; color: var(--ink); font-size: 13px; line-height: 1.45;
    box-shadow: 0 6px 24px rgba(var(--shadow-rgb),0.45);
  }
  #staleTabNotice .stale-title { color: var(--gold); font-size: 11px; letter-spacing: 0.08em;
    text-transform: uppercase; font-family: var(--mono); margin-bottom: 6px; }
  #staleTabNotice .stale-actions { display: flex; gap: 8px; margin-top: 10px; }
  #staleTabNotice button {
    min-height: var(--tap); padding: 0 14px; border-radius: 8px; cursor: pointer;
    background: transparent; border: 1px solid var(--border); color: var(--ink); font-size: 12px;
  }
  #staleTabNotice button.stale-primary { border-color: rgba(var(--gold-rgb), 0.6); color: var(--gold); }
  .apex-fab {
    position: fixed; right: 22px; bottom: 22px; z-index: 400;
    display: flex; align-items: center; gap: 8px;
    background: var(--panel-raised); border: 1px solid var(--border); color: var(--cyan-bright);
    font-family: var(--mono); font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase;
    padding: 14px 20px; min-height: 48px; border-radius: 999px; cursor: pointer;
    box-shadow: 0 6px 24px rgba(var(--shadow-rgb),0.45), 0 0 0 1px rgba(var(--cyan-glow-rgb), 0.08);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
  }
  .apex-fab:hover { border-color: var(--cyan); box-shadow: 0 6px 24px rgba(var(--shadow-rgb),0.5), 0 0 20px rgba(var(--cyan-glow-rgb), 0.18); }
  .apex-fab:active { transform: scale(0.97); }
  .apex-fab:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }
  .apex-fab-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--cyan); box-shadow: 0 0 6px var(--cyan); flex-shrink: 0; }
  .apex-fab-label { font-weight: 600; }

  /* ---- Apex floating panel ---- */
  .apex-panel {
    position: fixed; right: 22px; bottom: 86px; z-index: 400;
    width: 400px; height: 600px; max-height: calc(100vh - 120px);
    background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
    box-shadow: 0 20px 60px rgba(var(--shadow-rgb),0.55), 0 0 0 1px rgba(var(--cyan-glow-rgb), 0.06);
    padding: 16px 18px 18px; display: flex; flex-direction: column; overflow: hidden;
    animation: apexPanelIn 0.16s ease-out;
  }
  /* The plain wrapper div (#apexPanelRoot) that apexRenderPanel() builds
     .ai-shell into is itself a flex item of .apex-panel — without this rule
     it defaults to flex:0 1 auto with min-height:auto, so it grows to its
     content's full height instead of being clipped to the panel, which is
     what let a long conversation push past the panel / page (the reported
     scroll bug). Making it a proper shrinkable flex container passes a real,
     definite height down to .ai-shell so .ai-messages can actually scroll. */
  #apexPanelRoot { display: flex; flex-direction: column; flex: 1; min-height: 0; }
  @keyframes apexPanelIn { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: none; } }
  @media (prefers-reduced-motion: reduce) { .apex-panel { animation: none; } }
  @media (max-width: 640px) {
    .ai-msg { max-width: 92%; }
    .apex-fab { right: 14px; bottom: 14px; padding: 12px 16px; }
    .apex-panel {
      right: 10px; left: 10px; bottom: 78px; width: auto;
      height: calc(100vh - 110px); max-height: calc(100vh - 110px);
    }
    /* V1 stability pass — mobile touch targets: these four Apex controls measured under the
       ~44px comfortable-tap guideline at narrow phone widths (390-430px). Widening only these,
       only on narrow viewports; desktop layout/sizing above 640px is untouched. */
    .apex-routine-btn { min-height: 44px; }
    .ai-input-row .btn { min-height: 44px; }
    .ai-input { min-height: 44px; }
    .apex-panel .mini-refresh { width: 44px; height: 44px; }
  }
  /* ==========================================================================================
     OFFICE — WORKPLACE REFINEMENT LAYER
     ==========================================================================================
     Colour tokens alone got Office to "professional". The product intent is stronger than that:
     Mighty Life OS should BLEND IN when it is open on a work machine beside email, a calendar and
     a spreadsheet — familiar, unobtrusive, not obviously a personal self-improvement dashboard at
     a glance. The neon is what gives it away, and neon is not a colour: it is glow, halo, and
     wide-tracked uppercase brand type. None of that is reachable from a token.
     FAMILIARITY, NOT IMITATION — this borrows workplace CONVENTIONS (flat panels, hairline
     borders, a blue selection bar, quiet secondary text). It copies no product's interface, uses
     no Microsoft branding, icons or assets, and renames nothing.
     This layer lives at the END of the stylesheet so it wins on source order, and it overrides
     PROPERTIES ONLY — it does not restate a single component's rules, which is what Part 4 rules
     out. It changes no dimension: no font-size, no padding, no height, no width, no module order
     (Part 25). Density invariance is re-verified by audit after this block, not assumed. */

  /* 1. No glow, anywhere. 20 text-shadows die in one property reset rather than 20 edits. */
  /* !important is deliberate and is the correct tool here. `[data-theme="office"] *` scores
     (0,1,0), which LOSES to any compound component selector (0,2,0) — the first version of
     this reset silently did nothing to exactly the rules that glow most, and the Office glow
     test caught it. Raising specificity instead would mean
     restating component selectors, which is the CSS duplication Part 4 rules out. */
  [data-theme="office"] * { text-shadow: none !important; }
  /* 2. The halo box-shadows. Enumerated rather than blanket-reset, because Office should keep
        its restrained card/modal shadows — "no neon" is not "no depth". */
  [data-theme="office"] .brand-mark,
  [data-theme="office"] .icon-btn:hover,
  [data-theme="office"] .cal-cell.selected,
  [data-theme="office"] .hm-tab-btn.active,
  [data-theme="office"] .life-nav-btn.active,
  [data-theme="office"] .home-nav-btn.active,
  [data-theme="office"] .trav-nav-btn.active,
  [data-theme="office"] .ds-week-day.active,
  [data-theme="office"] .ds-item-card:hover,
  [data-theme="office"] .ds-weekly-day-today,
  [data-theme="office"] .ds-month-cell-today,
  [data-theme="office"] .ds-year-month-current,
  [data-theme="office"] .fav-card:hover,
  [data-theme="office"] .act-cal-cell.selected,
  [data-theme="office"] .apex-fab,
  [data-theme="office"] .apex-fab:hover,
  [data-theme="office"] .apex-fab-dot,
  /* 3. Flatter business panels. Radius and shadow only — no padding, no size. */
  [data-theme="office"] .panel,
  [data-theme="office"] .fit-modal,
  [data-theme="office"] .trav-modal,
  [data-theme="office"] .apex-panel {
    border-radius: 2px; box-shadow: 0 1px 2px rgba(var(--shadow-rgb), 0.10), 0 0 0 1px rgba(var(--border-rgb), 0.10);
  }
  [data-theme="office"] .insight-card { border-radius: 2px; }
  /* 4. Quiet the brand type. Uppercase + wide tracking on a 22px cyan heading is the single
        loudest "this is not a work tool" signal. Case and tracking only — the font SIZE is
        untouched, so line boxes keep their height and nothing reflows vertically. */
  [data-theme="office"] .fin-title,
  [data-theme="office"] .cc-card-name,
  [data-theme="office"] .journal-header-copy .journal-title,
  /* 5. Conventional workplace selection: a solid left/bottom accent bar rather than a glowing
        outline. This is the convention every mail and productivity client shares. */
  /* The selection bar is painted with an INSET SHADOW, not a thicker border. The first version
     used `border-bottom: 2px` and the density audit immediately caught it: the active tab grew
     from 36px to 37px, which is exactly the per-theme dimension change Part 25 forbids. An inset
     shadow paints inside the existing box and costs zero layout. */
  [data-theme="office"] .main-tab-btn.active {
    color: var(--cyan); border-color: transparent; background: var(--panel-raised);
    box-shadow: inset 0 -2px 0 var(--cyan);
  }
  [data-theme="office"] .sub-tab-btn.active { color: var(--cyan); box-shadow: inset 0 -2px 0 var(--cyan); }
  /* 6. Understated status + progress. Status colours keep their MEANING (Part 10) — only the
        decorative intensity of the fills drops. */
  [data-theme="office"] .progress-bar-fill,
  [data-theme="office"] .fin-progress-fill { filter: saturate(0.85); }
  /* 7. Insights read as business information panels, not highlight cards. */
  /* The hairline is an INSET SHADOW, not a border, for the same reason as the tab underline:
     adding a real 1px border grew each insight card by 1px, which the density audit caught as a
     6px page-height difference on Habits. An inset shadow gives the identical business-panel
     hairline at zero layout cost. */
  [data-theme="office"] .insight-card { background: var(--panel); box-shadow: inset 0 0 0 1px rgba(var(--border-rgb), 0.18); }
  /* 8. Professional input fields: hairline border, conventional focus ring. */
  [data-theme="office"] input, [data-theme="office"] select, [data-theme="office"] textarea {
    border-radius: 2px; box-shadow: none;
  }
  [data-theme="office"] input:focus, [data-theme="office"] select:focus, [data-theme="office"] textarea:focus {
    outline: 2px solid var(--cyan); outline-offset: 0; border-color: var(--cyan);
  }
  /* 10. THE DECORATIVE SIGNALLING (V1.2, Part 15). Looking at Office Dark rendered — rather than
         at its tokens — the tells that remained were not colours at all:
           - the HUD corner brackets on every panel (.panel::before/::after, 2px accent Ls)
         None of these carry information. Every panel's tag reads the same, the brackets are pure
         ornament, and the module's real name sits directly beneath the tag. They are removed or
         quietened HERE ONLY — every other theme keeps them, because they are part of the Mighty
         Life OS identity everywhere except the theme whose whole job is to not announce itself.
         The brackets are absolutely positioned with pointer-events:none, so removing them costs
         zero layout. The tag is QUIETENED rather than hidden: it keeps its box and its text, so
         no content disappears and the "hides nothing" test stays meaningful. */
  [data-theme="office"] .panel::before,
  [data-theme="office"] .panel::after { content: none; }
  [data-theme="office"] .module-tag { color: var(--ink-faint); letter-spacing: 0.08em; }

  /* 9. Apex as a compact business assistant panel rather than a sci-fi console. Presentation
        only — routing, actions, confirm/cancel and pending states are untouched. */
  [data-theme="office"] .apex-fab { border-radius: 4px; border: 1px solid var(--border); background: var(--panel); color: var(--cyan); }
  [data-theme="office"] .apex-fab-label { letter-spacing: 0.02em; text-transform: none; }
  [data-theme="office"] .apex-panel { border-radius: 3px; }

  /* =====================================================================
     V1.5 — GROUPED NAVIGATION, HOME BRIEFING, SETTINGS DESTINATION
     Composition only. No new colour system: every rule below uses tokens
     that already existed, so all six themes pick these surfaces up without
     a single theme-specific component rule (spec 03).
     ===================================================================== */
  .main-nav { display: flex; flex-wrap: wrap; gap: 6px 22px; align-items: flex-end;
    margin: 0 0 22px; padding-bottom: 12px; border-bottom: 1px solid var(--border-soft); }
  .nav-group { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
  .nav-group-label { font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--ink-faint); padding-left: 2px; }
  .nav-group-items { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
  .main-tab-btn.nav-secondary { opacity: 0.7; }
  .main-tab-btn.nav-secondary.active { opacity: 1; }

  /* Home briefing. Open canvas, no nested cards, generous vertical rhythm. */
  .home-brief { max-width: 720px; padding: 8px 0 40px; }
  .hb-greeting { font-size: 26px; letter-spacing: 0.06em; color: var(--ink-strong); }
  .hb-date { font-size: 13px; color: var(--ink-soft); margin-top: 4px; }
  .hb-focus { margin-top: 24px; font-size: 14px; color: var(--ink); }
  .hb-focus-label { font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-faint); margin-right: 8px; }
  .hb-now { margin-top: 28px; }
  .hb-now-label { font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-faint); }
  .hb-now-body { margin-top: 6px; display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; }
  .hb-now-time { font-family: var(--mono); font-size: 15px; color: var(--cyan-bright); }
  .hb-now-title { font-size: 17px; color: var(--ink-strong); overflow-wrap: anywhere; }
  .hb-primary { margin-top: 30px; }
  .hb-primary-btn { min-height: 44px; padding: 0 22px; font-size: 14px; }
  .hb-showing { margin-top: 34px; }
  .hb-showing-label { font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-faint); margin-bottom: 10px; }
  .hb-showing-row { display: flex; gap: 10px; flex-wrap: wrap; }
  .hb-chip { display: inline-flex; align-items: baseline; gap: 7px; padding: 8px 12px;
    border: 1px solid var(--border-soft); border-radius: 4px; font-size: 11.5px; color: var(--ink-soft); }
  .hb-chip strong { font-family: var(--mono); font-size: 14px; color: var(--ink); font-weight: 600; }
  .hb-relevant { margin-top: 34px; display: flex; flex-direction: column; gap: 8px; }
  .hb-rel-item { font-size: 13.5px; color: var(--ink-soft); }
  /* Incomplete is neutral; gold is reserved for something that actually needs a decision. */
  .hb-rel-attention { color: var(--ink); border-left: 2px solid var(--gold); padding-left: 10px; }
  .hb-quiet { font-size: 13.5px; color: var(--ink-soft); }
  .hb-apex { margin-top: 30px; }

  /* Settings destination */
  .set-section { max-width: 760px; margin: 0 0 40px; }
  .set-section-title { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-faint); padding-bottom: 10px; margin-bottom: 4px; border-bottom: 1px solid var(--border-soft); }
  .set-row { display: flex; gap: 20px; justify-content: space-between; align-items: flex-start;
    flex-wrap: wrap; padding: 18px 0; border-bottom: 1px solid var(--border-soft); }
  .set-row:last-child { border-bottom: none; }
  .set-row-stack { flex-direction: column; align-items: stretch; }
  .set-row-copy { min-width: 0; flex: 1 1 260px; }
  .set-row-label { font-size: 14px; color: var(--ink-strong); }
  .set-row-help { font-size: 12px; color: var(--ink-faint); margin-top: 4px; line-height: 1.55; max-width: 52ch; }
  .set-row-actions { display: flex; gap: 10px; flex-wrap: wrap; }
  .set-row-actions .btn, .set-row-actions .interest-btn { min-height: 44px; }
  .set-row-note { font-size: 12px; color: var(--ink-faint); padding: 0 0 14px; min-height: 1px; }
  .set-note-ok { color: var(--green); }
  .set-note-err { color: var(--red); }
  .set-about { font-size: 13px; color: var(--ink-soft); line-height: 1.65; max-width: 58ch; }
  .set-about p { margin: 6px 0 14px; }
  .set-about-name { font-size: 16px; color: var(--ink-strong); letter-spacing: 0.04em; }
  .set-about-h { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); margin-top: 10px; }
  .set-about-links { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12px; margin-top: 16px; }
  .set-about-links a { color: var(--cyan); }
  .set-about-version { font-size: 11px; color: var(--ink-faint); margin-top: 14px; letter-spacing: 0.08em; }

  /* Explicit user preference, layered on top of prefers-reduced-motion (never the reverse). */
  .force-reduced-motion *, .force-reduced-motion *::before, .force-reduced-motion *::after {
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important; scroll-behavior: auto !important;
  }

  @media (max-width: 700px) {
    .main-nav { gap: 6px 14px; }
    .home-brief { padding-bottom: 32px; }
    .hb-greeting { font-size: 21px; }
    .set-row { flex-direction: column; }
  }

  /* Travel trip-first landing (V1.5) */
  .trav-lead { padding: 4px 0 26px; }
  .trav-lead-when { font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--cyan); }
  .trav-lead-dest { font-size: 24px; color: var(--ink-strong); margin-top: 6px; overflow-wrap: anywhere; }
  .trav-lead-dates { font-family: var(--mono); font-size: 12.5px; color: var(--ink-soft); margin-top: 6px; }
  .trav-lead-empty { font-size: 15px; color: var(--ink-soft); }
  .trav-lead-actions { margin-top: 16px; }
  .trav-lead-actions .btn { min-height: 44px; padding: 0 20px; }

  /* =====================================================================
     STAGE 10 — MOBILE NAVIGATION, TABLET, WIDE-TOUCH (Tesla)
     ===================================================================== */
  .mnav { display: none; }
  .more-sheet { display: none; }

  @media (max-width: 860px) {
    /* Mobile is its own layout, not a narrowed desktop: the grouped rail is replaced by a
       thumb-reachable bar rather than being wrapped into six scrolling rows. */
    .main-nav { display: none; }
    .mnav {
      display: grid; grid-template-columns: repeat(5, 1fr);
      position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
      background: var(--panel); border-top: 1px solid var(--border);
      padding-bottom: env(safe-area-inset-bottom, 0px);
    }
    .mnav-btn {
      display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
      min-height: 56px; padding: 8px 4px; background: none; border: 0; cursor: pointer;
      color: var(--ink-faint); font-family: inherit;
    }
    .mnav-btn.active { color: var(--cyan-bright); }
    .mnav-ico { font-size: 15px; line-height: 1; }
    .mnav-lbl { font-size: 10px; letter-spacing: 0.04em; }
    /* Content clears the bar. Without this the last control on every screen sits under it. */
    body { padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
    .apex-fab { bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }

    .more-sheet { display: block; position: fixed; inset: 0; z-index: 70; }
    .more-sheet-scrim { position: absolute; inset: 0; background: rgba(0,0,0,0.55); }
    .more-sheet-panel {
      position: absolute; left: 0; right: 0; bottom: 0; max-height: 78vh;
      display: flex; flex-direction: column;
      background: var(--panel); border-top: 1px solid var(--border);
      border-radius: 10px 10px 0 0; padding-bottom: env(safe-area-inset-bottom, 0px);
    }
    .more-sheet-head { display: flex; align-items: center; justify-content: space-between;
      padding: 14px 16px; border-bottom: 1px solid var(--border-soft); }
    .more-sheet-title { font-size: 14px; color: var(--ink-strong); }
    /* The sheet is the ONLY scroller here — no scroll container inside another. */
    .more-sheet-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 8px 8px 16px; }
    .more-group { padding: 8px 0; }
    .more-group-label { font-size: 9px; letter-spacing: 0.18em; text-transform: uppercase;
      color: var(--ink-faint); padding: 6px 12px; }
    .more-item { display: block; width: 100%; text-align: left; min-height: 48px;
      padding: 12px 14px; background: none; border: 0; border-radius: 6px;
      color: var(--ink); font-size: 15px; font-family: inherit; cursor: pointer; }
    .more-item:active { background: var(--panel-raised); }

    /* Apex on mobile is a destination, not a floating panel pinned over the app. */
    .apex-panel {
      position: fixed; inset: 0; width: 100%; max-width: none; height: 100%;
      max-height: none; border-radius: 0; border: 0; z-index: 80;
    }
    .ai-shell { height: 100%; display: flex; flex-direction: column; }
    .ai-messages { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
    /* Keyboard-safe: the composer rides above the on-screen keyboard instead of being covered. */
    .ai-input-row { position: sticky; bottom: 0; background: var(--panel);
      padding-bottom: env(safe-area-inset-bottom, 0px); }
    .ai-input { font-size: 16px; }   /* 16px stops iOS Safari zooming the page on focus */
    input, select, textarea { font-size: 16px; }
  }

  @media (max-width: 860px) and (max-height: 460px) {
    /* Landscape phone / keyboard open: give the conversation the room instead of the chrome. */
    .apex-home-greeting { display: none; }
  }

  /* Tablet portrait: the grouped rail still fits, with more air between groups. */
  @media (min-width: 861px) and (max-width: 1100px) {
    .main-nav { gap: 8px 18px; }
    .main-tab-btn { min-height: 44px; }
  }

  /* Wide touch (Tesla-class): the same Life OS, sized for a fingertip in a parked car —
     larger targets, lower density, no hover dependency. Never a separate mode. */
  @media (min-width: 1100px) and (pointer: coarse), (min-width: 1600px) and (hover: none) {
    .main-tab-btn, .home-nav-btn, .life-nav-btn, .trav-nav-btn,
    .btn, .interest-btn, .mnav-btn { min-height: 48px; }
    .main-tab-btn { padding: 0 18px; font-size: 14px; }
    .home-brief { max-width: 820px; }
    .hb-primary-btn { min-height: 52px; font-size: 15px; }
    .set-row { padding: 22px 0; }
    /* Nothing may depend on hover to be discoverable on a touch screen. */
    .more-item:hover, .main-tab-btn:hover { background: none; }
  }

  /* =====================================================================
     STAGE 11 — RESTRAINED PREMIUM DARK (editorial/technical)
     Composition and restraint only. No new palette: the six themes keep
     their own tokens and simply inherit the calmer hierarchy below, so
     every theme maps to one semantic system rather than one per theme.
     ===================================================================== */

  /* 1. Glow is punctuation, not atmosphere. Frost blue stays for active,
        primary and Apex states; everything else stops radiating. */
  .module-title { text-shadow: none; }
  .brand-title { text-shadow: none; }
  .journal-header-copy .journal-title { text-shadow: none; letter-spacing: 0.02em; }

  /* 2. Micro-labels: keep the tracking, drop the shout. A label that names a
        module does not need to be uppercase to be understood as a label. */
  .module-title, .fin-title, .set-row-label, .more-sheet-title {
    text-transform: none;
  }

  /* 3. Open canvas by default. A panel earns its border when it groups
        something; a lone panel around one figure is a box for its own sake. */
  .panel { border-radius: 4px; }
  .home-brief, .set-section { background: none; border: 0; }

  /* 4. Red is reserved for a real problem or a destructive action. Anything
        merely incomplete or behind is neutral — Life OS does not scold. */
  .hb-rel-item { color: var(--ink-soft); }

  /* 5. Motion explains a state change; it never decorates an idle screen.
        The user setting layers on top of the system preference, never under. */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.001ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.001ms !important;
    }
  }

  /* V1.5.1 — deliberate detail disclosures on Insights / Finance / Travel landings. */
  .ins-deeper { padding: 18px 0 6px; }
  .ins-deeper .muted-link { min-height: 44px; }

/* =====================================================================
   BLACK FROST EDITORIAL — V1.6 VISUAL POLISH
   Visual-only refinement of the released V1.5 architecture.
   Doctrine: Quiet by default. Frost when active. Space with purpose.
   Typography over boxes. Meaning over metrics.
   ===================================================================== */

:root {
  --bg: #050A10;
  --panel: #0C121A;
  --panel-raised: #111923;
  --border: rgba(104, 170, 232, 0.18);
  --border-soft: rgba(151, 190, 226, 0.10);
  --cyan: #38B2FF;
  --cyan-bright: #A5E3FF;
  --cyan-dim: #6B8CA8;
  --ink: #E8EEF4;
  --ink-soft: #9AA9B8;
  --ink-faint: #708091;
  --ink-strong: #F8FAFC;
  --green: #22C55E;
  --red: #EF4444;
  --gold: #F59E0B;
  --on-accent: #04121C;
  --cyan-glow-rgb: 56, 178, 255;
  /* V4 theme repair: surface channels, so translucent Black Frost surfaces follow the theme. */
  --bg-rgb: 5, 10, 16;
  --panel-rgb: 12, 18, 26;
  --panel-raised-rgb: 17, 25, 35;
  --hairline-rgb: 151, 190, 226;
  --border-rgb: 104, 170, 232;
  --muted-fill-rgb: 154, 169, 184;
  --overlay-rgb: 2, 7, 12;
  --shadow-rgb: 0, 0, 0;
  --shadow-card: 0 16px 50px rgba(0,0,0,.18);

  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-lg: 16px;
  --space-xl: 24px;
  --space-2xl: 32px;
  --space-3xl: 48px;
  --space-4xl: 64px;
  --radius-sm: 8px;
  --radius-md: 10px;
  --radius-lg: 12px;
}

html { background: var(--bg); }
body {
  min-height: 100vh;
  background: var(--bg);
  background-image:
    radial-gradient(800px 520px at 28% -8%, rgba(var(--cyan-glow-rgb), .055), transparent 62%);
  color: var(--ink);
  font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  letter-spacing: 0;
  line-height: 1.48;
}

/* Human-first typography; mono is reserved for actual data. */
button, input, select, textarea { font-family: inherit; }
.stat-value, .module-code, .hb-now-time, .fin-value, .money, .mono,
input[type="time"], input[type="date"], input[type="number"] {
  font-family: var(--mono);
}

/* ---------- Desktop editorial shell / sidebar ---------- */
.wrap {
  max-width: none;
  margin: 0;
  min-height: 100vh;
  padding: 48px 48px 80px 296px;
}
.header {
  position: fixed;
  z-index: 45;
  left: 0;
  top: 0;
  width: 248px;
  height: 76px;
  padding: 22px 24px 14px;
  margin: 0;
  display: flex;
  align-items: center;
  border: 0;
  background: rgba(var(--bg-rgb),.94);
  backdrop-filter: blur(14px);
}
.brand { gap: 12px; min-width: 0; }
.brand-mark {
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 9px;
  transform: none;
  box-shadow: none;
  background: url('assets/mighty-life-os-logo.png') center / cover no-repeat;
}
.brand-greeting-line, .header-stats { display: none !important; }
.brand-title {
  color: var(--ink-strong);
  font-size: 15px;
  line-height: 1.15;
  font-weight: 700;
  letter-spacing: -.01em;
  text-transform: none;
  white-space: nowrap;
}

.main-nav {
  position: fixed;
  z-index: 44;
  left: 0;
  top: 76px;
  bottom: 0;
  width: 248px;
  padding: 8px 18px 24px;
  margin: 0;
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 26px;
  overflow-y: auto;
  background: rgba(var(--bg-rgb),.94);
  border: 0;
  border-right: 1px solid rgba(var(--hairline-rgb),.08);
  backdrop-filter: blur(14px);
}
.main-nav::after {
  content: "Part of the Mighty Ecosystem";
  margin-top: auto;
  padding: 22px 10px 2px;
  border-top: 1px solid var(--border-soft);
  color: var(--ink-faint);
  font-size: 11px;
  line-height: 1.35;
}
.nav-group { display: flex; flex-direction: column; gap: 8px; }
.nav-group-label {
  padding: 0 10px;
  color: var(--ink-faint);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.nav-group-items { display: flex; flex-direction: column; gap: 2px; }
.main-tab-btn {
  width: 100%;
  min-height: 42px;
  padding: 0 10px;
  display: flex;
  align-items: center;
  gap: 12px;
  background: transparent;
  border: 0;
  border-radius: 8px;
  color: var(--ink-soft);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  text-align: left;
  transition: color .15s ease, background .15s ease;
}
.main-tab-btn::after { display: none; }
.main-tab-btn::before {
  position: static;
  width: 20px;
  height: auto;
  border: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-faint);
  font: 16px/1 ui-sans-serif, system-ui, sans-serif;
  content: "•";
}
#mainTabHomeBtn::before{content:"⌂"} #mainTabTodayBtn::before{content:"◷"}
#mainTabScheduleBtn::before{content:"▦"} #mainTabProgressBtn::before{content:"◉"}
#mainTabFitnessBtn::before{content:"♡"} #mainTabLearningBtn::before{content:"◇"}
#mainTabFinanceBtn::before{content:"$"} #mainTabTravelBtn::before{content:"✈"}
#mainTabLifeBtn::before{content:"☼"} #mainTabJournalBtn::before{content:"▤"}
#mainTabInsightsBtn::before{content:"◈"} #mainTabInboxBtn::before{content:"▱"}
#mainTabSettingsBtn::before{content:"⚙"}
.main-tab-btn:hover { color: var(--ink-strong); background: rgba(255,255,255,.025); }
.main-tab-btn.active {
  color: var(--ink-strong);
  border: 0;
  background: rgba(var(--cyan-glow-rgb), .095);
  text-shadow: none;
  box-shadow: inset 2px 0 0 var(--cyan);
}
.main-tab-btn.active::before { color: var(--cyan); }
.main-tab-btn.nav-secondary { opacity: .78; }

/* The dedicated Settings destination replaces the old floating consumer gear. */
#devicePreviewToolbar { display: none; }
body.dev-tools-on #devicePreviewToolbar { display: block; }

.tab-panel { width: min(100%, 1120px); margin: 0; }
#mainTabFinance, #mainTabInsights { width: min(100%, 1240px); }
#mainTabJournal, #mainTabSettings { width: min(100%, 820px); }

/* ---------- Shared editorial typography ---------- */
.fin-header {
  align-items: flex-start;
  gap: 20px;
  margin-bottom: 36px;
}
.fin-title {
  color: var(--ink-strong);
  font-size: clamp(28px, 2.4vw, 36px);
  line-height: 1.15;
  font-weight: 750;
  letter-spacing: -.025em;
  text-transform: none;
  text-shadow: none;
}
.fin-subtitle {
  margin-top: 7px;
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.5;
}
.module-title {
  color: var(--ink-strong);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -.01em;
  text-transform: none;
}
.module-code {
  color: var(--ink-faint);
  letter-spacing: .04em;
  text-transform: none;
}

/* ---------- Surfaces: containment is earned ---------- */
.panel {
  background: var(--panel);
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  box-shadow: none;
}
.panel::before, .panel::after { display: none; }
.btn, .interest-btn, .muted-link, .mini-refresh, .icon-btn {
  border-radius: 9px;
}
.btn {
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid rgba(var(--cyan-glow-rgb), .45);
  background: rgba(var(--cyan-glow-rgb), .16);
  color: var(--ink-strong);
  font-weight: 650;
  box-shadow: none;
}
.btn:hover { background: rgba(var(--cyan-glow-rgb), .23); border-color: rgba(var(--cyan-glow-rgb), .7); }
.interest-btn {
  min-height: 44px;
  padding: 0 16px;
  background: var(--panel-raised);
  border: 1px solid var(--border-soft);
  color: var(--ink);
}
.muted-link { color: var(--ink-soft); }
input[type=text], input[type=number], input[type=date], input[type=time], textarea, select {
  min-height: 46px;
  padding: 10px 12px;
  background: rgba(var(--panel-raised-rgb),.78);
  border: 1px solid var(--border-soft);
  border-radius: 9px;
  color: var(--ink);
}
input:focus-visible, textarea:focus-visible, select:focus-visible,
button:focus-visible, a:focus-visible, [role="button"]:focus-visible {
  outline: 2px solid rgba(var(--cyan-glow-rgb), .9);
  outline-offset: 3px;
  box-shadow: 0 0 0 4px rgba(var(--cyan-glow-rgb), .08);
}

/* ---------- Home: briefing, not dashboard ---------- */
.home-brief {
  width: min(100%, 1040px);
  max-width: none;
  padding: 14px 0 72px;
}
.hb-greeting {
  color: var(--ink-strong);
  font-size: clamp(30px, 3vw, 38px);
  line-height: 1.12;
  font-weight: 760;
  letter-spacing: -.03em;
}
.hb-date { margin-top: 8px; color: var(--ink-soft); font-size: 15px; }
.hb-focus {
  margin-top: 12px;
  color: var(--ink);
  font-size: 14px;
}
.hb-focus-label {
  margin-right: 5px;
  color: var(--ink-faint);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}
.hb-now { margin-top: 48px; }
.hb-now-label, .hb-showing-label {
  margin-bottom: 13px;
  color: var(--ink-strong);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
  text-transform: none;
}
.hb-now-body {
  min-height: 68px;
  margin-top: 0;
  padding: 16px 18px;
  display: grid;
  grid-template-columns: 92px 1fr;
  align-items: center;
  gap: 16px;
  background: rgba(var(--panel-rgb),.82);
  border: 1px solid var(--border-soft);
  border-left: 2px solid var(--cyan);
  border-radius: 11px;
}
.hb-now-time { color: var(--cyan-bright); font-size: 14px; }
.hb-now-title { color: var(--ink-strong); font-size: 16px; font-weight: 650; }
.hb-primary {
  margin-top: 38px;
  padding-bottom: 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  border-bottom: 1px solid var(--border-soft);
}
.hb-primary::before {
  content: "Today";
  color: var(--ink-strong);
  font-size: 20px;
  font-weight: 720;
  letter-spacing: -.015em;
}
.hb-primary-btn { min-height: 44px; padding: 0 18px; font-size: 14px; }
.hb-showing {
  margin-top: 40px;
  padding-bottom: 40px;
  border-bottom: 1px solid var(--border-soft);
}
.hb-showing-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 26px;
}
.hb-chip {
  min-width: 0;
  padding: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 9px;
  align-items: baseline;
  background: transparent;
  border: 0;
  border-radius: 0;
  color: var(--ink-soft);
  font-size: 13px;
}
.hb-chip::after {
  content: "";
  grid-column: 1 / -1;
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(var(--cyan-glow-rgb),.72), rgba(var(--cyan-glow-rgb),.18));
}
.hb-chip strong { color: var(--ink-strong); font-size: 15px; }
.hb-relevant { margin-top: 36px; gap: 10px; }
.hb-rel-item, .hb-quiet { font-size: 14px; line-height: 1.55; }
.hb-rel-attention { padding-left: 12px; border-left-color: var(--gold); }
.hb-apex { margin-top: 28px; }
.hb-apex .muted-link { padding-left: 0; }

/* ---------- Today: premium day sheet ---------- */
#mainTabToday .fin-header { margin-bottom: 30px; }
#mainTabToday .fin-subtitle { font-size: 0; }
#mainTabToday .fin-subtitle::after { content: "Move through what matters, one thing at a time."; font-size: 14px; }
#mainTabToday .module-code { font-size: 12px; }
.td-section {
  margin: 0;
  padding: 28px 0;
  border-top: 1px solid var(--border-soft);
}
#tdNowSection { border-top: 0; padding-top: 0; }
.td-section-label {
  color: var(--ink-strong);
  font-size: 16px;
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: -.01em;
  text-transform: none;
}
.td-section-head { align-items: baseline; margin-bottom: 8px; }
.td-section-note { color: var(--ink-faint); font-size: 12px; }
.td-attn-row, .td-done-row {
  min-height: 50px;
  padding: 11px 4px;
  gap: 12px;
  border-bottom: 1px solid var(--border-soft);
  background: transparent !important;
}
.td-attn-row:hover { background: rgba(255,255,255,.018) !important; }
.td-attn-text, .td-done-text { color: var(--ink); font-size: 14px; }
.td-attn-meta { margin-top: 3px; color: var(--ink-faint); font-size: 12px; }
.td-add { margin-top: 18px; gap: 10px; }
.td-task-input { min-width: 220px; }
.td-add-detail { margin-top: 10px; gap: 10px; }
.td-completed { padding-bottom: 0; }
.td-completed-toggle {
  min-height: 44px;
  color: var(--ink-soft);
  background: transparent;
  border: 0;
  padding: 0;
}

/* ---------- Settings: quiet system preferences ---------- */
.set-section { max-width: 820px; margin: 0 0 46px; }
.set-section-title {
  margin-bottom: 8px;
  color: var(--ink-strong);
  font-size: 18px;
  font-weight: 720;
  letter-spacing: -.01em;
  text-transform: none;
}
.set-row { padding: 20px 0; border-bottom: 1px solid var(--border-soft); }
.set-row-label { color: var(--ink); font-size: 15px; font-weight: 650; letter-spacing: 0; }
.set-row-help { margin-top: 5px; color: var(--ink-faint); line-height: 1.55; }
.set-about { color: var(--ink-soft); line-height: 1.65; }
.set-about-name { color: var(--ink-strong); font-size: 20px; font-weight: 720; }

/* ---------- Apex: intelligence carries more frost than the canvas ---------- */
.apex-fab {
  right: 28px;
  bottom: 28px;
  min-height: 46px;
  padding: 0 18px;
  background: rgba(var(--panel-rgb),.94);
  border: 1px solid rgba(var(--cyan-glow-rgb), .30);
  border-radius: 11px;
  color: var(--cyan-bright);
  font-family: inherit;
  font-size: 13px;
  font-weight: 650;
  letter-spacing: 0;
  text-transform: none;
  box-shadow: 0 14px 42px rgba(0,0,0,.30);
}
.apex-fab-dot { box-shadow: none; }
.apex-panel {
  right: 28px;
  bottom: 88px;
  width: 420px;
  height: min(720px, calc(100vh - 120px));
  max-height: calc(100vh - 120px);
  padding: 20px;
  background: #09131D;
  border: 1px solid rgba(var(--cyan-glow-rgb), .25);
  border-radius: 14px;
  box-shadow: 0 24px 70px rgba(0,0,0,.42);
}
.apex-routine-btn {
  min-height: 46px;
  padding: 11px 13px;
  background: rgba(var(--panel-raised-rgb),.72);
  border: 1px solid var(--border-soft);
  border-radius: 9px;
  font-family: inherit;
}

/* ---------- Bottom nav / phone reinterpretation ---------- */
.mnav { display: none; }
@media (max-width: 860px) {
  body {
    background-image: radial-gradient(520px 340px at 25% -5%, rgba(var(--cyan-glow-rgb), .05), transparent 64%);
    padding-bottom: calc(68px + env(safe-area-inset-bottom, 0px));
  }
  .wrap {
    min-height: 100vh;
    padding: 18px max(18px, env(safe-area-inset-right)) 92px max(18px, env(safe-area-inset-left));
  }
  .header {
    position: static;
    width: auto;
    height: auto;
    padding: 0;
    margin: 0 0 26px;
    background: transparent;
    backdrop-filter: none;
  }
  .brand { gap: 0; }
  .brand-mark { width: 32px; height: 32px; border-radius: 9px; }
  .brand-title { display: none; }
  .main-nav { display: none; }
  .tab-panel, #mainTabFinance, #mainTabInsights, #mainTabJournal, #mainTabSettings { width: 100%; }

  .home-brief { width: 100%; padding: 4px 0 36px; }
  .hb-greeting { font-size: 26px; }
  .hb-date { margin-top: 6px; font-size: 13px; }
  .hb-focus { margin-top: 10px; font-size: 13px; }
  .hb-now { margin-top: 30px; }
  .hb-now-label, .hb-showing-label { margin-bottom: 10px; font-size: 15px; }
  .hb-now-body { min-height: 64px; grid-template-columns: 74px 1fr; padding: 14px; gap: 10px; }
  .hb-now-time { font-size: 12px; }
  .hb-now-title { font-size: 14px; }
  .hb-primary { margin-top: 28px; padding-bottom: 30px; align-items: center; }
  .hb-primary::before { font-size: 18px; }
  .hb-primary-btn { min-height: 48px; padding: 0 16px; }
  .hb-showing { margin-top: 30px; padding-bottom: 30px; }
  .hb-showing-row { grid-template-columns: 1fr; gap: 18px; }
  .hb-relevant { margin-top: 28px; }

  .fin-header { margin-bottom: 28px; }
  .fin-title { font-size: 28px; }
  .fin-subtitle { font-size: 13px; }
  .td-section { padding: 23px 0; }
  .td-attn-row, .td-done-row { min-height: 52px; padding: 12px 2px; }
  .td-add { display: grid; grid-template-columns: 1fr auto; }
  .td-add .muted-link { grid-column: 1 / -1; justify-self: start; }
  .td-task-input { min-width: 0; }

  .mnav {
    display: grid;
    min-height: calc(64px + env(safe-area-inset-bottom, 0px));
    background: rgba(var(--bg-rgb),.96);
    border-top: 1px solid var(--border-soft);
    backdrop-filter: blur(18px);
  }
  .mnav-btn { min-height: 64px; gap: 4px; color: var(--ink-faint); }
  .mnav-btn.active { color: var(--cyan-bright); }
  .mnav-ico { font-size: 18px; }
  .mnav-lbl { font-size: 11px; font-weight: 600; letter-spacing: 0; }

  .more-sheet-panel {
    background: #091018;
    border-top-color: var(--border-soft);
    border-radius: 16px 16px 0 0;
  }
  .more-sheet-head { padding: 18px; }
  .more-sheet-body { padding: 8px 10px 22px; }
  .more-item { min-height: 52px; border-radius: 9px; }

  .apex-fab { display: none; }
  .apex-panel {
    inset: 0;
    width: 100%;
    height: 100%;
    max-height: none;
    padding: max(18px, env(safe-area-inset-top)) 18px max(18px, env(safe-area-inset-bottom));
    border: 0;
    border-radius: 0;
  }
}

/* Compact tablet keeps the rail but trims the canvas gently. */
@media (min-width: 861px) and (max-width: 1100px) {
  .wrap { padding-left: 272px; padding-right: 28px; }
  .header, .main-nav { width: 224px; }
  .main-tab-btn { min-height: 44px; padding: 0 8px; font-size: 13px; }
  .home-brief { width: 100%; }
}

/* Wide touch / Tesla: same product, larger targets, lower density. */
@media (min-width: 1100px) and (pointer: coarse), (min-width: 1600px) and (hover: none) {
  .wrap { padding-left: 328px; padding-right: 64px; }
  .header, .main-nav { width: 276px; }
  .main-tab-btn { min-height: 50px; font-size: 15px; }
  .home-brief { width: min(100%, 1120px); }
  .td-attn-row, .td-done-row { min-height: 56px; }
  .btn, .interest-btn { min-height: 52px; }
}

/* Reduced motion remains authoritative. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .001ms !important; animation-duration: .001ms !important; }
}

/* =====================================================================
   BLACK FROST V1.6.1 — DESKTOP SCALE + MIGHTY SHELL POLISH
   ===================================================================== */

/* Stacked settings rows must not inherit the horizontal row's flex-basis.
   That old 260px basis was the source of the large blank gaps visible on
   desktop between the label/help copy and the controls. */
.set-row-stack > .set-row-copy { flex: 0 0 auto; width: 100%; }
#setModulePrefsBody,
#setThemeOptions {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 4px;
}
#setModulePrefsBody .module-pref-row,
#setThemeOptions .theme-opt {
  min-height: 58px;
  padding: 11px 12px;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: rgba(var(--panel-rgb),.46);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 13px;
}
#setModulePrefsBody .module-pref-row {
  display: grid;
  grid-template-columns: 22px 24px 1fr;
  align-items: center;
  gap: 8px;
}
#setModulePrefsBody .module-pref-row:hover,
#setThemeOptions .theme-opt:hover { background: rgba(var(--panel-raised-rgb),.78); color: var(--ink); }
#setModulePrefsBody .module-pref-row.on {
  border-color: rgba(var(--cyan-glow-rgb), .26);
  background: rgba(var(--cyan-glow-rgb), .055);
  color: var(--ink-strong);
}
#setModulePrefsBody .fr-module-check {
  color: var(--ink-faint);
  font-family: var(--mono);
  font-size: 11px;
}
#setModulePrefsBody .module-pref-row.on .fr-module-check { color: var(--cyan-bright); }
#setThemeOptions .theme-opt.active {
  border-color: rgba(var(--cyan-glow-rgb), .34);
  background: rgba(var(--cyan-glow-rgb), .07);
}
#setThemeOptions .theme-opt-label { font-family: inherit; font-size: 13px; font-weight: 650; color: var(--ink-strong); }
#setThemeOptions .theme-opt-hint { font-family: inherit; font-size: 11px; color: var(--ink-faint); }
#setThemeOptions .theme-swatch { width: 28px; height: 28px; border-radius: 8px; }

/* Settings is still a reading surface, but desktop should use the available
   monitor width instead of looking like a narrow mobile column on a 27–34” display. */
#mainTabSettings { width: min(100%, 1040px); }
#mainTabSettings .set-section { max-width: 1040px; }

/* Canonical Mighty footer: same hierarchy used by the focused sibling apps. */
.main-nav::after { content: none; }
.nav-footer {
  margin-top: auto;
  padding: 18px 8px 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.nav-footer-link {
  min-height: 38px;
  padding: 0 4px;
  border: 0;
  background: transparent;
  color: var(--ink-faint);
  font: 500 12px/1.2 inherit;
  text-align: left;
  cursor: pointer;
}
.nav-footer-link:hover,
.nav-footer-link.active { color: var(--ink-strong); }
.nav-footer-link.active { color: var(--cyan-bright); }
.nav-footer-divider { height: 1px; margin: 12px 0 14px; background: var(--border-soft); }
.nav-footer-signature {
  padding: 0 4px 4px;
  color: var(--ink-faint);
  font-size: 9px;
  font-weight: 650;
  letter-spacing: .18em;
  line-height: 1.5;
}

/* About */
#mainTabAbout { width: min(100%, 1120px); }
.about-page { padding: 6px 0 72px; }
.about-hero {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-bottom: 36px;
  border-bottom: 1px solid var(--border-soft);
}
.about-logo { width: 72px; height: 72px; border-radius: 18px; flex: 0 0 auto; }
.about-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 48px;
  margin-top: 8px;
}
.about-block { padding: 34px 0; border-bottom: 1px solid var(--border-soft); }
.about-kicker,
.eco-kicker {
  color: var(--cyan-bright);
  font-size: 10px;
  font-weight: 750;
  letter-spacing: .16em;
}
.about-block h2 { margin: 10px 0 10px; color: var(--ink-strong); font-size: 20px; line-height: 1.3; letter-spacing: -.015em; }
.about-block p { margin: 0; max-width: 58ch; color: var(--ink-soft); font-size: 14px; line-height: 1.7; }
.about-version-line { margin-top: 28px; color: var(--ink-faint); font-size: 11px; letter-spacing: .05em; }

/* Mighty Ecosystem — canonical category structure. */
#mainTabEcosystem { width: min(100%, 1280px); }
.ecosystem-page { padding: 6px 0 84px; }
.eco-hero { max-width: 720px; margin-bottom: 48px; }
.eco-hero .fin-title { margin-top: 9px; }
.eco-hero p { margin: 12px 0 0; color: var(--ink-soft); font-size: 15px; line-height: 1.65; }
.eco-section { padding: 30px 0 34px; border-top: 1px solid var(--border-soft); }
.eco-section-head { margin-bottom: 18px; }
.eco-section-title { color: var(--ink-strong); font-size: 18px; font-weight: 720; letter-spacing: -.01em; }
.eco-section-sub { margin-top: 4px; color: var(--ink-faint); font-size: 12px; }
.eco-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.eco-grid-four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.eco-grid-single { grid-template-columns: minmax(280px, 1fr); max-width: 420px; }
.eco-card {
  min-height: 94px;
  padding: 15px;
  display: grid;
  grid-template-columns: 52px 1fr auto;
  align-items: center;
  gap: 13px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: rgba(var(--panel-rgb),.52);
  color: inherit;
  text-decoration: none;
  transition: background .15s ease, border-color .15s ease, transform .15s ease;
}
.eco-card:hover { background: rgba(var(--panel-raised-rgb),.84); border-color: rgba(var(--cyan-glow-rgb), .24); transform: translateY(-1px); }
.eco-card img { width: 52px; height: 52px; border-radius: 13px; object-fit: cover; }
.eco-card > span:nth-child(2) { min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.eco-card strong { color: var(--ink-strong); font-size: 14px; font-weight: 700; }
.eco-card small { color: var(--ink-faint); font-size: 11px; line-height: 1.4; }
.eco-arrow { color: var(--ink-faint); font-size: 15px; }
.eco-card-current {
  cursor: default;
  background: rgba(var(--cyan-glow-rgb), .07);
  border-color: rgba(var(--cyan-glow-rgb), .30);
}
.eco-card-current:hover { transform: none; background: rgba(var(--cyan-glow-rgb), .07); }
.eco-card-current em {
  margin-left: 7px;
  color: var(--cyan-bright);
  font-size: 9px;
  font-style: normal;
  letter-spacing: .08em;
  white-space: nowrap;
}
.eco-footer-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 26px; }
.eco-footer-card {
  min-height: 74px;
  padding: 14px 16px;
  display: grid;
  grid-template-columns: 38px 1fr auto;
  gap: 12px;
  align-items: center;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: rgba(var(--panel-rgb),.38);
  color: inherit;
  text-decoration: none;
}
.eco-footer-card:hover { background: rgba(var(--panel-raised-rgb),.72); }
.eco-footer-card > span:nth-child(2) { display: flex; flex-direction: column; gap: 3px; }
.eco-footer-card strong { color: var(--ink-strong); font-size: 13px; }
.eco-footer-card small { color: var(--ink-faint); font-size: 11px; }
.eco-footer-icon {
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 1px solid rgba(var(--cyan-glow-rgb), .26); border-radius: 10px;
  color: var(--cyan-bright); font-size: 11px; font-weight: 750;
}

/* Data management was functionally correct but visually retained the old utility-modal density. */
#dataMgmtOverlay .data-management-modal {
  max-width: 700px;
  border-radius: 14px;
  background: #091119;
  border-color: rgba(var(--cyan-glow-rgb), .18);
  box-shadow: 0 30px 90px rgba(0,0,0,.50);
}
#dataMgmtOverlay .data-management-head { padding: 20px 22px; }
.data-management-subtitle { margin-top: 5px; color: var(--ink-faint); font-size: 12px; }
.data-management-close { width: 40px; height: 40px; flex: 0 0 auto; }
#dataMgmtOverlay .fit-modal-body { padding: 18px 22px 8px; }
#dataMgmtOverlay .fit-modal-foot { padding: 14px 22px 18px; border-top-color: var(--border-soft); }
#dataMgmtOverlay .dm-note { max-width: 68ch; font-size: 13px; line-height: 1.62; }
#dataMgmtOverlay .dm-section { margin-top: 0; padding: 24px 0; border-top: 1px solid var(--border-soft); }
#dataMgmtOverlay .dm-section:first-of-type { margin-top: 8px; padding-top: 24px; border-top: 1px solid var(--border-soft); }
#dataMgmtOverlay .dm-section-title {
  margin-bottom: 9px;
  color: var(--ink-strong);
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.005em;
  text-transform: none;
}
#dataMgmtOverlay .dm-section--danger { margin-top: 4px; }
#dataMgmtOverlay .dm-section--danger .dm-section-title { color: #FCA5A5; }
#dataMgmtOverlay .inline-form { gap: 10px; align-items: stretch; }
#dataMgmtOverlay .inline-form .input { min-height: 46px; }
.danger-secondary {
  border-color: rgba(239,68,68,.36) !important;
  background: rgba(239,68,68,.07) !important;
  color: #FCA5A5 !important;
}
.danger-secondary:hover { background: rgba(239,68,68,.12) !important; border-color: rgba(239,68,68,.52) !important; }
#dataMgmtOverlay .danger-btn { color: white; border-radius: 9px; }

/* Use more of a large desktop while preserving focused reading widths. */
@media (min-width: 1500px) and (pointer: fine) {
  .wrap { padding-left: 312px; padding-right: 64px; }
  .tab-panel { width: min(100%, 1320px); }
  #mainTabFinance, #mainTabInsights { width: min(100%, 1420px); }
  #mainTabHome .home-brief { width: min(100%, 1220px); }
  #mainTabSettings { width: min(100%, 1080px); }
  #mainTabSettings .set-section { max-width: 1080px; }
  #mainTabAbout { width: min(100%, 1180px); }
  #mainTabEcosystem { width: min(100%, 1360px); }
  #mainTabJournal { width: min(100%, 860px); }
}

@media (max-width: 1100px) {
  .eco-grid-four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .eco-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
  #setModulePrefsBody,
  #setThemeOptions { grid-template-columns: 1fr; gap: 8px; }
  .nav-footer { display: none; }
  .about-hero { align-items: flex-start; gap: 14px; padding-bottom: 28px; }
  .about-logo { width: 54px; height: 54px; border-radius: 14px; }
  .about-grid { grid-template-columns: 1fr; gap: 0; }
  .about-block { padding: 26px 0; }
  .eco-hero { margin-bottom: 32px; }
  .eco-section { padding: 24px 0 28px; }
  .eco-grid,
  .eco-grid-four,
  .eco-footer-grid { grid-template-columns: 1fr; }
  .eco-grid-single { max-width: none; }
  .eco-card { min-height: 82px; grid-template-columns: 46px 1fr auto; padding: 13px; }
  .eco-card img { width: 46px; height: 46px; border-radius: 12px; }
  #dataMgmtOverlay .data-management-modal { max-width: 100%; border-radius: 16px 16px 0 0; }
  #dataMgmtOverlay .inline-form { flex-direction: column; }
  #dataMgmtOverlay .inline-form > * { width: 100%; }
}

/* Black Frost 1.6.2 — keep the desktop sidebar scrollable without showing browser chrome. */
@media (min-width: 901px) {
  .main-nav {
    scrollbar-width: none;          /* Firefox */
    -ms-overflow-style: none;       /* legacy Edge/IE */
    overscroll-behavior: contain;
  }
  .main-nav::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;                  /* Chromium/Safari */
  }
}

/* =====================================================================
   BLACK FROST V1.6.3 — FINAL VISUAL MATURITY PASS
   Desktop maturity, compact ecosystem, and Apex operating-layer polish.
   ===================================================================== */

/* Wide desktop: let the OS use the monitor without stretching reading surfaces. */
@media (min-width: 1280px) and (pointer: fine) {
  .wrap { padding-left: 304px; padding-right: clamp(48px, 5vw, 92px); }
  .tab-panel { width: min(100%, 1280px); }
  #mainTabFinance, #mainTabInsights { width: min(100%, 1400px); }
  #mainTabJournal { width: min(100%, 820px); }
  #mainTabSettings, #mainTabAbout, #mainTabEcosystem { width: min(100%, 1180px); }
  .home-brief { width: min(100%, 1180px); }
}
@media (min-width: 1800px) and (pointer: fine) {
  .wrap { padding-right: clamp(72px, 7vw, 140px); }
  .tab-panel { width: min(100%, 1360px); }
  #mainTabFinance, #mainTabInsights { width: min(100%, 1480px); }
  .home-brief { width: min(100%, 1240px); }
}

/* Compact Mighty Ecosystem directory: recognition first, marketing second. */
#mainTabEcosystem { width: min(100%, 1120px); }
.ecosystem-page { padding: 4px 0 60px; }
.eco-hero { max-width: 640px; margin-bottom: 28px; }
.eco-hero p { margin-top: 9px; font-size: 14px; line-height: 1.55; }
.eco-section { padding: 20px 0 22px; }
.eco-section-head { margin-bottom: 12px; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.eco-section-title { font-size: 16px; }
.eco-section-sub { margin-top: 0; font-size: 11px; }
.eco-grid { gap: 9px; }
.eco-card {
  min-height: 72px;
  padding: 10px 11px;
  grid-template-columns: 40px 1fr auto;
  gap: 10px;
  border-radius: 10px;
}
.eco-card img { width: 40px; height: 40px; border-radius: 10px; }
.eco-card > span:nth-child(2) { gap: 2px; }
.eco-card strong { font-size: 13px; }
.eco-card small { font-size: 10.5px; line-height: 1.3; }
.eco-card-current em { font-size: 8px; margin-left: 5px; }
.eco-grid-single { max-width: 360px; }
.eco-footer-grid { gap: 9px; margin-top: 18px; }
.eco-footer-card { min-height: 62px; padding: 10px 12px; grid-template-columns: 32px 1fr auto; gap: 9px; border-radius: 10px; }
.eco-footer-icon { width: 30px; height: 30px; border-radius: 8px; }
.eco-footer-card strong { font-size: 12.5px; }
.eco-footer-card small { font-size: 10.5px; }

/* Apex: personal operating layer, not a chatbot window. */
.apex-panel {
  width: 430px;
  padding: 22px;
  background:
    radial-gradient(360px 220px at 15% 0%, rgba(var(--cyan-glow-rgb), .055), transparent 72%),
    #08121b;
}
.ai-topbar { margin-bottom: 20px; align-items: center; }
.ai-topbar-id { align-items: center; gap: 9px; }
.ai-provider-pill { opacity: .7; }
.apex-home-view { gap: 0; justify-content: flex-start; padding-top: 6px; }
/* V1.7: the hero sits at the top of the panel rather than vertically centred. Centring a
   variable-height block in a tall panel produced a large, drifting gap above it and pushed the
   actions toward the middle of the screen; anchoring it keeps the first thing you read and the
   first thing you can tap close together. */
.apex-home-greeting { padding: 2px 0 18px; border-bottom: 1px solid var(--border-soft); }
.apex-home-question { color: var(--ink-strong); font-size: 24px; line-height: 1.15; font-weight: 730; letter-spacing: -.025em; }
.apex-home-briefing { margin-top: 8px; color: var(--ink-soft); font-size: 13px; line-height: 1.5; max-width: 42ch; }
.apex-home-actions { display: grid; grid-template-columns: 1fr; gap: 8px; padding: 16px 0 8px; }
.apex-routine-btn {
  min-height: 44px;
  padding: 10px 12px;
  text-align: left;
  background: rgba(var(--panel-raised-rgb),.58);
  border-color: rgba(var(--hairline-rgb),.09);
}
.apex-routine-btn:hover { background: rgba(var(--cyan-glow-rgb), .075); border-color: rgba(var(--cyan-glow-rgb), .25); }
.ai-suggested-row { gap: 7px; padding-bottom: 0; }
.ai-chip { font-family: inherit; font-size: 11.5px; border-radius: 999px; padding: 7px 10px; background: rgba(var(--panel-raised-rgb),.42); color: var(--ink-soft); }
.ai-chip:hover { color: var(--cyan-bright); background: rgba(var(--cyan-glow-rgb), .06); }
.ai-input-row { gap: 8px; padding-top: 14px; border-top: 1px solid var(--border-soft); }
.ai-input { font-family: inherit; border-radius: 9px; background: rgba(var(--panel-raised-rgb),.68); }
.ai-input-row .btn { min-width: 68px; }
.ai-disclaimer { margin-top: 9px; color: var(--ink-faint); font-size: 10.5px; line-height: 1.45; }
.ai-messages { gap: 18px; padding-right: 3px; }
.ai-msg { max-width: 92%; }
.ai-msg-meta { margin-bottom: 5px; text-transform: none; letter-spacing: 0; font-size: 10px; }
.ai-msg-bubble { border-radius: 10px; padding: 10px 12px; font-size: 13px; line-height: 1.6; }
.ai-msg-assistant { max-width: 100%; }
.ai-msg-assistant .ai-msg-bubble { padding: 2px 0 2px 12px; background: transparent; border: 0; border-left: 2px solid rgba(var(--cyan-glow-rgb), .55); }
.ai-msg-user .ai-msg-bubble { background: rgba(var(--panel-raised-rgb),.66); border-color: rgba(var(--hairline-rgb),.10); }
.ai-action-buttons { margin-top: 10px; }
.ai-action-confirm, .ai-action-cancel { min-height: 40px; border-radius: 8px; }

/* Deep-screen maturity: reduce old dashboard weight without removing any depth. */
#mainTabFitness .panel,
#mainTabLearning .panel,
#mainTabFinance .panel,
#mainTabTravel .panel,
#mainTabInsights .panel,
#mainTabProgress .panel {
  box-shadow: none;
}
#mainTabFitness .fin-header,
#mainTabLearning .fin-header,
#mainTabFinance .fin-header,
#mainTabTravel .fin-header,
#mainTabInsights .fin-header,
#mainTabProgress .fin-header { margin-bottom: 30px; }

/* Modal/sheet consistency: one Black Frost language. */
.fit-modal, .trav-modal, .data-management-modal {
  border-radius: 14px;
  border-color: rgba(var(--hairline-rgb),.10);
  box-shadow: 0 24px 72px rgba(0,0,0,.48);
}

/* Compact system pages on mobile without reintroducing card stacks. */
@media (max-width: 860px) {
  .eco-hero { margin-bottom: 22px; }
  .eco-section { padding: 18px 0 20px; }
  .eco-section-head { display: block; margin-bottom: 10px; }
  .eco-section-sub { margin-top: 3px; }
  .eco-grid, .eco-grid-four, .eco-grid-single { grid-template-columns: 1fr; max-width: none; }
  .eco-card { min-height: 68px; }
  .eco-footer-grid { grid-template-columns: 1fr; }
  .apex-home-question { font-size: 22px; }
  .apex-home-briefing { max-width: none; }
  .apex-home-actions { padding-top: 18px; }
  .ai-msg-assistant { max-width: 100%; }
}


/* =====================================================================
   BLACK FROST V1.6.4 — LOW-FRICTION HABITS + FINAL MATURITY PASS
   Starter check-ins, calmer habit management, Finance progressive disclosure,
   tighter Ecosystem density, and more contextual Apex.
   ===================================================================== */

/* Habits: doing first, configuration second. */
#mainTabProgress .progress-top-row { align-items: start; }
#mainTabProgress .panel { border-color: rgba(var(--hairline-rgb),.075); }
#mainTabProgress .habit-manager-summary { margin-top: 2px; }
.hm-starter-note { margin: 2px 0 16px; color: var(--ink-faint); font-size: 11px; line-height: 1.5; }
.hm-add-disclosure { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border-soft); }
.hm-add-disclosure > summary { width: max-content; color: var(--cyan-bright); font-size: 12px; cursor: pointer; list-style: none; }
.hm-add-disclosure > summary::-webkit-details-marker { display: none; }
.hm-add-disclosure > summary::before { content: '+'; margin-right: 7px; }
.hm-add-disclosure[open] > summary::before { content: '−'; }
.hm-add-form { margin-top: 12px; }
.hm-rename-btn { min-height: 34px; padding: 0 9px; border: 1px solid var(--border-soft); border-radius: 8px; background: transparent; color: var(--ink-faint); font: inherit; font-size: 10.5px; cursor: pointer; }
.hm-rename-btn:hover { color: var(--cyan-bright); border-color: rgba(var(--cyan-glow-rgb), .24); }
#habitManager .habit-row { padding: 9px 0; margin: 0; border-bottom: 1px solid rgba(var(--hairline-rgb),.055); }
#habitManager .habit-row:last-child { border-bottom: 0; }

/* Finance: common workflows stay visible; deeper destinations are user-pulled. */
.fin-primary-nav {
  align-items: center;
  display: flex;
  flex-wrap: wrap;          /* wraps to a second line before it ever hides anything */
  gap: 6px;
  overflow: visible;
}
.fin-primary-nav .home-nav-btn { flex: 0 0 auto; }

/* Ecosystem should read as a directory, not a marketing landing page. */
.ecosystem-page { padding-bottom: 44px; }
.eco-hero { margin-bottom: 20px; }
.eco-section { padding: 16px 0 18px; }
.eco-section-head { margin-bottom: 9px; }
.eco-grid { gap: 7px; }
.eco-card { min-height: 64px; padding: 9px 10px; grid-template-columns: 36px 1fr auto; gap: 9px; }
.eco-card img { width: 36px; height: 36px; border-radius: 9px; }
.eco-card strong { font-size: 12.5px; }
.eco-card small { font-size: 10px; }
.eco-footer-grid { margin-top: 14px; gap: 7px; }
.eco-footer-card { min-height: 56px; padding: 9px 10px; }

/* Large desktop: use available space through composition rather than oversized cards. */
@media (min-width: 1680px) and (pointer: fine) {
  .wrap { padding-right: clamp(52px, 4vw, 88px); }
  .tab-panel { width: min(100%, 1480px); }
  #mainTabHome .home-brief { width: min(100%, 1320px); }
  #mainTabProgress, #mainTabFitness, #mainTabLearning, #mainTabTravel { width: min(100%, 1380px); }
  #mainTabFinance, #mainTabInsights { width: min(100%, 1540px); }
  #mainTabEcosystem { width: min(100%, 1180px); }
  #mainTabJournal { width: min(100%, 860px); }
}

@media (max-width: 860px) {
  .hm-rename-btn { min-height: 40px; }
  /* Narrow widths: scroll the row rather than hiding tabs behind a menu. */
  .fin-primary-nav { flex-wrap: nowrap; overflow-x: auto; overflow-y: visible; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .fin-primary-nav::-webkit-scrollbar { display: none; }
      .eco-section { padding: 14px 0 16px; }
  .eco-card { min-height: 62px; }
}


/* =====================================================================
   BLACK FROST V1.7 — APEX GUIDE + THEME REPAIR
   Apex becomes the guided operating layer; theme mood reaches the shell too.
   ===================================================================== */
/* Theme repair: late Black Frost polish must keep structure, not freeze Mighty Dark colours. */
.header, .main-nav { background: var(--bg); }
.apex-panel { background: var(--panel); }
.apex-routine-btn, .ai-input, .ai-msg-user .ai-msg-bubble, .hb-now-body { background: var(--panel); }
.more-sheet-panel { background: var(--panel); }
.data-management-modal { background: var(--panel); }
#dataMgmtOverlay .dm-section { background: transparent; }
.theme-opt { transition: background .15s ease, border-color .15s ease, color .15s ease; }
#mainTabSettings .theme-opt.active { box-shadow: inset 2px 0 0 var(--cyan); }

/* Apex Guide visual grammar: assistant text stays open; guidance/action surfaces earn containment. */
.apex-panel { width: min(460px, calc(100vw - 36px)); }
.apex-guide-subtitle { margin-top: 2px; color: var(--ink-faint); font-size: 10.5px; line-height: 1.25; }
.apex-guide-choices { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 11px; }
.apex-guide-choice {
  min-height: 38px; padding: 7px 10px; border: 1px solid var(--border-soft); border-radius: 9px;
  background: var(--panel-raised); color: var(--ink); font: inherit; font-size: 11.5px; text-align: left; cursor: pointer;
}
.apex-guide-choice:hover { border-color: rgba(var(--cyan-glow-rgb),.34); color: var(--cyan-bright); background: rgba(var(--cyan-glow-rgb),.07); }
.apex-guide-choice:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.apex-guide-checklist { margin-top: 12px; border-top: 1px solid var(--border-soft); border-bottom: 1px solid var(--border-soft); }
.apex-guide-checklist-head { min-height: 42px; display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--ink-strong); font-size: 11px; font-weight: 700; }
.apex-guide-checklist-head span:last-child { color: var(--cyan-bright); font-family: var(--mono); font-weight: 600; }
.apex-guide-checkrow { width: 100%; min-height: 52px; display: grid; grid-template-columns: 28px 1fr; align-items: center; gap: 8px; padding: 8px 2px; border: 0; border-top: 1px solid var(--border-soft); background: transparent; color: var(--ink); text-align: left; cursor: pointer; }
.apex-guide-checkrow:hover { background: rgba(var(--cyan-glow-rgb),.035); }
.apex-guide-checkmark { width: 22px; height: 22px; display: grid; place-items: center; border: 1px solid var(--border); border-radius: 50%; color: var(--ink-faint); font-size: 12px; }
.apex-guide-checkrow.is-done .apex-guide-checkmark { border-color: rgba(var(--cyan-glow-rgb),.5); background: rgba(var(--cyan-glow-rgb),.14); color: var(--cyan-bright); }
.apex-guide-checkcopy { display: grid; gap: 2px; }
.apex-guide-checkcopy strong { color: var(--ink); font-size: 11.5px; font-weight: 680; }
.apex-guide-checkcopy small { color: var(--ink-faint); font-size: 11px; line-height: 1.35; }
.apex-guide-checkrow.is-done .apex-guide-checkcopy { opacity: .7; }
.apex-guide-checklist-empty { margin-top: 12px; padding: 12px 0; color: var(--ink-faint); font-size: 11.5px; border-top: 1px solid var(--border-soft); }

@media (max-width: 860px) {
  .apex-panel { width: 100%; }
  .apex-guide-choice { min-height: 44px; }
  .apex-guide-checkrow { min-height: 56px; }
}

  /* =====================================================================
     APEX GATEWAY V2 — opening-state layout and inline navigation
     The opening state previously left ~216px of empty panel below the
     actions (42% of the view) because the column stretched to fill the
     panel. It is now a natural-height stack anchored to the top, so the
     hero, the three actions and the input read as one deliberate group.
     ===================================================================== */
  /* The opening group is centred in the space between the header and the composer. Anchoring it
     to the top left ~240px of empty panel beneath it (42% of the view) with the composer pinned
     at the bottom; centring balances that space instead of pooling it in one place, which is why
     the empty state now reads as deliberate rather than unfinished. */
  .apex-home-view { justify-content: center; }
  /* The panel header ("Apex"), the action buttons and the composer are all left-aligned; the
     hero was the only centred element, which read as misaligned rather than as emphasis — and
     centring a 44ch paragraph broke it into ragged lines ("…set up your Life / OS, or take…").
     One alignment for the whole panel. */
  .apex-home-greeting { text-align: left; }
  .apex-home-question { text-align: left; }
  .apex-home-briefing { text-align: left; margin-left: 0; margin-right: 0; }
  .apex-home-greeting { padding: 2px 0 16px; }
  .apex-home-question { font-size: 19px; line-height: 1.3; letter-spacing: 0.01em; }
  .apex-home-briefing { margin-top: 7px; font-size: 12.5px; line-height: 1.5; max-width: 44ch; }
  .apex-home-actions { padding: 14px 0 6px; gap: 7px; }
  .apex-routine-btn { min-height: 46px; text-align: left; }

  /* Inline navigation offered inside a reply — quieter than a confirm button, because it is a
     suggestion the user may ignore, not a decision waiting on them. */
  .apex-nav-actions { display: flex; flex-wrap: wrap; gap: 7px; margin: 9px 0 2px; }
  .apex-nav-action {
    min-height: 40px; padding: 8px 14px; cursor: pointer;
    background: transparent; border: 1px solid rgba(var(--cyan-glow-rgb), .30);
    border-radius: 8px; color: var(--cyan-bright);
    font-family: inherit; font-size: 12.5px;
  }
  .apex-nav-action:active { background: rgba(var(--cyan-glow-rgb), .10); }

  /* Comfortable reading width for the conversation itself. */
  .ai-msg-bubble { max-width: 58ch; }

  @media (max-width: 860px) {
    /* Mobile Apex is a destination, not a corner panel squeezed onto a phone. */
    .apex-home-question { font-size: 21px; }
    .apex-nav-action { min-height: 44px; }
    .ai-msg-bubble { max-width: none; }
  }

  /* Apex opening state — narrow/tall panels.
     Centring balances the space in a short desktop panel, but on a full-height phone panel it
     leaves the group floating in the middle with a large void above it. Below 700px wide the
     content anchors nearer the top instead, and the intro paragraph is allowed the full panel
     width so it stops breaking phrases like "your Life / OS" across lines. */
  /* Never wider than the panel, so the intro cannot break phrases across lines. */
  .apex-home-briefing { max-width: min(44ch, 100%); }
  @media (max-width: 700px) {
    .apex-home-view { justify-content: flex-start; padding-top: 14px; }
    /* A phone panel is already narrow; a second cap only creates ragged wrapping. */
    .apex-home-briefing { max-width: none; }
  }

  /* =====================================================================
     APEX GUIDED COMPANION V3
     A guided conversation stays a conversation: the flow label is a quiet
     line inside the reply (not a stepper or a form), paragraphs get a small
     gap instead of blank lines, and a guided decision reads as three plain
     choices — the primary one filled, "Change it" outlined, "Skip" quiet.
     ===================================================================== */
  .ai-para-gap { display: block; height: 7px; }
  .apex-guide-progress {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 6px;
    font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-faint);
  }
  .apex-guide-progress-title { color: var(--cyan-dim, var(--ink-soft)); }
  .apex-guide-progress-stage::before, .apex-guide-progress-saved::before { content: '·'; margin-right: 6px; color: var(--ink-faint); }
  .apex-guide-progress-saved { color: var(--ink-soft); }
  .apex-guided-decision { gap: 7px; }
  .apex-guided-decision .ai-action-btn { min-width: 0; padding: 8px 14px; }
  .ai-action-secondary { background: transparent; border: 1px solid rgba(var(--cyan-glow-rgb), .32); color: var(--cyan-bright); }
  .ai-action-secondary:hover { background: rgba(var(--cyan-glow-rgb), .08); }
  .ai-action-secondary:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
  .apex-guided-decision .ai-action-cancel { background: transparent; border-color: transparent; text-decoration: underline; text-underline-offset: 3px; min-width: 0; }
  .apex-guided-decision .ai-action-cancel:hover { border-color: transparent; color: var(--ink); }
  /* Header stays one row at every width: name + status on the left, Clear chat and close on the
     right. It used to wrap on phones, dropping the close button onto its own line. */
  .ai-topbar { flex-wrap: nowrap; }
  .ai-topbar-id { flex: 1 1 auto; min-width: 0; flex-wrap: nowrap; }
  .ai-topbar-id > div { min-width: 0; }
  .apex-guide-subtitle { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .ai-topbar-actions { flex: 0 0 auto; }
  .ai-msg-assistant .apex-guide-choices { margin-top: 9px; }
  .ai-msg-assistant .apex-nav-actions + .apex-guide-choices { margin-top: 6px; }
  /* The composer is the primary control once a conversation is running. */
  .apex-conversation-view ~ .ai-input-row .ai-input { min-height: 44px; }
  @media (max-width: 860px) {
    .apex-guided-decision .ai-action-btn { min-height: 44px; flex: 1 1 auto; }
    .apex-guided-decision .ai-action-cancel { flex: 0 0 auto; }
    .apex-guide-choices { gap: 8px; }
    .apex-guide-choice { flex: 1 1 auto; text-align: center; }
  }

  /* =====================================================================
     APEX V3.1 — FRONT DOOR
     The opening state is a short, deliberate block: one line that says what
     Apex is for, one sentence of promise, one reassurance, three doors, and
     the composer directly underneath. On desktop the panel fits that block
     instead of stretching to 720px around it (the old empty band). On phones
     Apex stays a full-screen destination.
     ===================================================================== */
  @media (min-width: 861px) {
    .apex-panel.apex-panel--home { height: auto; }
    .apex-panel--home #apexPanelRoot,
    .apex-panel--home .ai-shell { flex: 0 0 auto; }
    .apex-panel--home .apex-home-view { flex: 0 0 auto; justify-content: flex-start; padding-top: 2px; }
  }
  /* The hero says it; the header doesn't need to say it twice. */
  .apex-panel--home .apex-guide-subtitle { display: none; }
  .apex-panel--home .ai-topbar { margin-bottom: 14px; }
  .apex-home-greeting { padding: 2px 0 18px; }
  .apex-home-question { font-size: 21px; line-height: 1.25; font-weight: 700; letter-spacing: -0.01em; color: var(--ink-strong, var(--ink)); text-wrap: balance; }
  .apex-home-briefing { margin-top: 8px; font-size: 13px; line-height: 1.55; color: var(--ink-soft); max-width: min(40ch, 100%); }
  .apex-home-reassure { margin-top: 10px; font-size: 12.5px; line-height: 1.4; color: var(--cyan-bright); }
  .apex-home-actions { padding: 16px 0 2px; gap: 8px; }
  .apex-routine-btn { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
  .apex-routine-btn::after { content: '›'; flex: 0 0 auto; color: var(--ink-faint); font-size: 17px; line-height: 1; transition: transform .15s ease, color .15s ease; }
  .apex-routine-btn:hover::after, .apex-routine-btn:focus-visible::after { color: var(--cyan-bright); transform: translateX(2px); }
  @media (prefers-reduced-motion: reduce) { .apex-routine-btn::after { transition: none; } }
  /* The composer is the main way in, so it reads as one. */
  .apex-panel--home .ai-input-row { margin-top: 18px; }
  .apex-panel--home .ai-input { border-color: rgba(var(--cyan-glow-rgb), .30); }
  .ai-disclaimer { font-size: 10px; line-height: 1.4; }
  /* Clarifying questions offer short, equal choices. */
  .apex-guide-choices .apex-guide-choice { max-width: 100%; }
  @media (max-width: 860px) {
    .apex-home-question { font-size: 21px; }
    .apex-home-briefing { max-width: none; text-wrap: pretty; }
    .apex-routine-btn { min-height: 48px; }
  }

/* =====================================================================
   APEX V4 — ABOUT REFRESH
   ===================================================================== */
.about-block p + p { margin-top: 10px; }
.about-note { color: var(--ink-faint) !important; font-size: 13px !important; }
.about-cta { margin-top: 14px; min-height: 44px; padding: 0; background: none; border: 0; color: var(--cyan-bright); font: inherit; font-size: 13px; cursor: pointer; }
.about-cta:hover { color: var(--ink-strong); }
.about-grid .about-block:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* =====================================================================
   APEX V4 — UNIVERSAL FRONT DOOR + ADAPTIVE WORKSPACE
   Universal layer first (build / focus / teach), the screen's help second.
   One Apex, three presentations: compact · docked · fullscreen.
   ===================================================================== */
:root { --apex-dock-w: min(440px, 34vw); --apex-vvh: 100vh; --apex-vvt: 0px; }

/* ---- Universal layer ---- */
.apex-universal { display: grid; gap: 7px; padding: 14px 0 2px; }
.apex-universal-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  min-height: 46px; padding: 10px 14px; border-radius: 10px; cursor: pointer; text-align: left;
  font: inherit; font-size: 13.5px; font-weight: 650; color: var(--ink-strong, var(--ink));
  background: rgba(var(--panel-raised-rgb), .72); border: 1px solid rgba(var(--hairline-rgb), .14);
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.apex-universal-btn::after { content: '›'; flex: 0 0 auto; color: var(--ink-faint); font-size: 17px; line-height: 1; }
.apex-universal-btn:hover, .apex-universal-btn:focus-visible { border-color: rgba(var(--cyan-glow-rgb), .38); background: rgba(var(--cyan-glow-rgb), .08); color: var(--cyan-bright); }
.apex-universal-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.apex-universal-btn--build { background: rgba(var(--cyan-glow-rgb), .12); border-color: rgba(var(--cyan-glow-rgb), .34); }
.apex-universal-btn--build::after { color: var(--cyan-bright); }

/* ---- Context layer ---- */
.apex-context-block { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border-soft); }
.apex-context-label { font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); }
#apexPanel [hidden] { display: none !important; }
#apexPanel .apex-home-view { gap: 0; }
.apex-panel--home .apex-home-briefing { max-width: none; }
.apex-context-block .apex-home-actions { display: flex; flex-direction: row; flex-wrap: wrap; gap: 7px; padding: 9px 0 0; }
.apex-context-block .apex-routine-btn { width: auto; flex: 1 1 0; min-width: 136px; min-height: 46px; padding: 8px 12px; font-size: 12.5px; font-weight: 560; justify-content: center; text-align: center; }
.apex-context-block .apex-routine-btn::after { content: none; }
.apex-context-block .apex-home-actions:empty { display: none; }
.apex-back-to-chat { align-self: flex-start; margin-top: 12px; min-height: 40px; padding: 0; background: none; border: 0; color: var(--cyan-bright); font: inherit; font-size: 12.5px; cursor: pointer; }
.apex-panel--home .apex-home-greeting { padding-bottom: 14px; }

/* ---- Header controls ---- */
.ai-topbar-actions { display: flex; align-items: center; gap: 4px; }
.apex-head-btn { font-size: 15px; line-height: 1; }

/* ---- Guided task strip ---- */
.apex-task-strip { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 12px;
  margin: -6px 0 10px; padding: 8px 10px; border-radius: 9px; background: rgba(var(--panel-raised-rgb), .55); border: 1px solid rgba(var(--hairline-rgb), .10); }
.apex-task-name { font-size: 10px; font-weight: 750; letter-spacing: .12em; text-transform: uppercase; color: var(--cyan-bright); }
.apex-task-parts { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11.5px; color: var(--ink-faint); }
.apex-task-part.is-active { color: var(--ink); }
.apex-task-part.is-done { color: var(--ink-soft); }

/* ---- Proposal card, summary, collapsed steps ---- */
.apex-proposal-card { margin-top: 8px; padding: 11px 13px; border-radius: 10px; border: 1px solid rgba(var(--cyan-glow-rgb), .26); background: rgba(var(--cyan-glow-rgb), .05); max-width: 58ch; }
.apex-proposal-title { font-size: 10px; font-weight: 750; letter-spacing: .12em; text-transform: uppercase; color: var(--cyan-bright); margin-bottom: 5px; }
.apex-proposal-line { font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }
.apex-proposal-name { font-size: 14px; font-weight: 680; color: var(--ink-strong, var(--ink)); }
.apex-summary { margin-top: 8px; padding: 11px 13px; border-radius: 10px; border: 1px solid rgba(var(--hairline-rgb), .14); background: rgba(var(--panel-raised-rgb), .5); max-width: 58ch; }
.apex-summary-title { font-size: 10px; font-weight: 750; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 6px; }
.apex-summary-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; font-size: 12.5px; color: var(--ink); }
.apex-summary-list span { color: var(--cyan-bright); margin-right: 4px; }
.apex-summary-note { margin-top: 7px; font-size: 12px; color: var(--ink-soft); }
.apex-done-row { align-self: flex-start; font-size: 11.5px; color: var(--ink-faint); padding: 1px 2px; }
.apex-done-row span { color: var(--cyan-bright); }
.apex-guide-choices--list { flex-direction: column; align-items: stretch; }
.apex-guide-choices--list .apex-guide-choice { width: 100%; text-align: left; }

/* ---- Show me where ---- */
.apex-spotlight { outline: 2px solid rgba(var(--cyan-glow-rgb), .55); outline-offset: 4px; border-radius: 10px; transition: outline-color .6s ease; }
@media (prefers-reduced-motion: reduce) { .apex-spotlight { transition: none; } }

/* ---- Docked workspace (desktop / large touch) ---- */
@media (min-width: 861px) {
  .apex-panel.apex-mode-docked,
  .apex-panel.apex-mode-docked.apex-panel--home {
    top: var(--apex-vvt, 0px); right: 0; bottom: auto; left: auto;
    width: var(--apex-dock-w); height: var(--apex-vvh, 100vh); max-height: none;
    border-radius: 0; border: 0; border-left: 1px solid var(--border-soft);
    box-shadow: -18px 0 50px rgba(var(--shadow-rgb), .22); animation: none;
    padding-top: max(20px, env(safe-area-inset-top, 0px)); padding-bottom: max(16px, env(safe-area-inset-bottom, 0px));
  }
  .apex-panel.apex-mode-docked #apexPanelRoot,
  .apex-panel.apex-mode-docked .ai-shell { flex: 1 1 auto; min-height: 0; }
  .apex-panel.apex-mode-docked .apex-home-view { flex: 1 1 auto; overflow-y: auto; }
  body.apex-docked .wrap { padding-right: calc(var(--apex-dock-w) + 36px); transition: padding-right .18s ease; }
  body.apex-docked .apex-fab { display: none; }
}
@media (prefers-reduced-motion: reduce) { body.apex-docked .wrap { transition: none; } }

/* ---- Full screen (phones, small tablets) ---- */
@media (max-width: 860px) {
  .apex-panel.apex-mode-fullscreen {
    top: var(--apex-vvt, 0px); bottom: auto; height: var(--apex-vvh, 100%); max-height: none;
  }
  .apex-panel.apex-mode-fullscreen .apex-home-view { overflow-y: auto; min-height: 0; flex: 1 1 auto; }
  .apex-universal-btn { min-height: 52px; font-size: 15px; }
  .apex-context-block .apex-routine-btn { min-height: 46px; font-size: 14px; }
  .apex-head-btn { width: 44px; height: 44px; }
  .apex-task-strip { margin-top: 0; }
}

/* ---- Large touchscreens (Tesla-class): bigger targets, less text, no typing required ---- */
:root { --apex-dock-w-touch: min(540px, 40vw); }
.apex-panel.apex-large-touch { --apex-dock-w: var(--apex-dock-w-touch); }
body.apex-large-touch-open { --apex-dock-w: var(--apex-dock-w-touch); }
.apex-panel.apex-large-touch .apex-universal-btn { min-height: 60px; font-size: 16px; padding: 14px 18px; }
.apex-panel.apex-large-touch .apex-routine-btn,
.apex-panel.apex-large-touch .apex-guide-choice,
.apex-panel.apex-large-touch .apex-nav-action,
.apex-panel.apex-large-touch .ai-action-btn { min-height: 56px; font-size: 15px; }
.apex-panel.apex-large-touch .ai-input,
.apex-panel.apex-large-touch .ai-input-row .btn { min-height: 56px; font-size: 16px; }
.apex-panel.apex-large-touch .apex-head-btn { width: 52px; height: 52px; font-size: 18px; }
.apex-panel.apex-large-touch .apex-home-briefing,
.apex-panel.apex-large-touch .ai-disclaimer { display: none; }
.apex-panel.apex-large-touch .ai-msg-bubble { font-size: 15px; }

/* ---- Keyboard open: keep the question and the composer; drop the chrome ---- */
.apex-panel.apex-kb-open .apex-home-greeting,
.apex-panel.apex-kb-open .apex-context-block,
.apex-panel.apex-kb-open .ai-disclaimer,
.apex-panel.apex-kb-open .apex-guide-subtitle,
.apex-panel.apex-kb-open .ai-provider-pill { display: none; }
.apex-panel.apex-kb-open .ai-topbar { margin-bottom: 6px; }
.apex-panel.apex-kb-open .module-title { font-size: 13px; }
.apex-panel.apex-kb-open .apex-task-strip { margin: 0 0 6px; padding: 5px 8px; }
.apex-panel.apex-kb-open .apex-universal { padding-top: 6px; }
.apex-panel.apex-kb-open .ai-input-row { padding-top: 8px; }

/* The dialog container takes focus on open (instead of the input); it needs no ring of its own. */
#apexPanel:focus { outline: none; }

/* ==========================================================================
   APEX V4.1.1 — A WAITING PROPOSAL, SHOWN QUIETLY
   One compact line above the composer while a proposal waits and the conversation has
   moved on. It never repeats in the transcript.
   ========================================================================== */
.apex-pending-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 8px 0 0; padding: 7px 10px;
  border-radius: 9px; border: 1px solid rgba(var(--cyan-glow-rgb), .22); background: rgba(var(--cyan-glow-rgb), .05); }
.apex-pending-strip[hidden] { display: none !important; }
.apex-pending-label { font-size: 10px; font-weight: 750; letter-spacing: .12em; text-transform: uppercase; color: var(--cyan-bright); }
.apex-pending-what { flex: 1 1 12ch; min-width: 0; font-size: 12.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.apex-pending-actions { display: flex; gap: 6px; margin-left: auto; }
.apex-pending-strip .ai-action-btn { min-height: 32px; min-width: 0; padding: 4px 12px; font-size: 12px; }
@media (pointer: coarse), (max-width: 700px) { .apex-pending-strip .ai-action-btn { min-height: 44px; } }
.apex-panel.apex-large-touch .apex-pending-strip .ai-action-btn { min-height: 56px; font-size: 15px; }
.apex-panel.apex-kb-open .apex-pending-strip { margin-top: 4px; padding: 4px 8px; }

/* V4.1.2 (Part 8): Finance Snapshot — plain facts in place of the retired Financial Health Score. */
.fin-snapshot { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.fin-snap-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; align-items: baseline; padding: 6px 0; border-bottom: 1px solid var(--border-soft); }
.fin-snap-label { font-size: 12px; color: var(--ink-soft); min-width: 0; }
.fin-snap-value { font-size: 14px; font-weight: 600; color: var(--ink); text-align: right; }
.fin-snap-sub { grid-column: 1 / -1; font-size: 11.5px; color: var(--ink-faint); }
.fin-snap-note { padding-top: 4px; }

/* V4.1.2 (Part 47): What You Track rows. The label used to be a bare text node that landed in the
   24px icon column and wrapped ("Life & / Interests"). Check, icon and label now each own a
   column; rows share one height; the label never wraps on desktop and ellipsizes only if it must. */
#setModulePrefsBody { align-items: stretch; }
#setModulePrefsBody .module-pref-row {
  grid-template-columns: 26px 24px minmax(0, 1fr);
  column-gap: 10px;
  min-height: 52px;
  height: 100%;
  padding: 10px 14px;
  text-align: left;
  line-height: 1.25;
}
#setModulePrefsBody .fr-module-check { justify-self: start; white-space: nowrap; }
#setModulePrefsBody .module-pref-icon { display: inline-flex; align-items: center; justify-content: center; width: 24px; font-size: 16px; line-height: 1; }
#setModulePrefsBody .module-pref-label { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.module-pref-row .module-pref-icon { flex: 0 0 auto; }
.module-pref-row .module-pref-label { min-width: 0; }
#setModulePrefsBody + * { margin-top: 0; }
.set-row-stack .set-row-help + .set-row-help { margin-top: 4px; }
@media (max-width: 860px) {
  #setModulePrefsBody .module-pref-row { min-height: 48px; }
}
@media (max-width: 380px) {
  #setModulePrefsBody .module-pref-label { white-space: normal; }
}

/* =====================================================================
   V4.2 — CONSOLIDATION + DEEP POLISH
   Responsive fixes only: no new components, no new colors.
   ===================================================================== */

/* 1. Mobile "More": a compact two-column grid in the same groups and glyphs as the desktop rail.
      About / Mighty Ecosystem stay quiet at the bottom. */
@media (max-width: 900px) {
  .more-sheet-panel { max-height: min(80vh, 80dvh); }
  .more-sheet-head { padding: 12px 14px 12px 18px; }
  .more-sheet-body { padding: 4px 12px calc(14px + env(safe-area-inset-bottom, 0px)); }
  .more-group { padding: 6px 0 4px; }
  .more-group-label { padding: 6px 4px 6px; }
  .more-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  .more-item {
    display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 10px 12px;
    background: rgba(var(--panel-raised-rgb), .55); border: 1px solid var(--border-soft); border-radius: 10px;
  }
  .more-item:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
  .more-ico { width: 20px; flex: 0 0 20px; text-align: center; color: var(--ink-faint); font: 16px/1 ui-sans-serif, system-ui, sans-serif; }
  .more-lbl { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 14px; }
  .more-group--quiet .more-item { background: none; border-color: transparent; min-height: 44px; color: var(--ink-soft); font-size: 13px; }
  .more-group--quiet .more-group-label { display: none; }
  .more-group--quiet { border-top: 1px solid var(--border-soft); margin-top: 8px; padding-top: 8px; }
}
@media (max-width: 340px) { .more-grid { grid-template-columns: 1fr; } }

/* 2. Content never hides behind the bottom bar, including keyboard focus scrolling. */
@media (max-width: 900px) {
  html { scroll-padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
}

/* 3. Bottom-sheet modals: dynamic viewport height (mobile URL bar / keyboard) and the home
      indicator never cover the primary action row. */
@media (max-width: 700px) {
  .fit-modal, .trav-modal { max-height: 94dvh; }
  .fit-modal-foot, .trav-modal-foot { padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px)); }
}

/* 4. Touch targets (coarse pointers + the large-touch preview). Segmented controls, small text
      buttons and footer links reach 44px without changing their look on a mouse. */
@media (pointer: coarse) {
  .pv-btn, .ins-tf-btn, .ib-cat-btn, .tab-btn, .fit-cal-nav-btn, .nav-footer-link, .device-menu-action { min-height: 44px; }
  .fit-cal-nav-btn, .ib-cat-btn { min-width: 44px; }
  button.muted-link { min-height: 44px; display: inline-flex; align-items: center; }
  #tdMoreToggle { min-width: 44px; justify-content: center; }
  .reorder-btn { min-width: 44px; min-height: 44px; }
  .ds-item-card { min-height: 44px; }
}
html.force-touch .pv-btn, html.force-touch .ins-tf-btn, html.force-touch .ib-cat-btn, html.force-touch .tab-btn,
html.force-touch .fit-cal-nav-btn, html.force-touch .nav-footer-link, html.force-touch .device-menu-action,
html.force-touch-large .pv-btn, html.force-touch-large .ins-tf-btn, html.force-touch-large .ib-cat-btn, html.force-touch-large .tab-btn,
html.force-touch-large .fit-cal-nav-btn, html.force-touch-large .nav-footer-link, html.force-touch-large .device-menu-action { min-height: 44px; }
html.force-touch .fit-cal-nav-btn, html.force-touch-large .fit-cal-nav-btn,
html.force-touch .ib-cat-btn, html.force-touch-large .ib-cat-btn { min-width: 44px; }
html.force-touch button.muted-link, html.force-touch-large button.muted-link { min-height: 44px; display: inline-flex; align-items: center; }
html.force-touch #tdMoreToggle, html.force-touch-large #tdMoreToggle { min-width: 44px; justify-content: center; }
html.force-touch .reorder-btn, html.force-touch-large .reorder-btn { min-width: 44px; min-height: 44px; }
html.force-touch .ds-item-card, html.force-touch-large .ds-item-card { min-height: 44px; }

/* 4b. V4.2.1: the actual product touch-target floor is 44px, not 40 — two dense components
      (the fitness activity calendar's circular day cells and the small custom habit checkbox)
      can't literally grow to 44px visual circles without overflowing their layout at narrow
      widths, so their REAL, tappable hit area is expanded invisibly via a transparent pseudo-
      element instead — the same technique already used for .checkbox below, just with a bigger
      inset for the smaller calendar cells. The visible circle/checkbox size is unchanged. */
@media (pointer: coarse) {
  .fit-cal-day[role="button"] { position: relative; }
  .fit-cal-day[role="button"]::before { content: ""; position: absolute; inset: -6px; }
}
html.force-touch .fit-cal-day[role="button"], html.force-touch-large .fit-cal-day[role="button"] { position: relative; }
html.force-touch .fit-cal-day[role="button"]::before, html.force-touch-large .fit-cal-day[role="button"]::before {
  content: ""; position: absolute; inset: -6px;
}

/* 5. Short laptops (1366×768, 1440×800, 1440×900): the whole rail — including About, Mighty
      Ecosystem and the signature — fits without a hidden scroll, on mouse/trackpad only. */
@media (min-width: 901px) and (max-height: 940px) and (pointer: fine) {
  .header { height: 66px; padding-top: 16px; padding-bottom: 10px; }
  .main-nav { top: 66px; gap: 16px; padding-bottom: 14px; }
  .nav-group { gap: 4px; }
  .main-tab-btn { min-height: 36px; }
  .nav-footer { padding-top: 10px; }
  .nav-footer-link { min-height: 30px; }
  .nav-footer-divider { margin: 8px 0 10px; }
}
@media (min-width: 901px) and (max-height: 820px) and (pointer: fine) {
  .header { height: 60px; padding-top: 14px; }
  .main-nav { top: 60px; gap: 12px; padding-top: 4px; }
  .nav-group-items { gap: 1px; }
  .main-tab-btn { min-height: 33px; font-size: 13.5px; }
  .nav-footer-link { min-height: 28px; }
}

/* 6. Wide touch (Tesla-class): the rail may need to scroll there — say so with a thin bar
      instead of hiding it, so About and Mighty Ecosystem are discoverable. */
@media (min-width: 1100px) and (pointer: coarse) {
  .main-nav { scrollbar-width: thin; scrollbar-color: rgba(var(--hairline-rgb), .25) transparent; }
  .main-nav::-webkit-scrollbar { display: block; width: 4px; }
  .main-nav::-webkit-scrollbar-thumb { background: rgba(var(--hairline-rgb), .25); border-radius: 4px; }
}
html.force-touch-large .main-nav { scrollbar-width: thin; scrollbar-color: rgba(var(--hairline-rgb), .25) transparent; }

/* 7. Home — facts instead of a report card (V4.2). */
.hb-primary::before { content: none; }
.hb-primary-text { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.hb-primary-title { color: var(--ink-strong); font-size: 20px; font-weight: 720; letter-spacing: -.015em; }
.hb-primary-sub { color: var(--ink-soft); font-size: 13.5px; }
.hb-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.hb-fact {
  min-width: 0; min-height: 64px; padding: 12px 14px; display: flex; flex-direction: column; justify-content: center; gap: 4px;
  text-align: left; cursor: pointer; font-family: inherit;
  background: rgba(var(--panel-rgb), .6); border: 1px solid var(--border-soft); border-radius: 10px; color: var(--ink-soft);
}
.hb-fact:hover { border-color: rgba(var(--cyan-glow-rgb), .35); }
.hb-fact:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.hb-fact-label { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); }
.hb-fact-val { font-size: 14px; color: var(--ink-strong); line-height: 1.35; }
@media (max-width: 700px) {
  .hb-primary { margin-top: 28px; padding-bottom: 28px; }
  .hb-showing { margin-top: 28px; padding-bottom: 28px; }
  .hb-facts { grid-template-columns: 1fr; gap: 8px; }
  .hb-fact { min-height: 56px; flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; }
  .hb-fact-val { text-align: right; }
  .hb-relevant { margin-top: 24px; }
}
.fr-lead--soft { color: var(--ink-soft); }
html.force-touch-large .main-nav::-webkit-scrollbar { display: block; width: 4px; }
html.force-touch-large .main-nav::-webkit-scrollbar-thumb { background: rgba(var(--hairline-rgb), .25); border-radius: 4px; }

/* 8. Mobile density (V4.2). */
@media (max-width: 700px) {
  /* Settings rows stack; the copy block must not keep its 260px desktop flex-basis as a HEIGHT
     (it left ~250px of dead space above the name field). */
  .set-row-copy { flex: 0 0 auto; }
  .display-name-row { width: 100%; padding: 0; }
  .display-name-row .input { font-size: 16px; }
  #setCurrentFocusInput { width: 100%; }
}
@media (max-width: 520px) {
  /* Finance KPIs: two per row instead of one — eight tall cards were most of a phone screen. */
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .kpi-card { padding: 11px 12px; min-width: 0; }
}
@media (max-width: 700px) {
  /* Habits: Category Progress repeats the Life Balance list directly above it (same areas, same
     numbers), so phones show it once. Desktop keeps both side by side. */
  .habits-category-progress { display: none; }
  .key-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
}

/* 9. Apex header (V4.2): the tagline is already the first line of Apex's home view, so a
      truncated second copy ("Your guide to living a migh…") is dropped wherever it would clip. */
@media (max-width: 700px) { .apex-guide-subtitle { display: none; } }
body:not(.apex-docked) .apex-panel .apex-guide-subtitle { display: none; }

/* =========================================================================================
   V4.2.2 — MOBILE RECOVERY + UX FIX PASS
   Phone-only. "Phone" = narrow (≤860px) OR a coarse-pointer phone turned sideways (short and
   ≤1024px wide). Desktop and tablets are not matched by any rule below except where noted
   (class-based Apex full-screen, which only exists on phones).
   The visual-viewport variables (--apex-vvl/t/w/h) are written by apexApplyViewport().
   ========================================================================================= */

/* ---- 1. 16px field floor: iPhone Safari zooms the page on focus below 16px, and stays zoomed.
        !important on purpose: dozens of component rules set 11–14.5px with higher specificity,
        and this floor must win over every one of them on a phone. ---- */
@media (max-width: 860px), (pointer: coarse) and (max-height: 500px) and (max-width: 1024px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="image"]),
  select,
  textarea { font-size: 16px !important; }
}

/* ---- 2. Apex full screen: follows the VISUAL viewport on both axes, clears every safe area,
        and its header never scrolls. ID + class specificity so no later/earlier rule
        (e.g. the generic `.apex-panel { padding: 22px }`) can strip the safe-area padding. ---- */
#apexPanel.apex-mode-fullscreen,
#apexPanel.apex-mode-fullscreen.apex-panel--home {
  position: fixed;
  left: var(--apex-vvl, 0px); top: var(--apex-vvt, 0px); right: auto; bottom: auto;
  width: var(--apex-vvw, 100vw); height: var(--apex-vvh, 100vh);
  max-width: none; max-height: none; margin: 0;
  border: 0; border-radius: 0; box-shadow: none; animation: none;
  z-index: 400;
  padding: max(12px, env(safe-area-inset-top, 0px)) max(14px, env(safe-area-inset-right, 0px))
           max(8px, env(safe-area-inset-bottom, 0px)) max(14px, env(safe-area-inset-left, 0px));
  display: flex; flex-direction: column; overflow: hidden;
}
#apexPanel.apex-mode-fullscreen.apex-kb-open { padding-bottom: 6px; }
#apexPanel.apex-mode-fullscreen #apexPanelRoot,
#apexPanel.apex-mode-fullscreen .ai-shell { flex: 1 1 auto; min-height: 0; height: auto; display: flex; flex-direction: column; }
#apexPanel.apex-mode-fullscreen .ai-topbar { flex: 0 0 auto; margin-bottom: 10px; }
#apexPanel.apex-mode-fullscreen .apex-home-view { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
#apexPanel.apex-mode-fullscreen .apex-conversation-view { flex: 1 1 auto; min-height: 0; }
#apexPanel.apex-mode-fullscreen .ai-messages { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; gap: 12px; padding: 10px 10px 12px; }
#apexPanel.apex-mode-fullscreen .ai-input-row { flex: 0 0 auto; padding-bottom: 0; margin-top: 10px; }
#apexPanel.apex-mode-fullscreen .ai-input { font-size: 16px; }
#apexPanel.apex-mode-fullscreen .apex-head-btn { width: 44px; height: 44px; }
/* Density: the privacy note stays on Apex's front door; in a running conversation it gives its
   two lines back to the messages. */
#apexPanel.apex-mode-fullscreen .ai-disclaimer { margin-top: 6px; }
#apexPanel.apex-mode-fullscreen:not(.apex-panel--home) .ai-disclaimer { display: none; }
/* Guided choices: 5+ options become a two-column grid instead of a ~330px stacked wall.
   Same buttons, same handlers — layout only. */
#apexPanel.apex-mode-fullscreen .apex-guide-choices--list:has(> .apex-guide-choice:nth-child(5)) {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px;
}
#apexPanel.apex-mode-fullscreen .apex-guide-choices--list:has(> .apex-guide-choice:nth-child(5)) .apex-guide-choice {
  width: auto; min-height: 44px; padding: 8px 10px; line-height: 1.3; text-align: left;
}
@media (min-width: 600px) {
  #apexPanel.apex-mode-fullscreen .apex-guide-choices--list:has(> .apex-guide-choice:nth-child(5)) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Short screens (landscape phone, small phone with browser chrome): keep the question and the
   doors, drop the explanatory paragraph. */
@media (max-height: 560px) {
  #apexPanel.apex-mode-fullscreen .apex-home-briefing,
  #apexPanel.apex-mode-fullscreen .apex-home-reassure { display: none; }
  #apexPanel.apex-mode-fullscreen .apex-home-greeting { padding-bottom: 8px; }
  #apexPanel.apex-mode-fullscreen .apex-universal { padding-top: 8px; }
  #apexPanel.apex-mode-fullscreen .apex-context-block { margin-top: 8px; padding-top: 8px; }
}
/* A phone sideways never shows the corner launcher on top of full-screen Apex. */
@media (pointer: coarse) and (max-height: 500px) and (max-width: 1024px) {
  body:has(#apexPanel.apex-mode-fullscreen[style*="flex"]) .apex-fab { display: none; }
}

/* ---- 3. Top safe area for the app itself (installed iPhone app, notch / Dynamic Island). ---- */
@media (max-width: 860px) {
  .wrap { padding-top: max(18px, calc(env(safe-area-inset-top, 0px) + 8px)); }
}
@media (max-width: 640px) {
  .wrap { padding-top: max(14px, calc(env(safe-area-inset-top, 0px) + 8px)); }
}

/* ---- 4. More and every form follow the visual viewport: an open iOS keyboard or a zoomed page
        shrinks/moves the overlay with it, so Close, Cancel and Save stay on screen. ---- */
@media (max-width: 860px) {
  .more-sheet {
    inset: auto; left: var(--apex-vvl, 0px); top: var(--apex-vvt, 0px);
    width: var(--apex-vvw, 100vw); height: var(--apex-vvh, 100vh);
  }
  .more-sheet-panel { max-height: calc(var(--apex-vvh, 100vh) * 0.82); }
  .more-sheet-body { overscroll-behavior: contain; min-height: 0; }
}
@media (max-width: 860px), (pointer: coarse) and (max-height: 500px) and (max-width: 1024px) {
  .fit-modal-overlay, .trav-modal-overlay {
    inset: auto; left: var(--apex-vvl, 0px); top: var(--apex-vvt, 0px);
    width: var(--apex-vvw, 100vw); height: var(--apex-vvh, 100vh);
  }
  .fit-modal, .trav-modal, #dataMgmtOverlay .data-management-modal {
    max-height: calc(var(--apex-vvh, 100vh) - max(10px, env(safe-area-inset-top, 0px)));
    min-height: 0;
  }
  .fit-modal-head, .trav-modal-head, .fit-modal-foot, .trav-modal-foot { flex-shrink: 0; }
  .fit-modal-body, .trav-modal-body { min-height: 0; overscroll-behavior: contain; }
}
/* Scroll lock (set by mlLockScroll): the page underneath is pinned in place. */
html.ml-scroll-locked { overscroll-behavior: none; }

/* ---- 5. Habits on phones: check-in before the Life Balance chart; whole row is the target. ---- */
@media (max-width: 860px) {
  #mainTabProgress > .progress-top-row:not(.progress-top-row--natural) > .progress-section:nth-child(2) { order: -1; }
}
@media (max-width: 860px), (pointer: coarse) {
  #dueTodayList .habit-checkin-row { min-height: 48px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
}
/* HTML drag-and-drop does nothing on touch screens; the ▲▼ buttons remain the way to reorder. */
@media (pointer: coarse) { .habit-drag-handle { display: none; } }
html.force-touch .habit-drag-handle, html.force-touch-large .habit-drag-handle { display: none; }

/* ---- 6. Today: habit rows are real check-offs (same checkbox look as Habits). ---- */
.td-habit-row { cursor: pointer; min-height: 44px; }
.td-habit-row:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* ---- 7. 44px floor for segmented/period/filter toggles on phones. Visual density is kept
        by centring the label in the taller box rather than enlarging the type. ---- */
@media (max-width: 860px), (pointer: coarse) and (max-height: 500px) and (max-width: 1024px) {
  .pv-btn, .fin-range-btn, .ins-tf-btn, .ib-cat-btn, .tab-btn, .hm-tab-btn,
  .home-nav-btn, .life-nav-btn, .trav-nav-btn, .trav-modal-sub-btn, .device-menu-action {
    min-height: 44px;
  }
  .fin-range-btn, .pv-btn, .ins-tf-btn, .ib-cat-btn, .hm-tab-btn {
    display: inline-flex; align-items: center; justify-content: center;
  }
}

/* ---- 8. Add Interest gets the same header close control as every other form. ---- */
#interestModalOverlay .fit-modal-head { display: flex; align-items: center; justify-content: space-between; }

/* ---- 9. The close control is the last thing to go: when full-screen Apex is very narrow
        (a zoomed-in phone, a 320px screen), secondary header items fold away first. ---- */
#apexPanel.apex-mode-fullscreen { container-type: inline-size; container-name: apexfs; }
#apexPanel.apex-mode-fullscreen .ai-topbar { min-width: 0; }
#apexPanel.apex-mode-fullscreen .ai-topbar-id { overflow: hidden; }
#apexPanel.apex-mode-fullscreen .ai-topbar-actions { flex: 0 0 auto; }
#apexPanel.apex-mode-fullscreen .ai-topbar-actions button[aria-label="Close Apex"] { flex: 0 0 auto; }
@container apexfs (max-width: 330px) {
  #apexClearChatBtn, .ai-provider-pill { display: none !important; }
}
@container apexfs (max-width: 230px) {
  #apexHomeBtn { display: none !important; }
  .ai-topbar .module-title { font-size: 14px; }
}
/* Composer never pushes Send off a narrow (zoomed) full-screen Apex. */
#apexPanel.apex-mode-fullscreen .ai-input-row { display: flex; gap: 8px; min-width: 0; }
#apexPanel.apex-mode-fullscreen .ai-input-row .ai-input { flex: 1 1 auto; min-width: 0; width: auto; }
#apexPanel.apex-mode-fullscreen .ai-input-row .btn { flex: 0 0 auto; }
