/*
 * Vaeron visual identity, ported from the production app so this dashboard is
 * the same product rather than a lookalike. Values copied verbatim from
 * apps/web/src/app/globals.css — nothing re-picked by eye.
 *
 * THE ONE RULE: colour is signal, never decoration. The chrome is monochrome
 * (graphite -> platinum); the only saturated hues on screen are success /
 * warning / danger = up-good / caution / down-bad. The "accent" is a
 * colourless platinum-ice — never a hue. On a trading dashboard that rule does
 * real work: a green number means money, not styling.
 */
:root {
  /* Graphite ramp — near-black with a faint cool cast. The elevation steps are
     deliberate: a panel must lift off the ground, not read as a hairline on black. */
  --canvas: #050608;
  --surface: #101319;
  --surface-raised: #1a1e26;
  --line: #171a20;
  --line-strong: #3b424e;

  /* Platinum text ramp. `muted` carries load-bearing content, so it sits at
     ~4.9:1 on surface rather than the ~2.5:1 the first pass measured. */
  --text: #fbfcfd;
  --text-secondary: #8b929e;
  --dim: #8b93a0;

  /* Accent — colourless platinum-ice. Focus, active rails, the mark. */
  --accent: #dceaf2;
  --focus-ring: #cfe0ea;

  /* Signal — the entire colour budget. */
  --green: #45de8c;
  --warning: #fbbf52;
  --red: #fb7185;

  /* The lit end of each signal hue.
   *
   * Only for the top stop of a filled signal button — the two-stop gradient
   * that makes a solid surface read as lit rather than flat, the same trick
   * `.platinum` plays with white. They are surfaces, never text: at these
   * lightnesses neither clears a contrast floor on the graphite ground, and
   * both are meant to carry dark ink rather than be read against dark.
   *
   * Written out longhand in two pages before this, which is two places for a
   * hue to drift from the base it is supposed to be a tint of.
   */
  --green-soft: #8ff0bd;
  --red-soft: #ffb3bf;

  /* Semantic aliases. Use these for verdicts and P&L, never the raw
     hue — it keeps "is this good?" separate from "which colour?". */
  --good: var(--green);
  --bad: var(--red);
  --neutral: var(--text-secondary);

  --font-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

body {
  background: var(--canvas);
  color: var(--text);
  font-family: var(--font-sans);
}

/* A whisper of grain over everything, for material depth. Pointer-safe. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  pointer-events: none;
  opacity: 0.02;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* Liquid glass — chrome only (bars, panels, chips). Never on dense content. */
.glass {
  position: relative;
  background: linear-gradient(145deg, rgba(255,255,255,.09),
                              rgba(255,255,255,.02) 46%, rgba(255,255,255,.035));
  backdrop-filter: blur(28px) saturate(1.5);
  -webkit-backdrop-filter: blur(28px) saturate(1.5);
  border: 1px solid rgba(220,234,242,.18);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28),
              inset 0 -1px 0 rgba(0,0,0,.3),
              0 14px 44px rgba(0,0,0,.44);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass { background: rgba(26,30,38,.94); }
}

/* Brushed-platinum TEXT — display headlines and the wordmark. */
.metal-text {
  background: linear-gradient(178deg, #fff 0%, #eaf0f4 38%, #a9b4be 52%,
                              #eaf0f4 66%, #fff 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* The mark, cropped to its own ink.
 *
 * `vaeron-emblem.png` is 341x512 but the mark inside it is only 222x270 — 47%
 * of the file's height is transparent padding. Setting `height` on the image
 * scales the padding along with the mark, which is why a 22px emblem showed
 * about 11px of actual logo.
 *
 * Here rather than in `_chrome.css` because the sign-in screen draws the same
 * mark and does not load the chrome. It had its own uncropped copy, so the
 * first screen anyone sees still wore the small version.
 *
 * `--emblem` is the height of the *mark*, not of the file; the multipliers are
 * the ink box measured off the asset and hold for any value of it. If the
 * artwork is ever re-exported tight they all become 1 and the wrapper can go.
 */
/* The default is a fallback inside `var()`, never a declaration on `.emblem`
 * itself: a custom property set on the element beats one inherited from its
 * parent, so `--emblem: 24px` here silently pinned every mark in the app to
 * 24px and ignored the 38px the header asks for. */
.emblem { display: block; position: relative; overflow: hidden; flex: none;
          height: var(--emblem, 24px);
          width: calc(var(--emblem, 24px) * 0.8222); }
.emblem img { position: absolute; max-width: none;
              height: calc(var(--emblem, 24px) * 1.8963);
              width: calc(var(--emblem, 24px) * 1.263);
              top: calc(var(--emblem, 24px) * -0.3704);
              left: calc(var(--emblem, 24px) * -0.2185); }

/* Polished-platinum SURFACE — the CTA, active tabs. Dark ink on light metal. */
.platinum {
  color: #06080a;
  background: linear-gradient(160deg, #fff 0%, #dce4ea 45%, #b4c0c9 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9),
              inset 0 -2px 4px rgba(0,0,0,.12),
              0 8px 22px rgba(0,0,0,.5);
}

/* The default button: a platinum surface, because the app's buttons are all
 * primary actions. Seven pages carried this rule byte-for-byte — seven copies
 * of one gradient, and seven chances for it to drift.
 *
 * A page that wants something else overrides it: every page's own <style>
 * block is parsed after this file, and any class beats a bare type selector
 * regardless.
 */
button {
  font: 600 12px/1 var(--font-sans);
  border: 0; border-radius: 8px; padding: 9px 13px; cursor: pointer;
  color: #06080a;
  background: linear-gradient(160deg, #fff 0%, #dce4ea 45%, #b4c0c9 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9),
              inset 0 -2px 4px rgba(0,0,0,.12),
              0 8px 22px rgba(0,0,0,.5);
}

/* Slow catch-the-light shimmer — metal and glass chrome only. */
.u-shimmer { position: relative; overflow: hidden; }
.u-shimmer::after {
  content: "";
  position: absolute; top: -50%; bottom: -50%; left: -60%;
  width: 45%; pointer-events: none;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.4), transparent);
  transform: skewX(-18deg);
  animation: vaeron-sweep 7s ease-in-out infinite;
}
@keyframes vaeron-sweep {
  0%   { left: -60%; }
  22%  { left: 130%; }
  100% { left: 130%; }
}

/*
 * A COMPLETELY static Vaeron, not a reduced one.
 *
 * Brand Guidelines v2 p.26: every animation is gated behind
 * prefers-reduced-motion, and a surface that animates under it is a defect.
 * Gating by name is only ever as complete as the last person who remembered,
 * so this covers everything by construction. Durations are near-zero rather
 * than `none` so transitionend listeners still fire.
 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .u-shimmer::after { animation: none !important; }
}

/* Keyboard focus, defined once for the whole app.
 *
 * Per-page stylesheets each grew their own `:focus-visible` rules for whatever
 * component was being worked on that day, so coverage was accidental: the lab
 * and race pages styled only their dropdown, and the sign-in screen — the one
 * page nobody can skip — had no focus styling at all. A keyboard user tabbing
 * through it moved an invisible cursor. Putting it here means a new page
 * cannot ship without it.
 */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: 3px;
}
/* Only for pointer users who have not moved focus by keyboard. */
:focus:not(:focus-visible) { outline: none; }

/* Text for screen readers and nothing else.
 *
 * Not `display:none` and not `visibility:hidden` — both remove it from the
 * accessibility tree along with the layout, which is the opposite of the
 * point. This is the clip-rect idiom: still rendered, still announced, one
 * pixel nobody can see.
 *
 * Used for the things a sighted reader gets from position and styling and a
 * screen reader gets from nothing at all: the dashboard's page title, the
 * "last updated" prefix on a bare timestamp, the name of a table.
 */
.u-sronly {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Skip past the chrome.
 *
 * The header is six links, and it is identical on every page. Without this a
 * keyboard user re-tabs the whole bar on every navigation before reaching
 * anything the page is actually about.
 *
 * Visible only while focused, and it has to sit above the sticky header — a
 * skip link that appears underneath the thing it skips is worse than none,
 * because it reads as broken.
 */
.skiplink {
  position: fixed;
  top: 8px; left: 8px;
  z-index: 100;
  transform: translateY(-200%);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  padding: 10px 14px;
  font: 600 13px var(--font-sans);
  text-decoration: none;
}
.skiplink:focus { transform: translateY(0); }

/* The agent card's stylesheet used to be here, forty-five rules of it, for a
 * card that no page rendered. Its own comment said "defined once here because
 * two pages draw it" — and both of those pages had long since grown a card of
 * their own, in their own `<style>`, byte-identical to each other.
 *
 * The card lives in `_fleet.css` now, beside everything else those two pages
 * share, and `card.js` renders it for both. What was here is deleted rather
 * than moved: none of it was reachable.
 */

/* How the agent is doing, at the edge of the card. Colour on these pages
   means money and nothing else, so this is never tinted by which group the
   card was filed under — a proven agent can be deeply in the red. */
/* The sample the rate rests on. 100% of one settled trade is not a record. */
/* Kept for any action that is genuinely unavailable — a disabled control
   must never sit next to a live one without saying why. */

/* ── Daily P&L curve ─────────────────────────────────────────────────────────
 *
 * Shared, like the agent card: the squadron shows the whole fleet, an agent
 * page shows one agent, and the component is identical. Namespaced so nothing
 * else can reach it — a bare `.curve` or `.tip` in a global sheet is the
 * collision that already happened twice.
 */
.pnlcurve { display:grid; grid-template-columns:minmax(190px,232px) minmax(0,1fr);
            gap:30px; align-items:center; }
@media (max-width: 820px) { .pnlcurve { grid-template-columns:1fr; gap:20px; } }
.pnlread { min-width:0; }
.pnlread .k { font-size:10px; letter-spacing:.14em; text-transform:uppercase;
              color:var(--dim); }
.pnltodate { font:600 30px/1 var(--mono); margin-top:9px; letter-spacing:-.03em;
             font-variant-numeric:tabular-nums; white-space:nowrap; }
.pnltrades { font-size:12px; color:var(--dim); margin-top:9px; line-height:1.5; }
.pnlsplit { display:grid; grid-template-columns:1fr 1fr; gap:14px;
            margin-top:18px; padding-top:15px; border-top:1px solid var(--line); }
.pnlsplit .v { font:600 14px/1 var(--mono); margin-top:6px;
               font-variant-numeric:tabular-nums; white-space:nowrap; }

.pnlplot { position:relative; min-width:0; }
.pnlsvg { display:block; width:100%; height:210px; }
@media (max-width: 820px) { .pnlsvg { height:170px; } }
.pnlgrid { stroke:var(--line-strong); stroke-width:1; opacity:.35; }
.pnlzero { stroke:var(--line-strong); stroke-width:1; opacity:.9; }
.pnlaxis { font:10px var(--mono); fill:var(--dim); }
.pnlline { fill:none; stroke:var(--green); stroke-width:2;
           stroke-linejoin:round; stroke-linecap:round; }
.pnlline.neg { stroke:var(--red); }
.pnlfill { fill:var(--green); opacity:.12; }
.pnlfill.neg { fill:var(--red); opacity:.12; }
.pnlpt { fill:var(--text); stroke:var(--surface); stroke-width:2;
         transition:r .12s ease; pointer-events:none; }
.pnlpt.on { r:6; }

/* Real buttons over the points. An SVG shape with `tabindex` becomes
   activeElement but fires no focus event, and a 4px circle is not something a
   thumb can hit. */
.pnlhits { position:absolute; inset:0; pointer-events:none; }
.pnlhit { position:absolute; width:34px; height:34px; padding:0; border:0;
          background:none; box-shadow:none; border-radius:50%;
          transform:translate(-50%, -50%); cursor:pointer; pointer-events:auto; }
.pnlhit:focus-visible { outline:2px solid var(--focus-ring); outline-offset:0; }

.pnltip { position:absolute; z-index:5; pointer-events:none;
          background:var(--surface-raised); border:1px solid var(--line-strong);
          border-radius:10px; padding:11px 13px; min-width:168px;
          box-shadow:0 16px 34px -14px rgba(0,0,0,.8);
          transform:translate(-50%, calc(-100% - 14px)); }
.pnltip[hidden] { display:none; }
.pnltip.below { transform:translate(-50%, 14px); }
.pnltip .when { font:500 10px/1 var(--mono); letter-spacing:.12em;
                text-transform:uppercase; color:var(--dim); }
.pnltip .amt { font:600 18px/1 var(--mono); margin-top:7px;
               font-variant-numeric:tabular-nums; }
.pnltip .rows { display:grid; grid-template-columns:auto auto; gap:3px 14px;
                margin-top:9px; padding-top:9px; border-top:1px solid var(--line);
                font:500 11.5px/1.4 var(--mono); }
.pnltip .rows span:nth-child(odd) { color:var(--dim); }
.pnltip .rows span:nth-child(even) { text-align:right;
                                     font-variant-numeric:tabular-nums; }

/* Tone for signed figures, defined once because the shared components use it.
   Colour on a bare class is safe in a shared sheet — a dimension is not. */
.pos { color: var(--good); }
.neg { color: var(--bad); }
.flat { color: var(--neutral); }


/* ── A book with no agents in it ──────────────────────────────────────────
   The live fleet is empty until a user funds an agent, and a page of zeros
   does not say that — $0.00 across nine tiles reads as a loss, or as a
   failed fetch, rather than as "nothing has happened here yet". So the
   aggregate pages replace themselves with a sentence when the book they were
   asked for holds no agents at all.

   `display:none` on the hidden state explicitly: `[hidden]` is a `display:
   none` rule of the lowest possible specificity, and a `display:grid` on the
   same element beats it — which is how a hidden panel ends up on screen. */
/* `align-items:stretch`, and `text-align:left` said outright: a flex column
   with `flex-start` shrink-wraps each paragraph to its own longest line, and
   the page underneath centres its text — so the first paragraph came out
   centred inside a box whose second paragraph was not. */
.nobook { display:flex; flex-direction:column; align-items:stretch;
          gap:10px; max-width:52ch; margin:56px auto; padding:28px 30px;
          text-align:left; border:1px solid var(--line); border-radius:14px;
          background:var(--surface); }
.nobook[hidden] { display:none; }
.nobook h2 { font:600 19px var(--font-sans); letter-spacing:-.015em;
             margin:0; color:var(--text); }
.nobook p { margin:0; font-size:13.5px; line-height:1.6;
            color:var(--text-secondary); }
.nobook .go { align-self:flex-start; margin-top:6px; padding:9px 15px; border-radius:9px;
              border:1px solid var(--line-strong); background:var(--surface-raised);
              color:var(--text); font:600 12.5px var(--font-sans);
              cursor:pointer; transition:background .15s, border-color .15s; }
.nobook .go:hover { background:rgba(255,255,255,.07);
                    border-color:var(--accent); }
.nobook .go:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
/* Everything the page would otherwise have drawn. Kept in the DOM rather than
   emptied so a switch back does not have to rebuild it from nothing. */
main.empty > *:not(.nobook):not(.u-sronly) { display:none; }
