/* PennyScan GUI — the design tokens, the shell (menu and top bar) and the
   shared components of the new pages.

   SCOPE. Every rule here is scoped to a `.ps-*` class or to `body.ps-page`
   (the new pages). Nothing restyles a legacy page's own content: style.css
   and dashboard.css keep their own tokens (--bg, --panel, --ink, --line,
   --accent, --pos, --neg …), and every token here is prefixed --ps- so a
   legacy page that loads this file keeps every colour it had. Base element
   styles (font, links, box sizing) apply only under body.ps-page.

   FONT. IBM Plex Sans and IBM Plex Sans Condensed, self-hosted from
   public/fonts/ (the @font-face block below; the owner's OK of 2026-10-12).
   The system stack behind each family in --ps-font / --ps-font-cond is what
   shows while a face loads (font-display: swap) and for any character
   outside the Latin range. Figures are tabular everywhere.

   COLOUR MEANS ONE THING EACH (the brief, with the owner's step-2 answers):
   - Teal / coral: gain / loss. Coral also says "engine down" on the status
     dot. Nothing decorative is teal or coral.
   - Amber: needs attention but is not a loss — stale data, Stopped (the kill
     switch), a kill-switch event, a position near its floor, and "New buys
     paused" once the daily loss pause has tripped.
   - Lavender: in DATA (charts, markers, dots, chips) it only ever means
     Athena. In CHROME it is the selected / link / focus accent. The status
     dot and the Real-orders dot are the text colour, never lavender.
   - Lime: chart callouts and "new" markers only.
   - --ps-line (#65708C) draws every non-text boundary: cards, inputs, the
     unselected interactive pills, the $0 baseline (dashed), tracks. It is at
     least 3:1 against the page, a card and a raised surface. The brief's
     #26304A border, and #222B42, #4A5675 and #2A3450, fail 3:1 and are not
     tokens (test/ps-tokens.test.js holds every pair).
   - Chart area fills (teal/coral at low alpha) are decorative: the line
     carries the data, so the fills are exempt from the 3:1 rule.
   - Future risk: Mercury's silver sits close to the text colour of a buy
     ring. Revisit when Mercury is built. */

/* ── the fonts: IBM Plex Sans and IBM Plex Sans Condensed ────────────────────
   @fontsource/ibm-plex-sans 5.3.0 and @fontsource/ibm-plex-sans-condensed
   5.3.0 (OFL-1.1: public/fonts/OFL.txt and OFL-Condensed.txt), copied byte
   for byte into public/fonts/: the Latin subset, normal style, weights 400,
   500, 600 and 700 — the only weights this file uses — as woff2. Each
   unicode-range is the package's own Latin one. public/fonts/README.md holds
   the source, the tarball integrity and every file's sha256;
   test/fonts.test.js holds this block, the files and the README together.
   Declaring a face downloads nothing: a page fetches a file only when it
   draws text in that family and weight. */

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-600-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-latin-700-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans Condensed";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-condensed-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans Condensed";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-condensed-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-condensed-latin-600-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "IBM Plex Sans Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/ibm-plex-sans-condensed-latin-700-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root {
  --ps-bg: #0D111C;
  --ps-card: #151B2B;
  --ps-raised: #1C2438;
  --ps-text: #E7EAF3;
  --ps-text-2: #B7BED0;
  --ps-muted: #8A93AB;
  --ps-line: #65708C;
  --ps-up: #2ED3B7;
  --ps-down: #FF6B6B;
  --ps-warn: #F5B544;
  --ps-accent: #A89BFF;
  --ps-accent-2: #C9C1FF;
  --ps-on-accent: #0D111C;
  --ps-lime: #D6F36B;
  --ps-athena: #A89BFF;
  --ps-tyr: #7DB3FF;
  --ps-mercury: #D5DBE8;
  --ps-up-tint: rgba(46, 211, 183, 0.14);
  --ps-down-tint: rgba(255, 107, 107, 0.14);
  --ps-warn-tint: rgba(245, 181, 68, 0.14);
  --ps-accent-tint: rgba(168, 155, 255, 0.14);
  --ps-win-row: rgba(46, 211, 183, 0.07);
  --ps-loss-row: rgba(255, 107, 107, 0.08);
  --ps-warn-zone: rgba(245, 181, 68, 0.5);
  --ps-r-card: 16px;
  --ps-r-hero: 20px;
  --ps-r-row: 8px;
  --ps-r-pill: 999px;
  --ps-rail-w: 96px;
  --ps-tabbar-h: 64px;
  --ps-gutter: 16px;
  --ps-font: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ps-font-cond: "IBM Plex Sans Condensed", "IBM Plex Sans", "Arial Narrow", system-ui, sans-serif;
}

/* ── the new pages' base (never a legacy page) ───────────────────────────── */

body.ps-page {
  box-sizing: border-box;
  margin: 0;
  min-height: 100vh;
  background: var(--ps-bg);
  color: var(--ps-text);
  color-scheme: dark;
  font: 15px/1.5 var(--ps-font);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  -webkit-text-size-adjust: 100%;
}

body.ps-page *,
body.ps-page *::before,
body.ps-page *::after { box-sizing: border-box; }

/* Zero-weight, so every .ps-* component (the rail, the tabs, the sheet) keeps its own colour. */
:where(body.ps-page) a { color: var(--ps-accent); }
:where(body.ps-page) a:where(:hover) { color: var(--ps-accent-2); }

.ps-main {
  max-width: 1248px;
  padding: 24px var(--ps-gutter) 48px;
}
.ps-main > * + * { margin-top: 16px; }

.ps-h1 {
  margin: 0;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

.ps-h2 {
  margin: 0 0 12px;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.25;
}

.ps-lede {
  margin: 0 0 16px;
  max-width: 44rem;
  color: var(--ps-text-2);
}

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

/* ── the shell: what every page shares ───────────────────────────────────── */

.ps-skip,
.ps-top,
.ps-rail,
.ps-tabbar,
.ps-sheet {
  box-sizing: border-box;
  font-family: var(--ps-font);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  -webkit-text-size-adjust: 100%;
}

.ps-top *,
.ps-rail *,
.ps-tabbar *,
.ps-sheet * { box-sizing: border-box; }

/* Skip link: the first focusable thing on the page, visible only on focus. */
.ps-skip {
  position: absolute;
  top: -200px;
  left: 8px;
  z-index: 40;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  border-radius: var(--ps-r-row);
  background: var(--ps-accent);
  color: var(--ps-on-accent);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.ps-skip:focus { top: 8px; }

/* Focus: a lavender ring, 2px, offset 2px — on the shell and the new pages. */
.ps-skip:focus-visible,
.ps-top :focus-visible,
.ps-rail :focus-visible,
.ps-tabbar :focus-visible,
.ps-sheet :focus-visible,
body.ps-page :focus-visible {
  outline: 2px solid var(--ps-accent);
  outline-offset: 2px;
}

/* ── the top bar: in flow, never sticky (a legacy page's own sticky bar stays) */

.ps-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px 10px;
  min-height: 56px;
  padding: 8px var(--ps-gutter);
  background: var(--ps-bg);
  border-bottom: 1px solid var(--ps-line);
  color: var(--ps-text);
  font-size: 13px;
  line-height: 1.3;
}

/* The flex-row legacy bodies (/, /credentials, /paper): the bar takes its own
   row, edge to edge across the body's padding. The sign-in and devices cards
   keep their layout. /paper's DOES change: its header and main shared one
   flex row and shrank to fit it; now, whenever the two do not fit side by
   side (always on a phone, and on a desktop once the page's content is
   wide), main wraps below the header — a known side effect until /paper's
   own restyle. */
body.ps-has-top:not(.page-wide):not(.ps-page) { flex-wrap: wrap; align-content: flex-start; }
body.ps-has-top:not(.page-wide):not(.ps-page) > .ps-top {
  flex: 1 0 100%;
  margin: -2rem -1rem 1.5rem;
}

.ps-brand {
  order: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  background: var(--ps-raised);
  color: var(--ps-accent);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  margin-right: auto;
}

.ps-top .ps-h1 { order: 1; margin-right: auto; font-size: 22px; }

.ps-modebox {
  order: 2;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

.ps-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  padding: 4px 12px;
  border-radius: var(--ps-r-pill);
  background: var(--ps-raised);
  color: var(--ps-text-2);
  font-size: 13px;
  line-height: 1.25;
  white-space: nowrap;
}

.ps-top .ps-picks { order: 3; }
/* Until the first status read answers, the mode and own-picks pills hold their place unseen (ps-shell.js): on a
   phone they are the bar's second row, which must not appear under a page already drawn (/live's STOP). */
.ps-top [data-pending="true"] { visibility: hidden; }
.ps-top .ps-clock { order: 4; color: var(--ps-text); }
.ps-top .ps-status { order: 5; }
.ps-break { display: none; }

/* The mode pill: the SHAPE carries the state, so colour is never the only cue. */
.ps-mode { color: var(--ps-text); }
.ps-glyph {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
}
.ps-mode[data-pill="real"] .ps-glyph { border-radius: 50%; background: var(--ps-text); }
.ps-mode[data-pill="paper"] .ps-glyph { border-radius: 50%; border: 2px solid var(--ps-text); }
.ps-mode[data-pill="stopped"] { color: var(--ps-warn); }
.ps-mode[data-pill="stopped"] .ps-glyph { border-radius: 1px; background: var(--ps-warn); }
.ps-mode[data-pill="closed"] { color: var(--ps-muted); }
.ps-mode[data-pill="closed"] .ps-glyph { display: none; }

.ps-next {
  padding-left: 12px;
  color: var(--ps-muted);
  font-size: 12px;
  white-space: nowrap;
}

/* Under the Real orders pill after a mid-session OFF: plain words, secondary text — no money colour. */
.ps-entries-off {
  padding-left: 12px;
  color: var(--ps-text-2);
  font-size: 12px;
  white-space: nowrap;
}

/* New buys paused: the daily loss pause has tripped. Amber — attention, not a loss; read only, beside the mode.
   Its two bars are the shape cue, so colour is never the only one. */
.ps-top .ps-paused { order: 3; }
.ps-paused {
  color: var(--ps-warn);
  background: var(--ps-warn-tint);
}
.ps-paused .ps-icon {
  width: 14px;
  height: 14px;
  stroke-width: 2.4;
}

/* The status: a dot and words that always say the state. */
.ps-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  color: var(--ps-text-2);
  white-space: nowrap;
}
.ps-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 2px solid var(--ps-muted);
}
.ps-status[data-state="ok"] .ps-dot { border-color: var(--ps-text); background: var(--ps-text); }
.ps-status[data-state="stale"] { color: var(--ps-warn); }
.ps-status[data-state="stale"] .ps-dot { border-color: var(--ps-warn); background: var(--ps-warn); }
.ps-status[data-state="down"] { color: var(--ps-down); white-space: normal; }
.ps-status[data-state="down"] .ps-dot { border-color: var(--ps-down); background: var(--ps-down); }
.ps-status[data-state="signedout"],
.ps-status[data-state="checking"] { color: var(--ps-muted); }

.ps-status a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  min-width: 44px;
  color: var(--ps-accent);
  font-weight: 600;
}
.ps-status a:hover { color: var(--ps-accent-2); }

.ps-wide-only { display: inline; }
.ps-narrow-only { display: none; }

/* ── the rail (desktop, 768px and up) ────────────────────────────────────── */

/* No side padding: the items centre themselves (align-items), at the very place 12px of padding put them, in the
   95px left inside the 1px edge. 12px each side left 71px for the 72px items: a 1px overflow, and with it a
   horizontal scrollbar, since a box that scrolls one way scrolls both. With none, a classic vertical scrollbar
   (15-17px, on a window shorter than the rail's items) still leaves the items room. */
.ps-rail {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 32;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: var(--ps-rail-w);
  padding: 16px 0;
  overflow-y: auto;
  background: var(--ps-bg);
  border-right: 1px solid var(--ps-line);
}

.ps-rail-brand {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  margin-bottom: 12px;
  border-radius: 14px;
  background: var(--ps-raised);
  color: var(--ps-accent);
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
}

.ps-nav-item {
  position: relative;
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 72px;
  min-height: 60px;
  padding: 6px 2px;
  border-radius: var(--ps-r-card);
  color: var(--ps-muted);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
}
.ps-nav-item:hover { color: var(--ps-text); }
.ps-nav-item[aria-current="page"] {
  background: var(--ps-accent-tint);
  color: var(--ps-accent-2);
}
/* A selected item is not told by its tint alone (1.25:1): a 3px bar too. */
.ps-nav-item[aria-current="page"]::before {
  content: "";
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 0;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--ps-accent);
}

.ps-icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── the bottom tab bar and the More sheet (phone, under 768px) ──────────── */

.ps-tabbar {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 32;
  display: none;
  height: calc(var(--ps-tabbar-h) + env(safe-area-inset-bottom, 0px));
  padding: 0 4px env(safe-area-inset-bottom, 0px);
  background: var(--ps-card);
  border-top: 1px solid var(--ps-line);
}

.ps-tab {
  position: relative;
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 44px;
  min-height: 44px;
  height: var(--ps-tabbar-h);
  margin: 0;
  padding: 4px 2px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--ps-muted);
  font: 500 12px/1.2 var(--ps-font);
  text-decoration: none;
  cursor: pointer;
}
.ps-tab[aria-current="page"],
.ps-tab[data-active="true"],
.ps-tab[aria-expanded="true"] { color: var(--ps-accent-2); }
.ps-tab[aria-current="page"]::before,
.ps-tab[data-active="true"]::before {
  content: "";
  position: absolute;
  top: 0;
  left: 22%;
  right: 22%;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--ps-accent);
}

.ps-scrim {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: rgba(13, 17, 28, 0.72);
}

.ps-sheet {
  position: fixed;
  right: 0;
  bottom: calc(var(--ps-tabbar-h) + env(safe-area-inset-bottom, 0px));
  left: 0;
  z-index: 31;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - var(--ps-tabbar-h) - 24px);
  padding: 8px var(--ps-gutter) 16px;
  overflow-y: auto;
  background: var(--ps-card);
  border-top: 1px solid var(--ps-line);
  border-radius: var(--ps-r-card) var(--ps-r-card) 0 0;
  color: var(--ps-text);
}

.ps-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 48px;
}

.ps-sheet-title {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
}

.ps-sheet-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: 0 -8px 0 0;
  padding: 0;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-pill);
  background: transparent;
  color: var(--ps-text);
  cursor: pointer;
}

.ps-sheet-h {
  margin: 16px 0 4px;
  color: var(--ps-muted);
  font-size: 13px;
  font-weight: 500;
}

.ps-sheet-link {
  display: flex;
  align-items: center;
  min-height: 52px;
  padding: 0 12px;
  border-radius: var(--ps-r-row);
  color: var(--ps-text);
  font-size: 15px;
  text-decoration: none;
}
.ps-sheet-link:hover { background: var(--ps-raised); }
.ps-sheet-link[aria-current="page"] {
  background: var(--ps-accent-tint);
  color: var(--ps-accent-2);
}

/* `hidden` wins over every display rule here: the new pages load no
   style.css, whose [hidden] rule the legacy pages have. */
.ps-sheet[hidden],
.ps-scrim[hidden],
.ps-top [hidden],
.ps-rail [hidden],
.ps-tabbar [hidden],
.ps-sheet [hidden] { display: none !important; }

@media (min-width: 768px) {
  body.ps-has-shell { margin-left: var(--ps-rail-w); }
  .ps-top .ps-brand { display: none; }
  .ps-sheet,
  .ps-scrim { display: none !important; }
}

@media (max-width: 767.98px) {
  .ps-rail { display: none; }
  .ps-tabbar { display: flex; }
  body.ps-has-shell {
    padding-bottom: calc(var(--ps-tabbar-h) + 16px + env(safe-area-inset-bottom, 0px));
  }

  /* THREE ROWS, THE SAME HEIGHT IN EVERY STATE, so nothing under the bar ever moves — /live's STOP above all (the
     owner's answer of 2026-10-12): the bar never grows when "New real entries off — managing to flat" or "New
     buys paused" appears, and never shrinks when either goes, when the first read lands, or on a 401 (on every
     page but the sign-in page, below).
       1. PS, the clock and the status (36px: the brand).
       2. The mode pill and, beside it, "New buys paused" (28px); under the pill, its line — "New real entries
          off — managing to flat", "Next open: …" or "Deciding at the open", never two at once (src/ui-read.js) —
          in a slot of its own (16px) that is there whether a line shows or not: the mode box is 46px tall, and
          its line is set in that slot out of the flow, so the line never widens the box and never pushes the
          pill off the row.
       3. Own picks (28px), on a row of its own whatever its wording.
     Between the rows, 6px: the break after row 1 and the one after row 2 (::after) are those 6px, so the bar
     has no row gap of its own. min-height holds all of it, padding and edge included —
     8 + 36 + 6 + 46 + 6 + 28 + 8 + 1 = 139px — so a row that empties (a 401 takes rows 2 and 3, and gives row 1
     its 44px Sign in link) leaves the bar as tall as it was; align-content keeps the rows at the top.
     Every row fits at 320px: row 2 is at most 108 + 8 + 149px in Plex (Real orders, New buys paused), the
     line 219px, own picks' longest wording 266px. */
  .ps-top {
    justify-content: flex-start;
    align-content: flex-start;
    min-height: 139px;
    gap: 0 8px;
  }
  /* A page with its title in the bar (Home, Commanders, Colosseum, Settings): the title's row as well — 6px and
     22px × 1.2. */
  .ps-top:has(> .ps-h1) { min-height: 171.4px; }
  /* The sign-in page has no STOP, and who comes to it is most often signed out: there the bar keeps no room for
     rows 2 and 3 — no reservation, and the pending pills out of the layout until a good read shows them — so a
     signed-out visitor never sees an empty band under "Signed out — Sign in". Its first row is 44px from the first
     paint, the Sign in link's height, so "Checking…" turning to "Signed out — Sign in" never moves the sign-in card:
     8 + 44 + 6 + 6 + 8 + 1 = 73px either way. A signed-in visitor sees rows 2 and 3 appear (147px) as the page's own
     panel changes from "Loading…". */
  body[data-page="login"] > .ps-top { min-height: 0; }
  body[data-page="login"] > .ps-top [data-pending="true"] { display: none; }
  body[data-page="login"] > .ps-top .ps-status { min-height: 44px; }
  .ps-top .ps-clock { order: 2; margin-left: auto; }
  .ps-top .ps-status { order: 3; }
  /* The status stays on the first row, one line, whatever it says: it ends with an ellipsis at the room left of
     the brand and the clock (the whole text in its title; a screen reader reads it all) — a long "Engine down"
     reason never wraps the bar taller under the page. */
  .ps-top .ps-clock { min-width: 104px; justify-content: center; }
  .ps-top .ps-status { max-width: calc(100% - 156px); min-width: 0; overflow: hidden; }
  .ps-top .ps-status[data-state="down"] { white-space: nowrap; }
  .ps-top #ps-status-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ps-top .ps-status a { flex: 0 0 auto; }
  .ps-break { display: block; order: 4; flex: 0 0 100%; height: 6px; }
  .ps-modebox { order: 5; position: relative; height: 46px; margin-left: 0; }
  .ps-top .ps-next,
  .ps-top .ps-entries-off { position: absolute; top: 30px; left: 0; }
  .ps-top .ps-paused { order: 6; align-self: flex-start; }
  .ps-top::after { content: ""; order: 7; flex: 0 0 100%; height: 6px; }
  .ps-top .ps-picks { order: 8; }
  .ps-top .ps-h1 { order: 9; flex: 0 0 100%; margin-top: 6px; font-size: 22px; }

  .ps-wide-only { display: none; }
  .ps-narrow-only { display: inline; }

  .ps-main { padding-top: 16px; }
}

/* ── shared components (the new pages) ───────────────────────────────────── */

.ps-card {
  padding: 18px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-card);
  background: var(--ps-card);
  color: var(--ps-text);
}
.ps-card--hero {
  padding: 24px;
  border-radius: var(--ps-r-hero);
}

.ps-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}

/* A static chip: 28px, raised, secondary text. */
.ps-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 28px;
  padding: 2px 10px;
  border-radius: var(--ps-r-pill);
  background: var(--ps-raised);
  color: var(--ps-text-2);
  font-size: 12px;
  line-height: 1.2;
  white-space: nowrap;
}
.ps-chip--muted { color: var(--ps-muted); }
.ps-chip--athena { background: var(--ps-accent-tint); color: var(--ps-accent-2); }
.ps-chip--up { background: var(--ps-up-tint); color: var(--ps-up); }
.ps-chip--down { background: var(--ps-down-tint); color: var(--ps-down); }
.ps-chip--warn { background: var(--ps-warn-tint); color: var(--ps-warn); }

/* An interactive pill (filters, ranges, tabs): 36px on a desktop, 44px on a
   phone; unselected it has a --ps-line border (its raised fill alone is
   1.11:1 against a card); selected it is lavender with the page's ink. */
.ps-pill-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 36px;
  min-width: 44px;
  margin: 0;
  padding: 0 16px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-pill);
  background: var(--ps-raised);
  color: var(--ps-text-2);
  font: 500 13px/1.2 var(--ps-font);
  cursor: pointer;
}
.ps-pill-btn:hover { color: var(--ps-text); }
.ps-pill-btn[aria-pressed="true"],
.ps-pill-btn[aria-selected="true"] {
  border-color: var(--ps-accent);
  background: var(--ps-accent);
  color: var(--ps-on-accent);
  font-weight: 600;
}
.ps-pill-btn[aria-disabled="true"] {
  color: var(--ps-muted);
  cursor: not-allowed;
}

/* Rows and inputs: 8px corners; an input is 44px with a --ps-line border. */
.ps-row {
  border-radius: var(--ps-r-row);
}
.ps-row--win { background: var(--ps-win-row); }
.ps-row--loss { background: var(--ps-loss-row); }

.ps-input {
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-row);
  background: var(--ps-bg);
  color: var(--ps-text);
  font: 15px/1.3 var(--ps-font);
}

/* A stat card: a label, a value, one sub-line. */
.ps-stat__label {
  margin: 0;
  color: var(--ps-muted);
  font-size: 13px;
}
.ps-stat__value {
  margin: 4px 0 2px;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.ps-stat__sub {
  margin: 0;
  color: var(--ps-text-2);
  font-size: 13px;
}

/* A signed number: a sign and a triangle, never colour alone. */
.ps-sg {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ps-sg svg {
  flex: 0 0 auto;
  width: 0.62em;
  height: 0.62em;
  fill: currentColor;
  align-self: center;
}
.ps-sg--up { color: var(--ps-up); }
.ps-sg--down { color: var(--ps-down); }
.ps-sg--zero { color: var(--ps-text); }

/* Emblems: a 48px tile in the commander's tint; strokes 1.5. */
.ps-emblem {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--ps-r-card);
  background: var(--ps-accent-tint);
  color: var(--ps-athena);
}
.ps-emblem svg {
  width: 28px;
  height: 28px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ps-emblem--tyr { background: rgba(125, 179, 255, 0.13); color: var(--ps-tyr); }
.ps-emblem--mercury { background: rgba(213, 219, 232, 0.11); color: var(--ps-mercury); }
.ps-emblem--colosseum { background: rgba(213, 219, 232, 0.11); color: var(--ps-text-2); }

/* "Not built yet": the same frame, the emblem dimmed on a half-strength tint,
   the name and mode, a muted pill, and one line on what it will do. No
   numbers, no chart, no link. */
.ps-notbuilt {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.ps-notbuilt__head {
  display: flex;
  align-items: center;
  gap: 14px;
}
.ps-notbuilt .ps-emblem svg { opacity: 0.55; }
.ps-notbuilt .ps-emblem { background: rgba(168, 155, 255, 0.07); }
.ps-notbuilt .ps-emblem--tyr { background: rgba(125, 179, 255, 0.065); }
.ps-notbuilt .ps-emblem--mercury,
.ps-notbuilt .ps-emblem--colosseum { background: rgba(213, 219, 232, 0.055); }
.ps-notbuilt__name {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.2;
}
.ps-notbuilt__mode {
  margin: 2px 0 0;
  color: var(--ps-muted);
  font-size: 13px;
}
.ps-notbuilt__line {
  margin: 0;
  color: var(--ps-text-2);
  font-size: 14px;
}
.ps-chip--notbuilt {
  align-self: flex-start;
  background: var(--ps-raised);
  color: var(--ps-muted);
}

.ps-link-card {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-pill);
  color: var(--ps-accent);
  font-weight: 600;
  text-decoration: none;
}
.ps-link-card:hover { color: var(--ps-accent-2); }

/* The god medallions (public/ps-medallion.js; docs/mockup/Medallions.dc.html):
   a gold rim, a ring in the god's colour, an original emblem. Their colours
   are the component's own (each god's ring and emblem in its --ps-* token; a
   test holds them equal). Here: the slot a page reserves, the benched grey
   (Tyr and Mercury, not built yet), and the awaiting ring's pulse — the only
   motion besides the flash, and none for a reader who asks for less. */
.ps-medal { display: block; flex: 0 0 auto; overflow: visible; }
.ps-medal--benched { filter: grayscale(1) brightness(0.8); }
@keyframes ps-medal-pulse {
  0% { opacity: 0.95; transform: scale(0.97); }
  70% { opacity: 0; transform: scale(1.08); }
  100% { opacity: 0; transform: scale(1.08); }
}
.ps-medal__pulse { transform-box: fill-box; transform-origin: center; animation: ps-medal-pulse 2.2s ease-out infinite; }
.ps-medal-slot { display: inline-flex; flex: 0 0 auto; width: 56px; height: 56px; }

/* A live value whose text changed since the last poll: one short flash,
   teal if it rose, coral if it fell. Never on first render, and none at all
   for a reader who asks for less motion. */
@keyframes ps-flash-up {
  from { background-color: rgba(46, 211, 183, 0.28); }
  to { background-color: rgba(46, 211, 183, 0); }
}
@keyframes ps-flash-down {
  from { background-color: rgba(255, 107, 107, 0.28); }
  to { background-color: rgba(255, 107, 107, 0); }
}
.ps-flash--up { animation: ps-flash-up 600ms ease-out; }
.ps-flash--down { animation: ps-flash-down 600ms ease-out; }

@media (prefers-reduced-motion: reduce) {
  .ps-flash--up,
  .ps-flash--down { animation: none; }
  .ps-medal__pulse { animation: none; opacity: 0.85; }
}

@media (max-width: 767.98px) {
  .ps-pill-btn { min-height: 44px; }
  .ps-stat__value { font-size: 21px; }
  .ps-card--hero { padding: 18px; }
}

/* ── Home (public/home.html) ──────────────────────────────────────────────────
   The P&L card and its chart, the account cards and the daily loss pause, the
   commanders, the open positions beside the last actions, and every screen.
   Colours keep their one meaning each (the block at the top): teal / coral
   only for a gain / loss, amber only for attention (a kill-switch event, a
   position near its floor, a stale quote), lime only for the chart's callout,
   lavender in data only for Athena. A buy marker is a ring in the TEXT colour.
   Every marker that sits on a line of its own colour carries a card halo. */

.ps-h-note {
  margin: 0;
  padding: 12px 16px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-row);
  background: var(--ps-raised);
  color: var(--ps-text);
  font-size: 14px;
}
.ps-h-msg { margin: 0; color: var(--ps-text-2); font-size: 14px; }
.ps-h-msg--error { color: var(--ps-text); }
.ps-na { color: var(--ps-muted); }
/* `hidden` wins over a display rule on Home too (the Show-all button is a .ps-pill-btn, inline-flex). */
.ps-home [hidden] { display: none !important; }

.ps-sec-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
  margin-bottom: 12px;
}
.ps-sec-head .ps-h2 { margin: 0; }
.ps-sec-sub { margin: 0; color: var(--ps-text-2); font-size: 14px; }
.ps-h3 { margin: 20px 0 10px; color: var(--ps-text-2); font-size: 16px; font-weight: 600; }

/* 1. The P&L card */
.ps-pnl { display: flex; flex-direction: column; gap: 14px; }
.ps-pnl__top { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 16px; }
.ps-pnl__lead { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ps-pnl__titles { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
.ps-pnl__title { margin: 0; font-size: 26px; font-weight: 600; line-height: 1.2; letter-spacing: -0.01em; }
.ps-pnl__date { margin: 0; color: var(--ps-muted); font-size: 14px; }
.ps-pnl__who { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0; color: var(--ps-text-2); font-size: 14px; }
.ps-hero { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; }
.ps-hero__usd { font-size: 60px; font-weight: 600; line-height: 1; letter-spacing: -0.02em; }
.ps-hero__usd .ps-sg svg { width: 0.4em; height: 0.4em; }
.ps-hero__pct { font-size: 20px; font-weight: 600; }
.ps-pnl__reason,
.ps-pnl__note { margin: 0; color: var(--ps-text-2); font-size: 13px; }
.ps-pnl__stats { display: flex; flex-wrap: wrap; gap: 8px 32px; margin: 0; }
.ps-pnl__stat { display: flex; flex-direction: column; gap: 2px; }
.ps-pnl__stat dt { color: var(--ps-muted); font-size: 13px; }
.ps-pnl__stat dd { margin: 0; font-size: 18px; font-weight: 600; }
.ps-pnl__stat-sub { color: var(--ps-muted); font-size: 12px; font-weight: 400; }
.ps-pnl__basis { margin: 0; color: var(--ps-muted); font-size: 13px; }
.ps-pills { display: flex; flex-wrap: wrap; gap: 6px; }

/* An approximate figure (owner answer 5): "≈", the figure, a muted "Approx." chip. */
.ps-approx { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 4px 6px; }
.ps-approx__mark { color: var(--ps-text-2); }
.ps-chip--approx { align-self: center; color: var(--ps-text-2); font-weight: 400; }

/* The chart (public/ps-chart.js), drawn at its real pixel width. */
.ps-chart { position: relative; min-height: 200px; }
.ps-chart__svg { display: block; overflow: visible; font-family: var(--ps-font); }
.ps-chart__msg { margin: 0; padding: 8px 0; color: var(--ps-text-2); font-size: 14px; }
.ps-chart__msg--over {
  position: absolute;
  top: 16%;
  right: 0;
  left: 0;
  text-align: center;
  pointer-events: none;
}
.ps-chart__readout { min-height: 22px; margin: 0; color: var(--ps-text); font-size: 14px; }
.ps-ch-base { fill: none; stroke: var(--ps-line); stroke-width: 1.5; stroke-dasharray: 4 4; }
.ps-ch-tick,
.ps-ch-axis { stroke: var(--ps-line); stroke-width: 1; }
.ps-ch-yl,
.ps-ch-xl { fill: var(--ps-muted); font-size: 12px; }
.ps-ch-yl.ps-sg { display: inline; }
.ps-ch-fill { stroke: none; }
.ps-ch-fill--down { fill: var(--ps-down); fill-opacity: 0.25; }
.ps-ch-stop--a { stop-color: var(--ps-up); stop-opacity: 0.34; }
.ps-ch-stop--b { stop-color: var(--ps-up); stop-opacity: 0.03; }
.ps-ch-line { fill: none; stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.ps-ch-line--up { stroke: var(--ps-up); }
.ps-ch-line--down { stroke: var(--ps-down); }
/* A run at exactly $0 is neither a gain nor a loss: the text colour, over the line (ps-chart.js zeroRuns). */
.ps-ch-line--zero { stroke: var(--ps-text); }
.ps-ch-now { stroke: var(--ps-muted); stroke-width: 1; stroke-dasharray: 2 4; }
.ps-ch-nowl { fill: var(--ps-muted); font-size: 12px; }
.ps-ch-conn { stroke: var(--ps-text-2); stroke-width: 1.5; stroke-dasharray: 3 3; }
.ps-ch-end { stroke: var(--ps-card); stroke-width: 4; paint-order: stroke; }
.ps-ch-end--up { fill: var(--ps-up); }
.ps-ch-end--down { fill: var(--ps-down); }
.ps-ch-end--zero { fill: var(--ps-text); }
.ps-mk { cursor: pointer; }
.ps-mk--buy { fill: var(--ps-card); stroke: var(--ps-text); stroke-width: 2; }
.ps-mk--sale,
.ps-mk--stop { stroke: var(--ps-card); stroke-width: 4; paint-order: stroke; }
.ps-mk--gain { fill: var(--ps-up); }
.ps-mk--loss { fill: var(--ps-down); }
.ps-mk--flat { fill: var(--ps-text); }
.ps-mk-kline { stroke: var(--ps-warn); stroke-width: 1.5; stroke-dasharray: 2 3; }
.ps-mk-ksq { stroke: var(--ps-warn); stroke-width: 1.5; }
.ps-mk-ksq--on { fill: var(--ps-warn); }
.ps-mk-ksq--off { fill: var(--ps-card); }
.ps-ch-selring { fill: none; stroke: var(--ps-lime); stroke-width: 1.5; }
.ps-ch-leader { stroke: var(--ps-lime); stroke-width: 1.5; }
.ps-callout {
  position: absolute;
  z-index: 2;
  max-width: calc(100% - 8px);
  padding: 5px 12px;
  border-radius: var(--ps-r-card);
  background: var(--ps-lime);
  color: var(--ps-on-accent);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  pointer-events: none;
}
/* As wide as its words, at most the room on its side of the chart (ps-chart.js sets max-width); longer words wrap inside it. */
.ps-callout--mid,
.ps-callout--start,
.ps-callout--end { width: max-content; }
.ps-callout--mid { transform: translateX(-50%); }
.ps-callout--full { text-align: center; }
.ps-callout .ps-sg { color: inherit; }
.ps-mini { display: block; flex: 0 0 auto; overflow: visible; }
.ps-mini-base { stroke: var(--ps-line); stroke-width: 1; stroke-dasharray: 3 3; }
.ps-mini-line { stroke-width: 2; }
.ps-mini-end { stroke-width: 2; }
.ps-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin: 0;
  padding: 0;
  color: var(--ps-text-2);
  font-size: 13px;
  list-style: none;
}
.ps-legend__item { display: inline-flex; align-items: center; gap: 8px; }
.ps-lg-ico { flex: 0 0 auto; overflow: visible; }

/* 2. The account cards: 4 across, 3 on a narrow desktop, 2 on a phone; the daily loss pause spans two. */
.ps-acct { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.ps-acct > .ps-h-msg { grid-column: 1 / -1; }
.ps-stat { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 16px 18px; }
.ps-stat .ps-stat__label { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.ps-stat .ps-stat__value { margin: 2px 0 0; }
.ps-stat__note { margin: 0; color: var(--ps-muted); font-size: 12px; line-height: 1.4; }
.ps-pause { grid-column: span 2; gap: 10px; }
.ps-pause__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ps-pause__line { margin: 0; font-size: 15px; }
.ps-meter__wrap { display: flex; flex-direction: column; gap: 4px; padding: 4px 0; }
.ps-meter {
  position: relative;
  height: 12px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-pill);
  background: var(--ps-card);
}
.ps-meter__cap { position: absolute; top: -5px; bottom: -5px; left: -2px; width: 3px; border-radius: 2px; background: var(--ps-down); }
.ps-meter__zero { position: absolute; top: -5px; bottom: -5px; left: 50%; width: 2px; margin-left: -1px; background: var(--ps-text); }
.ps-meter__fill { position: absolute; top: 2px; bottom: 2px; }
.ps-meter__fill--up { border-radius: 0 999px 999px 0; background: var(--ps-up); }
.ps-meter__fill--down { border-radius: 999px 0 0 999px; background: var(--ps-down); }
.ps-meter__labels { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 12px; color: var(--ps-muted); font-size: 12px; }

/* 2b. The financial plan (Phase 4): one card — the phase, the returns, the way to $1,000, the next payday.
   4 across, 2 on a narrow desktop and on a phone; nothing reordered. */
.ps-plan { display: flex; flex-direction: column; gap: 12px; }
.ps-plan .ps-h2 { margin: 0; }
.ps-plan__body { display: flex; flex-direction: column; gap: 12px; }
.ps-plan__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.ps-plan__why { margin: 0; color: var(--ps-text-2); font-size: 13px; }
.ps-plan__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.ps-plan__cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ps-plan__cell .ps-stat__value { margin: 2px 0 0; font-size: 22px; }
.ps-plan__bar {
  position: relative;
  height: 8px;
  overflow: hidden;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-pill);
  background: var(--ps-card);
}
.ps-plan__fill { position: absolute; top: 0; bottom: 0; left: 0; background: var(--ps-text-2); }
.ps-plan__foot { margin: 0; color: var(--ps-muted); font-size: 12px; }

/* 3. The commanders */
.ps-cmd-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
.ps-cmd { display: flex; flex-direction: column; gap: 14px; }
.ps-cmd__head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.ps-cmd__who { flex: 1 1 auto; min-width: 0; }
.ps-cmd__name { margin: 0; font-size: 19px; font-weight: 600; line-height: 1.2; }
.ps-cmd__mode { margin: 2px 0 0; color: var(--ps-muted); font-size: 13px; }
.ps-cmd__figs { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px; }
.ps-cmd__nums { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ps-cmd__total { margin: 0; font-size: 30px; font-weight: 600; line-height: 1.1; }
.ps-cmd__split,
.ps-cmd__trades { margin: 0; color: var(--ps-text-2); font-size: 13px; }
.ps-cmd__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ps-cmd__chips .ps-chip { white-space: normal; }
.ps-cmd .ps-link-card { align-self: flex-start; }
.ps-cmd__medal { display: inline-flex; flex: 0 0 auto; }

/* 5. The open positions beside the last actions (below them on a phone) */
.ps-h-pair { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px; }
.ps-h-positions { flex: 2 1 460px; min-width: 0; }
.ps-acts { flex: 1 1 320px; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.ps-acts .ps-h2 { margin-bottom: 4px; }
.ps-pos-list { display: flex; flex-direction: column; gap: 12px; }
.ps-pos { display: flex; flex-direction: column; gap: 12px; }
.ps-pos__head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; }
.ps-pos__id { min-width: 0; }
.ps-pos__name { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.ps-pos__ticker { margin-right: 2px; font-size: 20px; font-weight: 700; }
.ps-pos__sub { margin: 4px 0 0; color: var(--ps-muted); font-size: 13px; }
.ps-pos__px { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; margin-left: auto; text-align: right; }
.ps-pos__price { margin: 0; font-size: 20px; font-weight: 600; }
.ps-pos__price--none { color: var(--ps-muted); font-size: 15px; font-weight: 500; }
.ps-pos__age { margin: 0; color: var(--ps-muted); font-size: 12px; }
.ps-pos__age--stale { color: var(--ps-warn); }
.ps-pos__chg { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 12px; margin: 0; font-size: 14px; font-weight: 600; }
.ps-pos__stop { margin: 0; color: var(--ps-text-2); font-size: 13px; }
/* A REAL lot with no stop resting at Robinhood: attention. */
.ps-pos__stop--none { color: var(--ps-warn); font-weight: 600; }
.ps-bar__wrap { display: flex; flex-direction: column; gap: 6px; padding-top: 4px; }
.ps-bar {
  position: relative;
  height: 12px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-pill);
  background: var(--ps-card);
}
/* The amber zone, floor to the near-the-floor line: 3.30:1 against the card, inside an outlined track. */
.ps-bar__zone { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 999px 0 0 999px; background: var(--ps-warn-zone); }
.ps-bar__tick { position: absolute; top: -5px; bottom: -5px; width: 2px; margin-left: -1px; }
.ps-bar__tick--stop { background: var(--ps-text); }
.ps-bar__tick--be { background: var(--ps-muted); }
/* The price dot always carries a 2px card halo: amber on the amber zone alone is 2.87:1. */
.ps-bar__pt {
  position: absolute;
  top: 50%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--ps-card);
}
.ps-bar__pt--up { background: var(--ps-up); }
.ps-bar__pt--down { background: var(--ps-down); }
.ps-bar__pt--flat { background: var(--ps-text); }
.ps-bar__pt--risk { background: var(--ps-warn); }
.ps-bar__labels { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 12px; color: var(--ps-muted); font-size: 12px; }

.ps-acts__list { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
.ps-act { display: flex; gap: 12px; padding: 9px 0; }
.ps-act-ico { flex: 0 0 12px; margin-top: 4px; overflow: visible; }
.ps-act-mark--athena { fill: var(--ps-athena); }
.ps-act-mark--switch { fill: none; stroke: var(--ps-text); stroke-width: 1.5; }
/* Athena's rows: her medallion at the feed size (32px) in place of an identity dot. */
.ps-act-medal { flex: 0 0 32px; margin-top: -2px; }
.ps-act__body { flex: 1 1 auto; min-width: 0; }
.ps-act__title { margin: 0; font-size: 14px; font-weight: 600; }
.ps-act__detail { margin: 2px 0 0; color: var(--ps-text-2); font-size: 13px; }
.ps-act__time { flex: 0 0 auto; padding-top: 2px; color: var(--ps-muted); font-size: 12px; white-space: nowrap; }
.ps-acts__more { align-self: flex-start; margin-top: 8px; }

/* 6. Every screen: the whole card is the link. */
.ps-screen-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.ps-screen {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 84px;
  padding: 16px 18px;
  color: var(--ps-text);
  text-decoration: none;
}
.ps-screen:hover { background: var(--ps-raised); color: var(--ps-text); }
.ps-screen__name { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 16px; font-weight: 600; }
.ps-screen__sub { color: var(--ps-muted); font-size: 13px; }

@media (min-width: 768px) and (max-width: 1099.98px) {
  .ps-acct { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ps-plan__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 767.98px) {
  .ps-hero__usd { font-size: 40px; }
  .ps-hero__pct { font-size: 17px; }
  .ps-pnl__title { font-size: 24px; }
  .ps-pnl__stats { gap: 8px 20px; }
  .ps-acct { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .ps-pause { grid-column: 1 / -1; }
  .ps-stat { padding: 12px 14px; }
  .ps-plan__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .ps-cmd-grid { grid-template-columns: minmax(0, 1fr); }
  .ps-screen-grid { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .ps-screen { min-height: 56px; padding: 10px 14px; }
}

/* ── Athena's page (public/commanders.html) ──────────────────────────────────
   Her header and medallion, the stats strip, today's chart (ps-chart.js),
   day by day as capsule bars, today's trades beside her own picks, how she
   trades, and the commanders not built yet — in the mockup's order at every
   width; a phone stacks the same sections. Teal / coral only for a gain / a
   loss (a bar, a row's tint), lime only for the callout and the ring round
   the bar it names, lavender in data only for Athena (her medallion). */

.ps-cmdr [hidden] { display: none !important; }
.ps-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; color: var(--ps-muted); font-size: 14px; }
.ps-crumbs a { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; }
.ps-cmdr__head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }
.ps-cmdr__medal { display: inline-flex; flex: 0 0 96px; width: 96px; height: 96px; }
.ps-cmdr__who { flex: 1 1 260px; min-width: 0; }
.ps-cmdr__name { margin: 0; font-size: 32px; font-weight: 600; line-height: 1.15; letter-spacing: -0.01em; }
.ps-cmdr__line { margin: 4px 0 0; color: var(--ps-text-2); font-size: 15px; }
.ps-cmdr__chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ps-cmdr__chips .ps-chip { min-height: 32px; padding: 4px 12px; font-size: 13px; white-space: normal; }
.ps-cmdr__glyph { flex: 0 0 auto; overflow: visible; }
.ps-cmdr__glyph--real { fill: var(--ps-text); }
.ps-cmdr__glyph--paper { fill: none; stroke: var(--ps-text); stroke-width: 1.5; }

/* The strip: five cells across, divided by --ps-line; the outer edges clipped by the card. */
.ps-cmdr__strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); padding: 0; overflow: hidden; }
.ps-cmdr__strip > .ps-h-msg { padding: 18px; }
.ps-cmdr__cell { min-width: 0; margin: -1px 0 0 -1px; padding: 16px 20px; border-top: 1px solid var(--ps-line); border-left: 1px solid var(--ps-line); }
.ps-cmdr__cell-label { margin: 0; color: var(--ps-muted); font-size: 13px; }
.ps-cmdr__cell-value { margin: 4px 0 2px; font-size: 26px; font-weight: 600; line-height: 1.15; }
.ps-cmdr__cell-sub { margin: 0; color: var(--ps-text-2); font-size: 13px; }
.ps-cmdr__cell-note { margin: 2px 0 0; color: var(--ps-muted); font-size: 12px; }

.ps-cmdr__sechead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; margin-bottom: 12px; }
.ps-cmdr__sechead .ps-h2 { margin: 0; }
.ps-cmdr__date { margin: 0; color: var(--ps-muted); font-size: 14px; }
.ps-cmdr__sub { margin: -6px 0 12px; color: var(--ps-text-2); font-size: 14px; }
.ps-cmdr__note { margin: 10px 0 0; color: var(--ps-muted); font-size: 13px; }

/* Day by day: one capsule per session, teal for a gain and coral for a loss, from the dashed $0 line. */
.ps-days { position: relative; }
.ps-days__svg { display: block; overflow: visible; font-family: var(--ps-font); }
.ps-day { cursor: pointer; }
.ps-day--up { fill: var(--ps-up); }
.ps-day--down { fill: var(--ps-down); }
.ps-day--zero { fill: var(--ps-text); }
.ps-day--none { fill: var(--ps-card); stroke: var(--ps-muted); stroke-width: 1.5; }
/* A paper day is never drawn as real money: an outline in the text colour, dashed, on the card (the key says so). */
.ps-day--paper { fill: var(--ps-card); stroke: var(--ps-text); stroke-width: 1.5; stroke-dasharray: 3 2; }
.ps-day[data-selected="true"] { stroke: var(--ps-lime); stroke-width: 2; paint-order: stroke; }
/* Each day's tap target: its whole column. */
.ps-day-hit { fill: transparent; cursor: pointer; }

.ps-cmdr__pair { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px; }
.ps-cmdr__trades { flex: 3 1 560px; min-width: 0; }
.ps-cmdr__picks { flex: 2 1 340px; min-width: 0; }

/* Today's trades: rows tinted by result; on a phone each row is a stacked card. */
.ps-tt__wrap { overflow-x: auto; }
.ps-tt { width: 100%; border-collapse: separate; border-spacing: 0 6px; font-family: var(--ps-font-cond); font-size: 15px; }
.ps-tt th { padding: 0 12px; color: var(--ps-muted); font-size: 13px; font-weight: 500; text-align: left; white-space: nowrap; }
.ps-tt td { padding: 12px; vertical-align: middle; }
.ps-tt .ps-tt__num { text-align: right; white-space: nowrap; }
.ps-tt .ps-tt__row { background: none; }
.ps-tt .ps-tt__row > td:first-child { border-radius: 8px 0 0 8px; }
.ps-tt .ps-tt__row > td:last-child { border-radius: 0 8px 8px 0; }
.ps-tt .ps-tt__row.ps-row--win > td { background: var(--ps-win-row); }
.ps-tt .ps-tt__row.ps-row--loss > td { background: var(--ps-loss-row); }
.ps-tt .ps-tt__row.ps-row--open > td,
.ps-tt .ps-tt__row.ps-row--flat > td { background: var(--ps-raised); }
.ps-tt__stock { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.ps-tt__ticker { font-weight: 700; }
.ps-tt__held { color: var(--ps-text-2); }
.ps-tt__pnl { font-weight: 600; }
.ps-tt__sub { color: var(--ps-muted); font-size: 12px; font-weight: 400; }

.ps-row--open,
.ps-row--flat { background: var(--ps-raised); }

/* Claude's reasons: its own words, quoted as it gave them. */
.ps-reasons { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; }
.ps-reason { padding: 10px 12px; border-radius: var(--ps-r-row); background: var(--ps-raised); }
.ps-reason__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; color: var(--ps-text-2); font-size: 13px; }
.ps-reason__time { color: var(--ps-muted); }
.ps-reason__ticker { color: var(--ps-text); font-weight: 700; }
.ps-reason__path { color: var(--ps-muted); }
.ps-quote { margin: 8px 0 0; padding: 0 0 0 10px; border-left: 1px solid var(--ps-line); color: var(--ps-text); font-size: 14px; }
.ps-quote p { margin: 0; }

/* Every session: one row per day, newest first. */
.ps-sessions { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; list-style: none; }
.ps-sess { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1.6fr); align-items: center; gap: 6px 12px; padding: 10px 12px; }
.ps-sess__date { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-weight: 600; }
.ps-sess__src { color: var(--ps-muted); font-size: 12px; font-weight: 400; }
.ps-sess__pnl { font-weight: 600; text-align: right; }
.ps-sess__trades { color: var(--ps-text-2); font-size: 13px; }

/* Own picks, switched off. */
.ps-cmdr__tiles { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0; }
.ps-cmdr__tile { flex: 1 1 140px; min-width: 0; padding: 12px 14px; border-radius: var(--ps-r-row); background: var(--ps-raised); }
.ps-cmdr__tile-value { margin: 2px 0; font-size: 22px; font-weight: 600; }
.ps-picks { display: flex; flex-direction: column; gap: 6px; margin: 0; padding: 0; font-family: var(--ps-font-cond); list-style: none; }
.ps-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 10px 12px; }
.ps-pick__time { flex: 0 0 auto; min-width: 72px; color: var(--ps-muted); font-size: 13px; }
.ps-pick__name { flex: 1 1 auto; font-weight: 600; }
.ps-pick__at { color: var(--ps-text-2); font-weight: 400; }
.ps-pick__later { color: var(--ps-text-2); font-size: 13px; }
.ps-pick__move { min-width: 76px; font-weight: 600; text-align: right; }

/* How Athena trades. */
.ps-cmdr__howgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.ps-cmdr__howcard { padding: 14px 16px; border-radius: var(--ps-r-row); background: var(--ps-raised); }
.ps-cmdr__howtitle { margin: 0; font-size: 15px; font-weight: 600; }
.ps-cmdr__howcard p { margin: 4px 0 0; color: var(--ps-text-2); font-size: 14px; }

@media (max-width: 767.98px) {
  .ps-cmdr__name { font-size: 26px; }
  .ps-cmdr__strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ps-cmdr__strip > .ps-cmdr__cell:first-child { grid-column: 1 / -1; }
  .ps-cmdr__cell { padding: 12px 14px; }
  .ps-cmdr__cell-value { font-size: 21px; }
  .ps-tt,
  .ps-tt tbody,
  .ps-tt .ps-tt__row,
  .ps-tt td { display: block; }
  .ps-tt thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  /* Each row a card: its cells keep their tint, the row clips them to its 8px corners. */
  .ps-tt .ps-tt__row { margin-bottom: 8px; overflow: hidden; border-radius: var(--ps-r-row); }
  .ps-tt .ps-tt__row > td,
  .ps-tt .ps-tt__row > td:first-child,
  .ps-tt .ps-tt__row > td:last-child { display: flex; justify-content: space-between; gap: 12px; padding: 6px 12px; border-radius: 0; text-align: right; }
  .ps-tt td::before { content: attr(data-label); color: var(--ps-muted); font-size: 13px; text-align: left; }
  .ps-sess { grid-template-columns: minmax(0, 1fr) auto; }
  .ps-sess__trades { grid-column: 1 / -1; }
}

/* ── Sessions and Session detail (public/dashboard.html, session.html) ────────
   GUI step 4: the two pages are new pages (body.ps-page.ps-sessions) and load
   ps.css alone. public/dashboard.js builds their parts with the class names it
   always used (panel, stats, data, badge, card …); they are styled here, only
   under .ps-sessions. Colours keep their one meaning each: teal / coral only
   for a gain / loss (a signed figure, a P&L pill, a trade row's tint), amber
   for attention (a kill-switch or critical alarm, a superseded or over-cap
   mark, a flagged figure), lavender only for links and the selected view or
   tab. Every boundary is --ps-line. */

.ps-sessions [hidden] { display: none !important; }
.ps-sessions .sess-main { display: flex; flex-direction: column; gap: 16px; }
.ps-sessions .sess-main > * + * { margin-top: 0; }
/* The session's sections, 16px apart; a section with nothing to say takes no room. */
.ps-sessions #detail { display: flex; flex-direction: column; gap: 16px; }
.ps-sessions #detail > :empty { display: none; }
.ps-sessions .sess-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.ps-sessions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-pill);
  background: var(--ps-raised);
  color: var(--ps-text);
  font: 500 14px/1.2 var(--ps-font);
  text-decoration: none;
  cursor: pointer;
}
.ps-sessions .btn:hover { background: var(--ps-card); }
.ps-sessions .btn:disabled { color: var(--ps-muted); cursor: progress; }
.ps-sessions .btn-quiet { background: transparent; }
.ps-sessions .muted { margin: 0; color: var(--ps-text-2); font-size: 14px; }
.ps-sessions .note { margin: 8px 0 0; color: var(--ps-muted); font-size: 13px; line-height: 1.45; }
.ps-sessions .warn-text { color: var(--ps-warn); }
.ps-sessions code { font-size: 13px; }
.ps-sessions .alert {
  padding: 12px 16px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-row);
  background: var(--ps-raised);
  color: var(--ps-text);
  font-size: 14px;
}
.ps-sessions .alert p { margin: 4px 0 0; color: var(--ps-text-2); }
.ps-sessions .alert--warn strong { color: var(--ps-warn); }

/* The cloud-report build control: restyled only; its code and its words are pinned (test/cloud-build-control.test.js). */
.ps-sessions .cloud-build {
  padding: 16px 18px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-card);
  background: var(--ps-card);
}
.ps-sessions .cloud-build h2 { margin: 0; font-size: 17px; font-weight: 600; }
.ps-sessions .cloud-build .build-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 12px; }
.ps-sessions .cloud-build .build-row label { color: var(--ps-text-2); font-size: 14px; }
.ps-sessions .cloud-build input[type="date"] {
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-row);
  background: var(--ps-bg);
  color: var(--ps-text);
  color-scheme: dark;
  font: 15px/1.3 var(--ps-font);
}
.ps-sessions .cloud-build .build-result { margin: 10px 0 0; font-size: 14px; overflow-wrap: anywhere; }
.ps-sessions .cloud-build .build-result.ok { color: var(--ps-text); font-weight: 600; }

/* The list: cards (one per session) or the dense table — a view. */
.ps-sessions .sess-viewbar:empty { display: none; }
.ps-sessions .sess-views[data-view="cards"] .sess-table,
.ps-sessions .sess-views[data-view="table"] .sess-cards { display: none; }
.ps-sessions .cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
.ps-sessions .cards a.card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 44px;
  padding: 16px 18px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-card);
  background: var(--ps-card);
  color: var(--ps-text);
  text-decoration: none;
}
.ps-sessions .cards a.card:hover { background: var(--ps-raised); }
/* An alarm is said by its badge, and the card carries an amber bar besides. */
.ps-sessions .cards a.card.card--alarm { box-shadow: inset 4px 0 0 var(--ps-warn); }
/* A superseded build stays listed and reachable, sunk to the page's colour under its current one. */
.ps-sessions .cards a.card.card--superseded { background: var(--ps-bg); }
.ps-sessions .card-head-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.ps-sessions .card-date { font-size: 17px; font-weight: 600; }
.ps-sessions .sess-pill { min-height: 32px; padding: 4px 12px; font-size: 15px; font-weight: 600; }
.ps-sessions .card-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.ps-sessions .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px 12px; }
.ps-sessions .card-k { display: block; color: var(--ps-muted); font-size: 12px; }
.ps-sessions .card-v { display: block; font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* Marks: chips. Whose money: Real in the text colour, Paper in the secondary text — the words say it. */
.ps-sessions .badge {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 2px 9px;
  border-radius: var(--ps-r-pill);
  background: var(--ps-raised);
  color: var(--ps-text-2);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}
.ps-sessions .badge--real { color: var(--ps-text); font-weight: 700; }
.ps-sessions .badge--paper { color: var(--ps-text-2); }
.ps-sessions .badge--ok { color: var(--ps-text); }
.ps-sessions .badge--cloud { color: var(--ps-text); }
.ps-sessions .badge--warn,
.ps-sessions .badge--bad { background: var(--ps-warn-tint); color: var(--ps-warn); }
.ps-sessions .badge--alarm { background: var(--ps-warn); color: var(--ps-on-accent); font-weight: 700; }
.ps-sessions .badge--exit { color: var(--ps-text); }

/* Panels: cards; their titles sentence case. */
.ps-sessions .panel {
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-card);
  background: var(--ps-card);
  overflow: hidden;
}
.ps-sessions .panel > h2 { margin: 0; padding: 16px 18px 4px; font-size: 17px; font-weight: 600; }
.ps-sessions .panel-body { padding: 8px 18px 16px; }
.ps-sessions .panel-body > :last-child { margin-bottom: 0; }
.ps-sessions .panel > div > .note { padding: 0 18px 14px; }
.ps-sessions .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px 16px; padding: 8px 18px 16px; }
.ps-sessions .stat { min-width: 0; }
.ps-sessions .stat-label { display: block; color: var(--ps-muted); font-size: 13px; }
.ps-sessions .stat-value { display: block; margin-top: 2px; font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
.ps-sessions .stat-sub { display: block; color: var(--ps-text-2); font-size: 12px; }
.ps-sessions .pos { color: var(--ps-up); }
/* A figure flagged for attention (a failure counted, a cap passed): amber. */
.ps-sessions .neg { color: var(--ps-warn); }
.ps-sessions .kv { display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px; margin: 0; font-size: 14px; }
.ps-sessions .kv dt { color: var(--ps-muted); }
.ps-sessions .kv dd { margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.ps-sessions .sample { margin: 4px 0 0; padding-left: 16px; color: var(--ps-text-2); font-size: 13px; }
.ps-sessions .sample li { margin: 2px 0; overflow-wrap: anywhere; }

/* Tables: rows separated by --ps-line; numbers tabular, right-aligned. */
.ps-sessions .table-wrap { overflow-x: auto; }
.ps-sessions table.data { width: 100%; border-collapse: collapse; font-family: var(--ps-font-cond); font-size: 14px; }
.ps-sessions table.data th { padding: 8px 12px; color: var(--ps-muted); font-size: 12px; font-weight: 500; text-align: left; white-space: nowrap; }
.ps-sessions table.data td { padding: 10px 12px; border-top: 1px solid var(--ps-line); text-align: left; vertical-align: middle; }
.ps-sessions table.data td.wrap-cell { min-width: 14rem; white-space: normal; }
.ps-sessions .num,
.ps-sessions .mono { font-variant-numeric: tabular-nums; }
.ps-sessions .num,
.ps-sessions th.num { text-align: right; }
.ps-sessions tr.row--alarm { background: var(--ps-warn-tint); }
.ps-sessions tr.row--superseded { background: var(--ps-bg); }
.ps-sessions .tt-ticker { margin-right: 6px; font-weight: 700; }
.ps-sessions .tt-held { color: var(--ps-text-2); white-space: nowrap; }

/* Session health: a card; an alarm says so in amber, with an amber bar. */
.ps-sessions .health {
  padding: 16px 18px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-card);
  background: var(--ps-card);
}
.ps-sessions .health--bad { box-shadow: inset 4px 0 0 var(--ps-warn); }
.ps-sessions .health--bad h2 { color: var(--ps-warn); }
.ps-sessions .health h2 { margin: 0 0 4px; font-size: 17px; font-weight: 600; }
.ps-sessions .health ul { margin: 6px 0 0; padding-left: 18px; color: var(--ps-text-2); }

/* The header strip. */
.ps-sessions .strip {
  padding: 16px 18px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-hero);
  background: var(--ps-card);
}
.ps-sessions .strip-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin-bottom: 12px; }
.ps-sessions .strip-date { margin-right: 4px; font-size: 22px; font-weight: 600; }
.ps-sessions .strip-cells { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px 16px; }
.ps-sessions .strip-label { display: block; color: var(--ps-muted); font-size: 13px; }
.ps-sessions .strip-value { display: block; margin-top: 2px; font-size: 26px; font-weight: 600; line-height: 1.15; font-variant-numeric: tabular-nums; }
.ps-sessions .strip-sub { display: block; color: var(--ps-text-2); font-size: 13px; }

/* The chart's panel (inside the panel's own padding: the chart takes its full width) and the tabs. */
.ps-sessions .panel .ps-chart { margin: 8px 0 0; }
.ps-sessions .panel .ps-chart__readout { margin: 4px 0 0; }
.ps-sessions .panel .ps-legend { margin: 8px 0 0; }
.ps-sessions .sess-tabs { flex-wrap: wrap; }

@media (max-width: 767.98px) {
  .ps-sessions .sess-viewbar,
  .ps-sessions .sess-table { display: none; }
  .ps-sessions .sess-views[data-view="table"] .sess-cards { display: grid; }
  .ps-sessions .cards { grid-template-columns: minmax(0, 1fr); }
  .ps-sessions .strip-cells { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ps-sessions .strip-cells > :first-child { grid-column: 1 / -1; }
  .ps-sessions .strip-value { font-size: 21px; }
  .ps-sessions .kv { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .ps-sessions .kv dd { margin-bottom: 8px; }
  /* Every table a stack of cards: each row a card, each value under its column's name. */
  .ps-sessions table.data,
  .ps-sessions table.data tbody,
  .ps-sessions table.data tr,
  .ps-sessions table.data td { display: block; }
  .ps-sessions table.data thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .ps-sessions table.data tr { margin: 0 12px 8px; overflow: hidden; border: 1px solid var(--ps-line); border-radius: var(--ps-r-row); }
  .ps-sessions table.data td { display: flex; justify-content: space-between; gap: 12px; padding: 6px 12px; border-top: 0; text-align: right; }
  .ps-sessions table.data td::before { content: attr(data-label); flex: 0 0 auto; color: var(--ps-muted); font-size: 13px; text-align: left; }
  .ps-sessions table.data td.wrap-cell { min-width: 0; }
  .ps-sessions .tt-held { white-space: normal; }
}

/* ── Settings (public/settings.html, settings.js) ─────────────────────────────
   Read only: where the values come from, then sizing, entries (with the
   screener), exits, safety and the switches. Each row is its label and a
   line on what it does, then the value and a SOURCE CHIP — Owner setting,
   Desktop report, Env override, or Code default, which is .ps-chip--warn
   (amber: attention) and so flagged. No money colour but a signed figure's;
   no control but the link to Live. A phone stacks every row. */

.ps-set__lede { margin-bottom: 0; }
.ps-set__group > .ps-h2 { margin-bottom: 4px; }
.ps-set__rows {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(460px, 1fr));
  gap: 0 32px;
}
.ps-set__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 16px;
  align-items: start;
  padding: 12px 0;
  border-top: 1px solid var(--ps-line);
}
.ps-set__name { min-width: 0; }
.ps-set__label { margin: 0; font-weight: 600; }
.ps-set__what { margin: 2px 0 0; color: var(--ps-muted); font-size: 13px; }
.ps-set__val {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  text-align: right;
}
.ps-set__value { font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; }
.ps-set__from,
.ps-set__note {
  grid-column: 1 / -1;
  margin: 4px 0 0;
  color: var(--ps-text-2);
  font-size: 13px;
}
.ps-set__from--flag { color: var(--ps-text); }
.ps-set__note { color: var(--ps-muted); }

/* The source chips: four kinds, each told by its words; the code default also by its amber. */
.ps-src--owner { border: 1px solid var(--ps-line); background: var(--ps-card); color: var(--ps-text); }
.ps-src--env { border: 1px solid var(--ps-line); background: var(--ps-bg); color: var(--ps-text-2); }

.ps-set__inforce { margin: 0 0 8px; }
.ps-set__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin: 12px 0;
  padding: 0;
  list-style: none;
}
.ps-set__legend-item { display: inline-flex; align-items: center; gap: 8px; }
.ps-set__count { font-weight: 600; font-variant-numeric: tabular-nums; }

/* The screener, inside Entries. */
.ps-set__sub {
  margin-top: 16px;
  padding: 16px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-row);
  background: var(--ps-raised);
}
.ps-set__h3 { margin: 0 0 4px; font-size: 17px; font-weight: 600; }
.ps-set__lane { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0 0; color: var(--ps-text-2); font-size: 13px; }

/* Safety: the daily loss pause and the Claude budget, side by side, then the rows. */
.ps-set__pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
  margin: 12px 0 8px;
}
.ps-set__panel {
  padding: 16px;
  border: 1px solid var(--ps-line);
  border-radius: var(--ps-r-row);
  background: var(--ps-raised);
}
.ps-set__panel-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.ps-set__big { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin: 8px 0 4px; }
.ps-set__big .ps-set__value { font-size: 26px; line-height: 1.15; }
.ps-set__unit { color: var(--ps-text-2); font-size: 14px; }
.ps-set__line { margin: 4px 0 0; font-size: 14px; }

.ps-set__live { margin-top: 12px; }

@media (max-width: 767.98px) {
  .ps-set__rows { grid-template-columns: minmax(0, 1fr); }
  .ps-set__row { grid-template-columns: minmax(0, 1fr); }
  .ps-set__val { justify-content: flex-start; text-align: left; }
  .ps-set__pair { grid-template-columns: minmax(0, 1fr); }
}

/* ── the Colosseum (public/colosseum.html, colosseum.js) ──────────────────────
   The standings layout of docs/mockup/Switch.dc.html: one row per commander —
   the rank, the medallion and name (with the Recommended badge, the one lime
   mark besides the chart's callout: the mockup's), the P&L with realistic
   fills and its range, trades, time in a trade, days, the P&L per 100 minutes
   in a position, and the margin against the live commander (Athena's row says
   LIVE NOW, in her chip). Display only: no button. A phone stacks each row into
   a small card, each figure under its own label. */

.ps-col__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
}
.ps-col__sub { margin: 0; color: var(--ps-text-2); font-size: 13px; }
.ps-col__table { display: flex; flex-direction: column; margin-top: 12px; }
.ps-col__row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) 118px 64px 88px 52px 100px 160px;
  gap: 8px;
  align-items: center;
  padding: 12px 10px;
  border-bottom: 1px solid var(--ps-line);
}
.ps-col__row--head {
  padding-top: 0;
  color: var(--ps-muted);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.ps-col__row--rec {
  border-radius: var(--ps-r-row);
  background: rgba(214, 243, 107, 0.06);
}
.ps-col__cell { min-width: 0; }
.ps-col__c2,
.ps-col__c3,
.ps-col__c4,
.ps-col__c5,
.ps-col__c6 {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}
.ps-col__rank { color: var(--ps-text-2); font-size: 15px; }
.ps-col__who { display: flex; align-items: center; gap: 12px; }
.ps-col__medal { display: inline-flex; flex: 0 0 auto; width: 44px; height: 44px; }
.ps-col__medal .ps-medal { width: 44px; height: 44px; }
.ps-col .ps-col__drum { width: 44px; height: 44px; }
.ps-col__names { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ps-col__name {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 17px;
  font-weight: 600;
}
.ps-col__badge {
  padding: 2px 7px;
  border-radius: var(--ps-r-pill);
  background: var(--ps-lime);
  color: var(--ps-on-accent);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.ps-col__mode { color: var(--ps-text-2); font-size: 13px; }
.ps-col__num { font-size: 15px; font-variant-numeric: tabular-nums; }
.ps-col__c2 .ps-sg { font-size: 16px; font-weight: 600; }
.ps-col__subnum { color: var(--ps-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.ps-col__margin { font-size: 13px; }
.ps-col__words { color: var(--ps-text-2); }
.ps-col__muted { color: var(--ps-muted); font-size: 13px; }
.ps-col__live { font-weight: 700; letter-spacing: 0.06em; }
.ps-col__label { display: none; }
.ps-col__verdict { margin: 14px 10px 0; font-weight: 600; }
.ps-col__rule { margin: 6px 10px 0; color: var(--ps-muted); font-size: 13px; line-height: 1.5; }
.ps-col__empty { display: flex; align-items: center; gap: 14px; padding: 8px 0; }
.ps-col__empty-h { margin: 0; font-size: 17px; font-weight: 600; }
.ps-col__empty-line { margin: 2px 0 0; color: var(--ps-text-2); font-size: 14px; }
.ps-col__sells-main { margin: 8px 0 4px; }
.ps-col__sells-range { margin: 0 0 4px; color: var(--ps-text-2); }
.ps-col__foot { margin: 0; color: var(--ps-muted); font-size: 13px; }

@media (max-width: 767.98px) {
  .ps-col__row--head { display: none; }
  .ps-col__row {
    grid-template-columns: 22px repeat(3, minmax(0, 1fr));
    grid-template-areas:
      "rank who who who"
      ". pnl trades time"
      ". days per against";
    gap: 10px;
    align-items: start;
    padding: 14px 4px;
  }
  .ps-col__c0 { grid-area: rank; }
  .ps-col__c1 { grid-area: who; }
  .ps-col__c2 { grid-area: pnl; }
  .ps-col__c3 { grid-area: trades; }
  .ps-col__c4 { grid-area: time; }
  .ps-col__c5 { grid-area: days; }
  .ps-col__c6 { grid-area: per; }
  .ps-col__c7 { grid-area: against; }
  .ps-col__c2,
  .ps-col__c3,
  .ps-col__c4,
  .ps-col__c5,
  .ps-col__c6 { align-items: flex-start; text-align: left; }
  .ps-col__label {
    display: block;
    color: var(--ps-muted);
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }
  .ps-col__verdict,
  .ps-col__rule { margin-right: 4px; margin-left: 4px; }
}
