/* ============================================================================
 * nergyapp/theme.css — the app's design tokens.
 * ----------------------------------------------------------------------------
 * Nothing below this file hard-codes a colour, a radius, a shadow or a font. If
 * a rule in `nergyapp.css` or `chrome.css` needs one that is not here, the token
 * is missing — add it here, BOTH THEMES AT ONCE. That is the whole discipline,
 * and it is what makes the light theme a set of values rather than a second
 * stylesheet somebody has to remember to update.
 *
 * WHAT CHANGED, AND WHY IT IS NOT A REPAINT. The palette was transcribed from
 * `NERGY_ref.html` — flat greys, one border weight, no elevation, no scale. That
 * reads as a prototype, and this is an instrument people are asked to trust with
 * expensive work. So the tokens now carry the three things a flat set cannot:
 *
 *   · DEPTH. Surfaces are a ladder (page → surface → raised → sunken), and each
 *     rung is a token rather than a one-off. A card knows what it sits on.
 *   · WEIGHT. Three border strengths and three elevations, so "quiet", "here"
 *     and "in front of everything" are distinguishable without colour.
 *   · SCALE. Radii and shadows step; nothing is a magic number in a rule.
 *
 * The hues are the app's own — the same blue, the same green, the same red. The
 * neutrals are cooled a few degrees towards blue, which is what stops a dark UI
 * from reading as grey plastic, and the light theme is built on the same ladder
 * rather than as an inversion of it.
 *
 * THE STAGE RAMP (`--rb1`…`--rb6`) is the one part of the palette that is not a
 * single accent, and it is deliberate. A plan is a pipeline, so its stages are
 * coloured along ONE axis — indigo → blue → cyan → teal → green → lime — rather
 * than from a categorical set. Neighbouring stages stay distinguishable, the
 * whole map still reads as one object, and the colour carries a meaning a random
 * assignment could not: how far through the work a stage sits. It does not
 * compete with the accent, because the accent is a FILL and these are hairlines
 * and washes.
 *
 * They are stored as bare `H S L` triples, not as colours, so a rule can ask for
 * the same hue at any opacity — `hsl(var(--rb) / .12)` for the wash under a
 * ribbon, `hsl(var(--rb))` for the ribbon itself. That is still one source per
 * hue per theme, which is the rule this file exists to keep.
 *
 * Fonts come from /vendor/fonts/fonts.css, which the service already serves.
 * ==========================================================================*/

:root {
  /* The surface ladder — page, the surface on it, what is raised off that, and
     what is cut into it (an input, a well, a chip at rest). The rungs are further
     apart than they were: a card that is two points off the page it sits on is a
     card the eye has to be told about with a border. */
  --bg:#090C12; --bg2:#141B2A; --bg3:#1D2740; --bg4:#2B3752;
  --surface:var(--bg2); --surface-raised:#182135; --surface-sunken:#080B10;

  /* Borders carry a little of the page's blue rather than being pure white at low
     alpha — a grey hairline over a blue surface reads as dirt. Raised a shade from
     the first pass: at the depth this page sits at, a 10% hairline was reading as
     no line at all — the surfaces have to be told apart without one. */
  --border:rgba(150,172,214,0.16); --border2:rgba(150,172,214,0.26); --border3:rgba(150,172,214,0.42);
  /* --muted raised a step: at this depth #7A879E measured under 4.5:1 against a
     raised card, which is exactly where it carries a menu label or a table's
     secondary column — the two places dim text is least forgivable. */
  --text:#EAEFF7; --muted:#8894AA; --muted2:#9AA7BE; --muted3:#C6CFE0;

  --blue:#C87A3D; --blue2:#A85F27; --blue-dim:rgba(200,122,61,0.16); --blue-glow:rgba(200,122,61,0.26);
  --blue-glow-soft:rgba(200,122,61,0.22);
  --cyan:#4FAFA0;
  --green:#4ADE80; --green-dim:rgba(74,222,128,0.14);
  --amber:#FBBF24; --red:#FB7185; --red-dim:rgba(251,113,133,0.14);
  /* The dark theme's red is a light salmon, so text ON it has to be dark. Not a
     colour choice — a contrast one, and it inverts with the theme. */
  --on-red:#1a0d0d;
  --on-accent:#ffffff;

  /* The accent, in the two shapes it is actually used in: a hairline along the
     top of something that matters, and a fill for the one primary action. */
  --accent-line:linear-gradient(90deg,var(--blue) 0%,var(--cyan) 45%,transparent 92%);
  --accent-fill:linear-gradient(135deg,var(--blue) 0%,var(--blue2) 100%);

  --sans:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:'IBM Plex Mono','SF Mono',ui-monospace,monospace; --serif:Georgia,serif;

  /* Series colours for charts. EIGHT, because that is where a categorical palette
     stops being distinguishable — past it the eye is guessing, and `chart.js` wraps
     rather than inventing a ninth. Ordered so the first few are far apart in hue:
     most charts use two or three, and those are the ones that must not be confused.
     They live here rather than in the module because a hex in a module is a hex that
     does not know the light theme exists. */
  --ch1:var(--blue); --ch2:#34d399; --ch3:#fbbf24; --ch4:#f472b6;
  --ch5:#a78bfa; --ch6:#22d3ee; --ch7:#fb7185; --ch8:#94a3b8;

  /* THE STAGE RAMP — see the header. `H S L` triples, so one hue serves the
     ribbon, its wash and its rail without three tokens each. Six, because a plan
     with more stages than that wraps rather than reaching for a seventh hue
     nobody can tell from the first. */
  --rb1:228 100% 73%; --rb2:208 92% 65%; --rb3:190 76% 56%;
  --rb4:169 68% 52%;  --rb5:142 64% 62%; --rb6:78 62% 60%;

  /* app-shell layout tokens (theme-neutral) */
  /* THE WHOLE APP IS DRAWN AT 85%, and this is the one number that says so.
     Not a type scale: every length in the app — type, padding, icons, the bar,
     the rail, the radii — is px, so one `zoom` on the root shrinks all of them
     together and the proportions the screens were designed at survive intact.
     Scaling the ~350 font sizes instead would have shrunk the text inside boxes
     that stayed the same size, which is a different design, not a smaller one.

     `--screen-h` / `--screen-w` are the viewport IN THESE COORDINATES, and they
     exist because `zoom` does not scale viewport units: under a root zoom of z,
     `100vh` still means the viewport, so it lands on screen at z × viewport and
     a full-height screen stops short of the bottom edge with a band of page
     under it. Dividing by the zoom is what makes `100vh` mean the window again.
     Every full-bleed height and every viewport-sized modal reads these two;
     `vw` inside a `clamp()` deliberately does not — those are fluid paddings
     already bounded by px ends, and at any real window width they sit on one of
     those ends, which zoom has already scaled. */
  --zoom:0.85;
  --screen-h:calc(100vh / var(--zoom));
  --screen-w:calc(100vw / var(--zoom));
  /* And the dynamic one, for the single full-screen surface that has to survive a
     phone browser's own bar retracting under it. Same division, same reason. */
  --screen-dh:calc(100dvh / var(--zoom));
  /* `--rail-gap` is the air around the left rail and the sidebars. They are
     PANELS floating on the page rather than walls welded to its edges, and the
     gap is the one number that says so — the rail's inset, the room the screens
     leave it, and the breathing space a side panel keeps from the window edge
     are all this, so none of the three can drift from the other two. */
  /* `--topbar-h` grew with the bar's type. It is not decoration: the rail hangs
     off it, the project window is `100vh` minus it, and the account menu opens
     under it — so the bar's height is set HERE, once, and everything that has to
     agree with it already reads this. */
  --topbar-h:62px; --rail-w:60px; --rail-gap:10px;
  /* WHAT THE FLOATING "Ask" PILL COVERS. It is fixed to the bottom-right corner of
     the window (`.na-assistant-toggle`), so anything that scrolls under it has to
     keep this much clear at its end or its last control ends up under the pill and
     cannot be pressed. One number, because the pill is one thing: its own height,
     the inset it floats at, and a gap so a button does not sit against it. */
  --fab-clear:76px;
  --shell-bg:rgba(15,20,31,0.84); --shell-border:var(--border);
  --shell-elev:0 1px 0 rgba(0,0,0,0.35);

  /* A FIFTH RUNG THAT IS NOT ON THE LADDER: a container that is mostly the page.
     `--surface` says "a card, on top of what is behind it"; this says "a region,
     with an edge" — a fill faint enough that the page wash reads straight
     through it, and a hairline that is the whole of why the region has a shape.
     It exists for the panels that must be FINDABLE without becoming a second
     focal point beside a raised card (the Planner's files sidebar), and it is a
     token rather than a one-off because the moment a second such region wants
     the look, the two must not drift. Used with a blur, the way the top bar
     uses `--shell-bg`. */
  --glass:rgba(24,33,53,0.52); --glass-edge:rgba(150,172,214,0.22);

  /* Radii step, so nothing in a rule is a magic number: a chip, a control, a
     card, a dialog. How round a thing is says how big it is. */
  --radius-sm:6px; --radius:9px; --radius-lg:14px; --radius-xl:18px;

  /* Elevation. 1 = resting on the page, 2 = lifted off it, 3 = in front of it. */
  --elev-1:0 1px 2px rgba(0,0,0,0.30);
  --elev-2:0 6px 18px -8px rgba(0,0,0,0.55), 0 1px 2px rgba(0,0,0,0.30);
  --elev-3:0 28px 64px -22px rgba(0,0,0,0.72), 0 2px 8px rgba(0,0,0,0.40);
  --ring:0 0 0 3px var(--blue-glow-soft);

  /* The page is not one flat colour: two very faint pools of the accent, fixed,
     so scrolling does not drag them. This is the whole of the atmosphere — never
     a texture over the content, and never anything a reader has to see past. */
  --page-wash:
    radial-gradient(1180px 660px at 10% -10%, rgba(200,122,61,0.13), transparent 62%),
    radial-gradient(940px 540px at 94% 2%, rgba(79,175,160,0.07), transparent 60%),
    radial-gradient(820px 620px at 62% 108%, rgba(168,95,39,0.05), transparent 64%);
}

:root[data-theme="light"] {
  /* The page is a cool paper rather than white, so a white card is a CARD. An app
     whose surfaces and whose page are both #FFF has no ladder at all — it has one
     rung and a lot of borders standing in for the other three. Neutral enough that
     a screen that is mostly page — the Planner canvas, before anything is on it —
     reads as paper, not as a wash of colour; the first pass leaned too far toward
     blue for that much of it at once. */
  --bg:#F5F6F8; --bg2:#FFFFFF; --bg3:#EEF0F3; --bg4:#E2E5EB;
  --surface:var(--bg2); --surface-raised:#FFFFFF; --surface-sunken:#F6F8FD;

  --border:rgba(20,32,58,0.10); --border2:rgba(20,32,58,0.16); --border3:rgba(20,32,58,0.28);
  --text:#101828; --muted:#667085; --muted2:#475467; --muted3:#2E3B52;

  --blue:#A85A1E; --blue2:#7A3F12; --blue-dim:rgba(168,90,30,0.09); --blue-glow:rgba(168,90,30,0.18);
  --blue-glow-soft:rgba(168,90,30,0.16);
  --cyan:#227A6E;
  --green:#0E9D73; --green-dim:rgba(14,157,115,0.12);
  --amber:#C9971C; --red:#DC2626; --red-dim:rgba(220,38,38,0.09);
  --on-red:#ffffff;

  --shell-bg:rgba(255,255,255,0.88);
  --shell-elev:0 1px 2px rgba(16,24,40,0.06);

  /* White at half strength over cool paper — a shade lighter than the page and
     no more, so the region is read from its edge rather than from its fill. The
     edge is a touch softer than `--border2`: on paper a hairline carries further
     than it does over a dark surface, and this one is drawing a whole column. */
  --glass:rgba(255,255,255,0.55); --glass-edge:rgba(20,32,58,0.14);

  --elev-1:0 1px 2px rgba(16,24,40,0.06);
  --elev-2:0 8px 24px -12px rgba(16,24,40,0.18), 0 1px 2px rgba(16,24,40,0.06);
  --elev-3:0 28px 64px -24px rgba(16,24,40,0.28), 0 2px 8px rgba(16,24,40,0.08);

  --page-wash:
    radial-gradient(1180px 660px at 10% -10%, rgba(168,90,30,0.09), transparent 62%),
    radial-gradient(940px 540px at 94% 2%, rgba(34,122,110,0.06), transparent 60%),
    radial-gradient(820px 620px at 62% 108%, rgba(168,90,30,0.04), transparent 64%);

  /* Darkened against white. The dark theme's series colours are tuned to sit on
     a dark card and go to pastel wash on a light one — same hues, more saturation. */
  --ch1:var(--blue); --ch2:#059669; --ch3:#C9971C; --ch4:#db2777;
  --ch5:#7c3aed; --ch6:#0891b2; --ch7:#e11d48; --ch8:#475569;

  /* The same ramp, walked down in lightness so every rung clears text contrast on
     paper. Same hues, same order, so a screenshot in either theme reads alike. */
  --rb1:232 72% 55%; --rb2:213 80% 46%; --rb3:192 84% 34%;
  --rb4:171 80% 30%; --rb5:145 68% 30%; --rb6:76 62% 31%;
}

* { box-sizing:border-box; margin:0; padding:0 }

/* The 85% itself, applied once, at the root. On `html` rather than on `body` so
   that fixed chrome — the top bar, the rail, the floating pill — is scaled with
   everything else rather than left at full size beside it. */
html { zoom:var(--zoom) }

html, body {
  height:100%;
  font-family:var(--sans);
  background:var(--bg);
  color:var(--text);
  font-size:15px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

/* The atmosphere, as its own layer: fixed, behind everything, inert to the
   pointer. On an element rather than on `body`'s background so a screen that
   scrolls does not drag the light down the page with it. */
body::before {
  content:''; position:fixed; inset:0; z-index:-1;
  background:var(--page-wash); pointer-events:none;
}

/* A number that changes in place — a percentage, a clock, a count — must not
   make the line beside it jump. */
.na-hg-pct, .na-hg-micro, .na-hg-clock { font-variant-numeric:tabular-nums }

::selection { background:var(--blue-dim); color:var(--text) }

/* One scrollbar treatment, so a panel that scrolls does not look like a
   different application from the one that does not. */
* { scrollbar-width:thin; scrollbar-color:var(--border2) transparent }
::-webkit-scrollbar { width:10px; height:10px }
::-webkit-scrollbar-track { background:transparent }
::-webkit-scrollbar-thumb {
  background:var(--border2); border-radius:99px;
  border:3px solid transparent; background-clip:content-box;
}
::-webkit-scrollbar-thumb:hover { background:var(--border3); background-clip:content-box }
