/* ══════════════════════════════════════════════════════════════════════
   CFIN TRADING EXCELLENCE                       © 2026 CFIN
   Proprietary & confidential — see repository NOTICE.           www.cfin.be
   ══════════════════════════════════════════════════════════════════════ */
/* =====================================================================
   perf-page.css — public /performance page (trade.cfin.be)
   Trade purple+blue family + page-local amber/green accents.
   Token-driven (theme.css); .light + @media(prefers-color-scheme:light)
   mirror the page-local tokens. Gradient ONLY on section titles.
   ===================================================================== */

/* === page-local tokens (token-driven; .light overrides below) ===
   SCOPED to .perf-root (not bare :root) so they do NOT leak into the admin
   shell when this stylesheet is loaded inside the admin Performance tab.
   --amber / --surface-1 / --flag collide with theme.css / design-system.css
   global token names; defining them on :root would restyle admin chrome
   (design-system .cfin-card/.dashboard-section/table backgrounds use
   var(--surface-1)). .perf-root wraps the entire report on BOTH the
   standalone page and the admin tab, so consumers still resolve them. */
.perf-root {
  /* --amber removed: inherits rgb(247,147,30) from :root (theme.css canonical) */
  --amber-tint: rgba(247,147,30,.16);
  --green-ea: var(--profit);            /* was #2ec5a8 off-brand teal; profit adapts per mode */
  --green-tint: rgba(var(--profit-rgb), .16);
  /* Iris family (added 2026-07-16, CEO "we compare green to iris now").
     Purple-blue brand, same tokens as the landing page's Iris cards
     (#6a71e0 → #a95ff4). Deliberately NOT --purple from theme.css: that is a
     generic UI accent, whereas this is Project Iris's brand identity and must
     stay visually distinct from --green-ea on the Green-vs-Iris comparison. */
  --iris-ea: #6a71e0;
  --iris-tint: rgba(106,113,224,.16);
  --surface-1: var(--bg-elevated);     /* was rgb(58,58,60); --bg-elevated adapts per mode */
  --flag: var(--orange, #ff9500);
  --flag-tint: var(--orange-bg);
  --hairline: #ffffff;                  /* svg point-highlight stroke (dark) */
}
/* Light page-local tokens. Mirror theme.css exactly: theme.css flips its
   tokens via BOTH :root.light (explicit pin) AND @media (prefers-color-scheme:light)
   (system, when un-pinned). We must do the same for our page-local tokens or
   they'd stay dark on a white card. Keep these two blocks identical. */
:root.light .perf-root {
  /* --amber, --green-ea, --surface-1 removed: var() references in base block
     already resolve correctly via theme.css light-mode tokens on :root.light */
  --amber-tint: rgba(235,140,25,.14);
  --green-tint: rgba(var(--profit-rgb), .14);
  --flag: var(--orange);
  --flag-tint: var(--orange-bg);
  --hairline: rgb(60,60,67);            /* dark hairline on light bg */
}
/* WCAG AA fix: .hint / small muted text in light mode reaches ≥4.5:1 on white.
   rgb(90,90,98) ≈ 6.7:1 on #fff. Scoped only to .perf-root; theme.css untouched.
   I7: extended beyond .hint to the page-local muted/dim small text the audit
   flagged (~11px P&L cues, sub-labels, footnotes, table dims, metric keys). Those
   resolve var(--text-dim), which in light mode (~rgb(120,120,128) ≈ 4.0:1 on #fff)
   was borderline; pin them to rgb(88,88,96) ≈ 6.9:1 so all clear 4.5:1. Dark mode
   is NOT touched (these overrides live only under :root.light / @media light). */
:root.light .perf-root .hint,
:root.light .perf-root .section > .hint,
:root.light .perf-root .section > h2 .hint,
:root.light .perf-root .sub,
:root.light .perf-root .hcard .sm,
:root.light .perf-root #heroGrid .stat-chip .sm,
:root.light .perf-root .card .retsub,
:root.light .perf-root .card .cfg,
:root.light .perf-root .method .disc,
:root.light .perf-root .nodata,
:root.light .perf-root table.perf th,
:root.light .perf-root table.acct-table td.cfgcell {
  color: rgb(88,88,96);
}
@media (prefers-color-scheme: light) {
  .perf-root {
    /* --amber, --green-ea, --surface-1 removed: var() references in base block
       resolve via theme.css @media light tokens automatically */
    --amber-tint: rgba(235,140,25,.14);
    --green-tint: rgba(var(--profit-rgb), .14);
    --flag: var(--orange);
    --flag-tint: var(--orange-bg);
    --hairline: rgb(60,60,67);
  }
  .perf-root .hint,
  .perf-root .section > .hint,
  .perf-root .section > h2 .hint,
  .perf-root .sub,
  .perf-root .hcard .sm,
  .perf-root #heroGrid .stat-chip .sm,
  .perf-root .card .retsub,
  .perf-root .card .cfg,
  .perf-root .method .disc,
  .perf-root .nodata,
  .perf-root table.perf th,
  .perf-root table.acct-table td.cfgcell {
    color: rgb(88,88,96);
  }
}

/* ===================== ambient background mesh =====================
   Every other page on the site sits on theme.css's fixed full-viewport
   `body::before` ambient gradient mesh (radial-gradient orbs). The standalone
   /performance page should match — paint the same mesh here explicitly so it
   shows regardless of stylesheet load order, in both colour schemes. Scoped to
   body.perf-standalone so the admin Performance tab (admin shell body, never
   .perf-standalone) is untouched. */
body.perf-standalone::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 800px 600px at 10% 15%, rgba(10, 132, 255, 0.18), transparent 70%),
    radial-gradient(ellipse 700px 500px at 85% 8%, rgba(191, 90, 242, 0.15), transparent 70%),
    radial-gradient(ellipse 600px 500px at 70% 75%, rgba(52, 199, 89, 0.12), transparent 70%),
    radial-gradient(ellipse 700px 400px at 25% 65%, rgba(90, 200, 250, 0.10), transparent 70%);
  will-change: transform;
  transform: translateZ(0);
}
:root.light body.perf-standalone::before {
  background:
    radial-gradient(ellipse 800px 600px at 10% 15%, rgba(10, 132, 255, 0.10), transparent 70%),
    radial-gradient(ellipse 700px 500px at 85% 8%, rgba(191, 90, 242, 0.08), transparent 70%),
    radial-gradient(ellipse 600px 500px at 70% 75%, rgba(52, 199, 89, 0.06), transparent 70%),
    radial-gradient(ellipse 700px 400px at 25% 65%, rgba(90, 200, 250, 0.05), transparent 70%);
}
/* Report content sits above the fixed mesh. */
body.perf-standalone .perf-site-header,
body.perf-standalone .perf-root,
body.perf-standalone .site-footer { position: relative; z-index: 1; }

/* ===================== standalone site header ===================== */
/* Sticky top bar for the public standalone /performance page only. Mirrors the
   landing-nav brand (animated gradient wordmark + pulsing dot + pill CTA) using
   theme tokens + theme.css keyframes (gradientShiftSlow/Fast, pulse). NOT used
   inside the admin tab (that body is the admin shell, never .perf-standalone). */
body.perf-standalone .perf-site-header {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px clamp(16px, 4vw, 40px);
  background: color-mix(in srgb, var(--bg-main) 80%, transparent);
  border-bottom: 1px solid var(--border-subtle);
  backdrop-filter: saturate(170%) blur(14px);
  -webkit-backdrop-filter: saturate(170%) blur(14px);
}
body.perf-standalone .perf-site-header .psh-brand {
  display: inline-flex; align-items: center; gap: 9px;
  text-decoration: none; min-width: 0;
}
/* Animated gradient wordmark — mirrors the landing-nav .logo-text. */
body.perf-standalone .perf-site-header .psh-name {
  font-size: 1.45rem; font-weight: 900; font-style: italic; letter-spacing: -.02em;
  line-height: 1;
  background: linear-gradient(90deg, var(--profit), var(--teal), var(--accent), var(--profit));
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  /* Fallback to solid green if background-clip:text isn't honored (print, old
     engines) so the wordmark never renders as invisible transparent text. */
  -webkit-text-fill-color: transparent; color: var(--profit);
  animation: gradientShiftSlow 4s ease-in-out infinite;
}
body.perf-standalone .perf-site-header .psh-brand:hover .psh-name {
  animation: gradientShiftFast 1s ease infinite; filter: brightness(1.1);
}
/* Pulsing green status dot — mirrors the landing-nav .logo-dot. */
body.perf-standalone .perf-site-header .psh-dot {
  width: 8px; height: 8px; flex: none; border-radius: 50%;
  background: var(--profit); box-shadow: 0 0 0 3px var(--profit-bg);
  animation: pulse 2s ease-in-out infinite;
}
body.perf-standalone .perf-site-header .psh-tag {
  font-size: .76rem; font-weight: 600; color: var(--text-sub); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  padding-left: 11px; margin-left: 2px; border-left: 1px solid var(--border-subtle);
}
/* Back-to-site affordance — pill CTA matching the landing-nav .nav-cta. */
body.perf-standalone .perf-site-header .psh-home {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  font-size: .82rem; font-weight: 600; text-decoration: none;
  color: var(--profit); background: var(--profit-bg);
  border: 1px solid var(--profit-bg); border-radius: var(--radius-pill, 100px);
  padding: 8px 16px; transition: border-color .15s, color .15s, background .15s, transform .15s;
}
body.perf-standalone .perf-site-header .psh-home:hover {
  border-color: var(--profit); transform: translateY(-2px);
}
body.perf-standalone .perf-site-header .psh-home svg { flex: none; transition: transform .15s; }
body.perf-standalone .perf-site-header .psh-home:hover svg { transform: translateX(-3px); }
@media (max-width: 560px) {
  body.perf-standalone .perf-site-header { padding: 11px 14px; }
  body.perf-standalone .perf-site-header .psh-tag { display: none; }
  body.perf-standalone .perf-site-header .psh-name { font-size: 1.3rem; }
}
@media (max-width: 380px) {
  body.perf-standalone .perf-site-header .psh-home .psh-home-lbl { display: none; }
  body.perf-standalone .perf-site-header .psh-home { padding: 8px 12px; }
}
@media (prefers-reduced-motion: reduce) {
  body.perf-standalone .perf-site-header .psh-name,
  body.perf-standalone .perf-site-header .psh-dot { animation: none; }
}

/* box-sizing scoped to the report subtree so it never re-flows the admin shell
   (which has its own box model). On the standalone page .perf-root wraps the
   whole body, so this still covers everything the page renders. */
.perf-root, .perf-root * { box-sizing: border-box; }

/* PAGE-LEVEL chrome — applies ONLY on the standalone /performance page
   (body.perf-standalone). When this stylesheet is loaded inside the admin
   Performance tab the body belongs to the admin shell, so these rules must
   NOT touch it (no background / font / margin takeover). */
body.perf-standalone { margin: 0; background: var(--bg-main); color: var(--text-main);
       font-family: var(--font-sans); }
.perf-root a { color: var(--accent); }
/* RESTRAINT LAYER (2026-07-17). Ceiling 1480→1320 and a fluid gutter.
   Measured before: ratio was 0.965 at 1440 (20px gutters) but 0.849 at 1366
   (98px gutters) — a NARROWER screen got MORE air than a wider one, because
   the `@media (max-width:1400px){max-width:1200px}` override kicked in below
   1400 while the 1480 ceiling never engaged at 1440. Both copies of that
   override are removed (see the two responsive sections below), so this one
   ceiling now governs and the gutter grows monotonically with the viewport. */
.perf-root .wrap { max-width: 1320px; margin: 0 auto; padding: 28px clamp(16px, 4vw, 48px) 80px; }
/* Inside the admin tab the report is fragment-injected with no outer page
   padding/centering — let it fill the pane and scroll with the page. */
.perfpub-report-mount .wrap { max-width: none; padding: 0; }

/* ===================== header (results-oriented public framing) ===================== */
.perf-root header.page { display:flex; flex-wrap:wrap; align-items:flex-end; justify-content:space-between; gap:16px; margin-bottom: 18px; }
.perf-root header.page h1 { font-size: 1.85rem; margin: 0 0 6px; letter-spacing:-.02em; line-height:1.1;
  font-weight:800; color:var(--text-main); }
.perf-root header.page .sub { color: var(--text-sub); font-size:.95rem; max-width:720px; line-height:1.5; }
.perf-root header.page .meta { display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.perf-root .updated { font-size:.78rem; color: var(--text-dim); white-space:nowrap; }
/* genuinely-stale data (markets open + age>1h): nudge the reader's attention. */
.perf-root .updated.stale { color: var(--warning, var(--orange)); }
/* .livepill — .chip geometry + profit semantic (larger padding keeps dot readable) */
.perf-root .livepill { display:inline-flex; align-items:center; gap:6px; font-size:var(--font-caption,11px); font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; color:var(--profit); background:var(--profit-bg); border-radius:var(--radius-pill,100px); padding:4px 11px; }
.perf-root .livepill .dot { width:7px; height:7px; border-radius:50%; background:var(--profit); box-shadow:0 0 0 3px var(--profit-bg); }
/* Markets closed — fleet resting: neutral pill, not a green "Live" lie. */
.perf-root .livepill.resting { color:var(--text-dim); background:var(--bg-soft, rgba(127,127,127,.12)); }
.perf-root .livepill.resting .dot { background:var(--text-dim); box-shadow:0 0 0 3px var(--bg-soft, rgba(127,127,127,.12)); }
/* Markets open but the last heartbeat is genuinely stale (>1h): warn. */
.perf-root .livepill.stale { color:var(--warning, var(--orange)); background:var(--orange-bg); }
.perf-root .livepill.stale .dot { background:var(--warning, var(--orange)); box-shadow:0 0 0 3px var(--orange-bg); }

/* "Actively trading now" indicator on per-account cards — live_positions-driven
   (real-time), distinct from the heartbeat dot. Green pulsing dot = the account
   currently holds at least one open position. */
.perf-root .trading-now { display:inline-flex; align-items:center; gap:5px; color:var(--profit); font-weight:600; }
.perf-root .trading-now .tdot { width:7px; height:7px; border-radius:50%; background:var(--profit); box-shadow:0 0 0 0 var(--profit); animation:perf-trade-pulse 1.8s ease-out infinite; }
@keyframes perf-trade-pulse {
  0% { box-shadow:0 0 0 0 rgba(var(--profit-rgb),.5); }
  70% { box-shadow:0 0 0 5px rgba(var(--profit-rgb),0); }
  100% { box-shadow:0 0 0 0 rgba(var(--profit-rgb),0); }
}

/* section primitives */
/* Card chrome aligned to the design-system standard (--surface-1 / --radius-card /
   --space-4) so the /performance cards match the dashboard, stats and admin cards
   — one consistent card look across every page. */
.perf-root .section { background:var(--surface-1, var(--bg-card)); border:1px solid var(--border); border-radius:var(--radius-card, 12px); padding:var(--space-4, 16px) calc(var(--space-4, 16px) + 4px); margin-bottom:22px; }

/* ===== Two-column chart pairing (wide screens) =====
   .chart-pair wraps two chart sections so they sit side-by-side at >=1200px and
   stack to one column below that. Tables / heatmap / KPI cards stay full-width
   (they are NOT wrapped). Each .section keeps its own card styling; the grid
   just lays them out. align-items:start so a shorter card doesn't stretch. */
.perf-root .chart-pair { display:grid; gap:16px; grid-template-columns:1fr; }
.perf-root .chart-pair > .section { margin-bottom:22px; min-width:0; }
@media (min-width:1200px){
  .perf-root .chart-pair { grid-template-columns:1fr 1fr; align-items:start; }
  /* Chart heights are now set in JS (sizeChart) to an exact pixel value that
     matches the SVG viewBox 1:1, so the chart fills its box with no distortion
     and no letterbox. We deliberately do NOT impose min/max-height here — a CSS
     height that differs from the JS-set value would reintroduce either a stretch
     (the old "squished" bug) or letterbox whitespace. align-items:start keeps the
     two cards top-aligned even if their natural heights differ slightly. */
}
.perf-root .section > h2 { font-size:1.05rem; margin:0 0 4px; display:flex; align-items:center; gap:9px;
  font-weight:700; color:var(--text-main); width:fit-content; }
.perf-root .section > h2 .secnum { -webkit-text-fill-color:initial; background:var(--surface-1); }
.perf-root .section > h2 .hint { -webkit-text-fill-color:initial; background:none; color:var(--text-dim); }
.perf-root .section > .hint { font-size:.78rem; color:var(--text-dim); margin:0 0 14px; line-height:1.5; }

/* RESTRAINT LAYER (2026-07-17): ONE measure cap for every block hint.
   These intros are prose and were uncapped, so they inherited the full content
   column — measured 186ch at 1920 (157ch once the 1320px ceiling landed) against
   a 45-75ch comfort band.
   Deliberately ONE rule on an element-qualified selector rather than extending
   the rule above: `.section > .hint` misses the hints nested in
   .avg-trend-wrap / .daily-heatmap-wrap / .today-head / .perf-zone-deep, and
   widening THAT selector would drag its font-size:.78rem onto them and silently
   restyle the 2026-07-06 overhaul. This sets max-width and nothing else.
   `p.hint` (not `.hint`) excludes the inline `<span class="hint">` badge inside
   h2 at line 281 — which must stay inline. `ch` not px so the cap tracks the
   font-size steps at 945/1151. Precedent: header.page .sub caps at 720px (229). */
:root { --perf-measure: 72ch; }
.perf-root p.hint { max-width: var(--perf-measure, 72ch); }
.perf-root .section > h2 + .hint { margin-top:2px; }
.perf-root .secnum { display:inline-flex; align-items:center; justify-content:center; width:20px; height:20px; border-radius:6px;
          background:var(--surface-1); color:var(--text-sub); font-size:.7rem; font-weight:800; flex:none; }

/* ===================== fresh-fleet framing banner ===================== */
.perf-root .freshbanner { display:flex; align-items:flex-start; gap:12px; background:var(--accent-bg, var(--surface-1));
  border:1px solid var(--accent); border-radius:14px; padding:13px 16px; margin:0 0 22px; }
.perf-root .freshbanner .ic { flex:none; color:var(--accent); display:flex; margin-top:1px; }
.perf-root .freshbanner .bt { font-weight:700; font-size:.9rem; margin:0 0 2px; color:var(--text-main); }
.perf-root .freshbanner .bb { font-size:.8rem; color:var(--text-sub); line-height:1.5; }
/* markets-closed variant: calm neutral framing, distinct from the accent
   fresh-fleet banner so a resting-weekend state never reads as an alert. */
.perf-root .freshbanner.mktclosed { background:var(--surface-1); border-color:var(--border, var(--surface-2)); }
.perf-root .freshbanner.mktclosed .ic { color:var(--text-dim); }

/* ===================== 1 · hero stat cards ===================== */
.perf-root .hero-grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(180px,1fr)); gap:14px; margin:6px 0 22px; }

/* HERO METRIC + COMPACT CHIPS scorecard (#heroGrid).
   Id selector wins over the .hero-grid class rules below/across breakpoints so
   this two-part layout (one accented hero card + a quiet chip grid) is the
   single source of truth for the header scorecard. Default = stacked (mobile);
   the ≥1000px rule (further down) splits hero left / chips right. */
.perf-root #heroGrid { display:grid; grid-template-columns:1fr; gap:14px; margin:6px 0 22px; align-items:stretch; }
.perf-root #heroGrid .chip-grid { display:grid; gap:10px; grid-template-columns:repeat(auto-fit, minmax(130px,1fr)); align-content:start; }
/* Compact stat chip — quiet card, no accent stripe (the hero is the only
   accented focal element). Theme-aware via tokens; dual light/dark handled by
   the token layer + the refinement block, so no per-theme overrides needed. */
.perf-root #heroGrid .stat-chip {
  background:var(--bg-card); border:1px solid var(--border-subtle); border-radius:10px;
  padding:11px 13px; position:relative;
  display:flex; flex-direction:column; justify-content:center;
  transition:border-color .15s, background .15s;
}
.perf-root #heroGrid .stat-chip:hover { border-color:var(--border); }
.perf-root #heroGrid .stat-chip .k { font-size:.7rem; font-weight:600; text-transform:uppercase; letter-spacing:.04em; color:var(--text-sub); }
.perf-root #heroGrid .stat-chip .v { font-size:1.25rem; font-weight:700; margin-top:2px; line-height:1.1; letter-spacing:-.01em;
  color:var(--text-main); font-variant-numeric:tabular-nums; }
.perf-root #heroGrid .stat-chip .v .pos, .perf-root #heroGrid .stat-chip .v.pos { color:var(--profit); }
.perf-root #heroGrid .stat-chip .v .neg, .perf-root #heroGrid .stat-chip .v.neg { color:var(--loss); }
.perf-root #heroGrid .stat-chip .sm { font-size:.7rem; color:var(--text-dim); margin-top:3px; }
/* Wide screens: hero left (~38%), chip-grid right fills to hero height.
   3-column grid forces 5 chips into 2 rows (3+2); align-content:stretch
   expands those rows to fill the full column height — no empty gap. */
@media (min-width:1000px){
  .perf-root #heroGrid { grid-template-columns: minmax(300px, 1.3fr) 2fr; gap:14px; align-items:stretch; justify-content:stretch; }
  .perf-root #heroGrid .chip-grid { grid-template-columns:repeat(3,1fr); grid-auto-rows:1fr; align-content:stretch; height:100%; }
}
.perf-root .hcard { background:var(--bg-card); border:1px solid var(--border); border-radius:14px; padding:16px 18px;
  min-height:104px; position:relative; overflow:hidden; }
/* Accent stripe is now MEANINGFUL: secondary cards get a quiet 2px hairline stripe;
   only the hero-primary card (rule below) gets the full-opacity accent + tint wash. */
.perf-root .hcard::before { content:''; position:absolute; left:0; top:0; bottom:0; width:2px; background:var(--border-subtle); opacity:1; }
.perf-root .hcard.amber::before { background:var(--amber); }
.perf-root .hcard.green::before { background:var(--green-ea); }
/* "Best account today" — accent-outlined highlight card */
.perf-root .hcard.best { border-color:var(--accent); box-shadow:inset 0 0 0 1px var(--accent), 0 4px 18px rgba(0,0,0,.16); }
.perf-root .hcard.best::before { background:var(--accent); opacity:1; width:4px; }
.perf-root .hcard.best .best-acct { color:var(--text); font-weight:800; font-variant-numeric:tabular-nums; }
.perf-root .hcard .k { font-size:.72rem; font-weight:600; text-transform:uppercase; letter-spacing:.04em; color:var(--text-sub); }
.perf-root .hcard .v { font-size:1.5rem; font-weight:700; margin-top:3px; line-height:1.1; letter-spacing:-.01em;
  color:var(--text-main); font-variant-numeric:tabular-nums; }
.perf-root .hcard .v .pos, .perf-root .hcard .v.pos { color:var(--profit); }
.perf-root .hcard .v .neg, .perf-root .hcard .v.neg { color:var(--loss); }
.perf-root .hcard .sm { font-size:.75rem; color:var(--text-dim); margin-top:4px; }
.perf-root .hcard .splitbar { display:flex; height:7px; border-radius:5px; overflow:hidden; margin-top:9px; background:var(--surface-1); }
.perf-root .hcard .splitbar i { display:block; height:100%; }
.perf-root .hcard .splitbar i.amber { background:var(--amber); } .perf-root .hcard .splitbar i.green { background:var(--green-ea); }
.perf-root .hcard .splitbar i.iris { background:var(--iris-ea); }
.perf-root .pos { color: var(--profit); } .perf-root .neg { color: var(--loss); } .perf-root .flat { color: var(--text-sub); }

/* ===================== 2 · fleet composition ===================== */
.perf-root .comp-grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(230px,1fr)); gap:18px; }
.perf-root .comp-block h3 { font-size:.82rem; margin:0 0 10px; color:var(--text-sub); }
.perf-root .comp-row { display:grid; grid-template-columns: 110px 1fr 38px; align-items:center; gap:10px; margin-bottom:9px; }
.perf-root .comp-row .clbl { font-size:.78rem; color:var(--text-sub); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.perf-root .comp-row .ctrack { position:relative; height:16px; background:var(--surface-1); border-radius:8px; overflow:hidden; }
.perf-root .comp-row .cfill { position:absolute; left:0; top:0; bottom:0; border-radius:8px; min-width:3px; background:var(--accent); }
.perf-root .comp-row .cfill.amber { background:var(--amber); } .perf-root .comp-row .cfill.green { background:var(--green-ea); }
.perf-root .comp-row .cfill.iris { background:var(--iris-ea); }
.perf-root .comp-row .cfill.purple { background:var(--purple); }
.perf-root .comp-row .cval { font-size:.82rem; font-weight:700; font-variant-numeric:tabular-nums; text-align:right; color:var(--text-sub); }

/* ===================== 3 · growth / monthly ===================== */
.perf-root .growth-head { display:flex; flex-wrap:wrap; align-items:center; gap:10px 14px; margin-bottom:14px; }
.perf-root .growth-head .spacer { flex:1; }
.perf-root .seg { display:inline-flex; border:1px solid var(--border); border-radius:10px; overflow:hidden; }
.perf-root .seg button { background:transparent; color:var(--text-sub); border:0; padding:7px 13px; cursor:pointer; font-size:.82rem; transition:background .15s,color .15s; }
/* Active/selected state: clearly distinct from inactive in both dark and light modes.
   Uses the accent tint so contrast ratio between active(accent) and inactive(text-sub) ≥ 3:1. */
.perf-root .seg button.active {
  background: var(--ds-accent-tint-strong, color-mix(in srgb, var(--accent) 18%, var(--surface-1)));
  border-color: var(--ds-accent-border, color-mix(in srgb, var(--accent) 35%, transparent));
  color: var(--accent);
  font-weight: var(--fw-semi, 600);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}
/* Mobile/touch tap targets: segmented controls, nav-jump links, tab buttons,
   toolbar actions and density/family pills were ~28–32px tall — below the 44px
   touch minimum (Apple HIG; matches the 40px+ standard applied on /charts).
   Phones + small tablets only; desktop sizing unchanged. */
@media (max-width:700px){
  /* segmented controls (.seg button) — growth family/scale/net toggles, agg/range segs */
  .perf-root .seg button,
  .perf-root .toolbar .seg button,
  /* nav-bar family filter (.nav-famseg / #navFamSeg) */
  .perf-root .nav-famseg button,
  .perf-root #navFamSeg button { min-height:44px; display:inline-flex; align-items:center; justify-content:center; }
  /* density toggle button */
  .perf-root .perf-density-toggle { min-height:44px; display:inline-flex; align-items:center; }
  /* section-nav jump links (#perfNavLinks .pnl) */
  .perf-root .perf-nav-links .pnl { min-height:44px; display:inline-flex; align-items:center; padding-left:12px; padding-right:12px; }
  /* tab strip buttons (.perf-tab) */
  .perf-root .perf-tab { min-height:44px; padding-top:0; padding-bottom:0; display:inline-flex; align-items:center; }
  /* toolbar action buttons (.btn) and label-wrapped toggles (.toggle) */
  .perf-root .toolbar .btn,
  .perf-root .toolbar .toggle { min-height:44px; display:inline-flex; align-items:center; }
}
.perf-root svg.growth { width:100%; height:auto; display:block; }
/* Floor so the growth curve doesn't compress at intermediate widths; ceiling so it
   never over-stretches past ~520px on very wide screens (viewBox 900×300). */
/* height set in JS (sizeChart) to match the viewBox 1:1 — no min/max clamp,
   which would letterbox or stretch the now-measured render. */
.perf-root .growth .axis { stroke: var(--border); stroke-width:1; }
.perf-root .growth .gridln { stroke: var(--border); stroke-width:1; stroke-dasharray:2 4; opacity:.45; }
.perf-root .growth .zeroln { stroke: var(--text-dim); stroke-width:1; stroke-dasharray:4 3; opacity:.7; }
.perf-root .growth text { fill: var(--text-dim); font-size:11px; }
.perf-root .growth path.gcurve { fill:none; stroke-width:2; }
.perf-root .growth path.gcurve.linear { stroke:var(--accent); }
/* Legend font-size: minimum 11px (≈ var(--font-caption)) so labels are legible at normal reading distance */
.perf-root .glegend { display:flex; gap:16px; flex-wrap:wrap; font-size:var(--font-caption, 11px); color:var(--text-sub); margin-top:10px; }
.perf-root .glegend .li { display:flex; align-items:center; gap:6px; }
.perf-root .glegend .dash { width:16px; height:2px; border-radius:2px; display:inline-block; }
.perf-root .glegend .dash.linear { background:var(--accent); }

/* ===================== 4 · monthly table ===================== */
/* I2: scroll container for table.perf (monthly breakdown). table.perf has
   white-space:nowrap + min-width:560px, so on phones it MUST scroll inside this
   wrapper rather than clip/overflow its card. max-width:100% pins the wrapper to
   its card width so overflow-x engages instead of the whole card widening. */
.perf-root .tbl-scroll { overflow-x:auto; -webkit-overflow-scrolling:touch; max-width:100%; }
.perf-root table.perf { width:100%; border-collapse:separate; border-spacing:0; font-size:.84rem;
  font-variant-numeric:tabular-nums; min-width:560px; }
.perf-root table.perf th, .perf-root table.perf td { padding:8px 12px; white-space:nowrap; }
.perf-root table.perf th { font-size:.66rem; text-transform:uppercase; letter-spacing:.05em; color:var(--text-dim);
  border-bottom:1px solid var(--border); text-align:right; font-weight:700; }
.perf-root table.perf th:first-child, .perf-root table.perf td:first-child { text-align:left; }
.perf-root table.perf td { text-align:right; border-bottom:1px solid var(--border-subtle); color:var(--text-sub); }
.perf-root table.perf td:first-child { color:var(--text-main); font-weight:600; }
.perf-root table.perf tbody tr:last-child td { border-bottom:0; }

/* ===================== 5 · per-EA / per-symbol aggregate ===================== */
.perf-root .agg-head { display:flex; flex-wrap:wrap; align-items:center; gap:10px 14px; margin-bottom:14px; }
.perf-root .agg-head .spacer { flex:1; }
.perf-root .agg-row { display:grid; grid-template-columns: minmax(120px, max-content) repeat(4, minmax(64px,1fr)); align-items:center; gap:10px;
  padding:9px 10px; border-radius:9px; background:var(--surface-1); margin-bottom:7px; font-size:.82rem; }
.perf-root .agg-row.head { background:transparent; padding:2px 10px; font-size:.64rem; text-transform:uppercase;
  letter-spacing:.05em; color:var(--text-dim); font-weight:700; margin-bottom:4px; }
.perf-root .agg-row .akey { display:flex; align-items:center; gap:7px; font-weight:700; min-width:0; white-space:nowrap; }
.perf-root .agg-row .akey .cfg { font-size:.66rem; color:var(--text-dim); font-weight:600; }
.perf-root .agg-row .anum { text-align:right; font-variant-numeric:tabular-nums; }
.perf-root .agg-row.head .anum { text-align:right; }

/* swatch / badges shared */
.perf-root .swatch { width:10px; height:10px; border-radius:3px; display:inline-block; vertical-align:middle; }
.perf-root .swatch.amber { background:var(--amber); } .perf-root .swatch.green { background:var(--green-ea); }
.perf-root .swatch.iris { background:var(--iris-ea); }
/* .badge — shares .chip canonical geometry; keeps semantic amber/green colors */
.perf-root .badge {
  display: inline-flex; align-items: center; gap: var(--space-1, 4px);
  padding: 2px var(--space-2, 8px);
  border-radius: var(--radius-pill, 100px);
  font-size: var(--font-caption, 11px); font-weight: 600;
  line-height: 1.4; letter-spacing: .05em;
  text-transform: uppercase; white-space: nowrap;
}
.perf-root .badge.amber { background:var(--amber-tint); color:var(--amber); }
/* Iris family (2026-07-16) — mirrors the amber/green pairs above so an Iris
   account renders in its own brand purple-blue instead of colourless/green. */
.perf-root .badge.iris { background:var(--iris-tint); color:var(--iris-ea); }
.perf-root .badge.green { background:var(--green-tint); color:var(--green-ea); }

/* .acctbadge — per-account DEMO/LIVE label. Green "LIVE" = real money; muted
   "DEMO" = demonstration grid. Shares the pill geometry; tokens adapt to mode. */
.perf-root .acctbadge { display:inline-flex; align-items:center; font-size:var(--font-caption,11px);
  font-weight:700; letter-spacing:.04em; text-transform:uppercase; white-space:nowrap;
  border-radius:var(--radius-pill,100px); padding:1px var(--space-2,8px); margin-left:5px; vertical-align:middle; }
.perf-root .acctbadge.live { color:var(--green-ea); background:var(--green-tint);
  border:1px solid color-mix(in srgb, var(--green-ea) 45%, transparent); }
.perf-root .acctbadge.demo { color:var(--text-dim); background:var(--bg-soft, rgba(127,127,127,.12));
  border:1px solid var(--border, rgba(127,127,127,.22)); }
/* count chip inside the account-type segmented buttons (e.g. "Live € 3") */
.perf-root #acctseg .seg-n { margin-left:5px; font-size:.72em; font-weight:700; opacity:.7; font-variant-numeric:tabular-nums; }
/* account-type filter scope note — reuses .freshbanner; accent-tinted "info" tone */
.perf-root .freshbanner.acctscope { background:var(--accent-bg, var(--surface-1)); }
.perf-root .freshbanner.acctscope .ic { color:var(--accent); }

/* ===================== 6 · settings matrix (kept) ===================== */
.perf-root .matrix-grid { display:grid; gap:18px; grid-template-columns: repeat(auto-fit, minmax(250px,1fr)); }
.perf-root .mblock h3 { font-size:.82rem; margin:0 0 4px; color:var(--text-sub); }
.perf-root .mblock .sub { font-size:.7rem; color:var(--text-dim); margin:0 0 9px; }
.perf-root .hrow { display:grid; grid-template-columns: 96px 1fr; align-items:center; gap:8px; margin-bottom:7px; }
.perf-root .hrow .hlbl { font-size:.78rem; color:var(--text-sub); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.perf-root .hcell { position:relative; height:30px; border-radius:7px; display:flex; align-items:center; justify-content:space-between;
         padding:0 9px; font-size:.78rem; font-weight:700; font-variant-numeric:tabular-nums; border:1px solid transparent;
         color:var(--text-main); }
.perf-root .hcell .n { font-size:.62rem; font-weight:600; opacity:.7; }
.perf-root .hcell.best { outline:2px solid var(--accent); outline-offset:-2px; box-shadow:0 0 0 3px var(--accent-bg, transparent); }
.perf-root .hcell.best::after { content:'BEST'; position:absolute; top:-7px; right:6px; font-size:.5rem; font-weight:800; letter-spacing:.05em;
                     color:var(--accent); background:var(--bg-card); padding:0 3px; border-radius:3px; }
.perf-root .hcell.empty { background:var(--surface-1); color:var(--text-dim); }

/* ===================== 7 · risk metrics ===================== */
.perf-root .risk-grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(180px,1fr)); gap:14px; }
.perf-root .riskcard { border:1px solid var(--border-subtle); border-radius:12px; padding:13px 15px; background:var(--surface-1); }
.perf-root .riskcard .k { font-size:.68rem; text-transform:uppercase; letter-spacing:.05em; color:var(--text-dim); }
.perf-root .riskcard .v { font-size:1.3rem; font-weight:800; margin-top:4px; font-variant-numeric:tabular-nums; }
.perf-root .riskcard .sm { font-size:.74rem; color:var(--text-dim); margin-top:2px; }
/* breach: worst peak DD exceeded the configured cap — amber, not alarm-red */
.perf-root .riskcard--warn { border-color:var(--warning, var(--orange)); background:var(--orange-bg, var(--surface-1)); }
.perf-root .riskcard--warn .v,
.perf-root .riskcard--warn .sm b { color:var(--warning, var(--orange)); }

/* ===================== 8 · fleet health / heartbeats ===================== */
.perf-root .health-grid { display:grid; grid-template-columns: repeat(auto-fit, minmax(200px,1fr)); gap:14px; }
.perf-root .healthcard { border:1px solid var(--border-subtle); border-radius:12px; padding:14px 16px; background:var(--surface-1);
  display:flex; align-items:center; gap:13px; }
.perf-root .healthcard .hd { width:11px; height:11px; border-radius:50%; flex:none; background:var(--text-dim); }
.perf-root .healthcard .hd.live { background: var(--profit); box-shadow:0 0 0 4px var(--profit-bg); }
.perf-root .healthcard .hd.stale { background: var(--loss); box-shadow:0 0 0 4px var(--loss-bg); }
.perf-root .healthcard .ht .k { font-size:.7rem; text-transform:uppercase; letter-spacing:.05em; color:var(--text-dim); }
.perf-root .healthcard .ht .v { font-size:1.35rem; font-weight:800; font-variant-numeric:tabular-nums; margin-top:2px; }

/* ===================== empty states (new sections) ===================== */
.perf-root .nd-card { font-size:.82rem; color:var(--text-dim); padding:26px 14px; text-align:center;
  background:var(--surface-1); border-radius:12px; line-height:1.5; }
.perf-root .nd-card .nd-ic { display:block; margin:0 auto 8px; color:var(--text-dim); opacity:.6; }
.perf-root .nd-card .nd-t { font-weight:700; color:var(--text-sub); margin-bottom:3px; }

/* ===================== methodology footer ===================== */
.perf-root .method { margin-top:30px; padding:20px 22px; background:var(--bg-card); border:1px solid var(--border-subtle);
  border-radius:14px; font-size:.78rem; color:var(--text-sub); line-height:1.65; }
.perf-root .method h3 { font-size:.82rem; margin:0 0 9px; color:var(--text-main); }
.perf-root .method dl { display:grid; grid-template-columns: 160px 1fr; gap:6px 16px; margin:0 0 12px; }
.perf-root .method dt { color:var(--text-dim); font-weight:600; }
.perf-root .method dd { margin:0; color:var(--text-sub); }
.perf-root .method .disc { font-size:.74rem; color:var(--text-dim); border-top:1px solid var(--border-subtle); padding-top:11px; margin-top:4px; }

/* tooltip */
.perf-root #tip { position:fixed; z-index:50; pointer-events:none; background:var(--bg-panel); border:1px solid var(--border);
       border-radius:9px; padding:8px 10px; font-size:.74rem; line-height:1.5; box-shadow:0 8px 24px var(--shadow-color);
       color:var(--text-main); display:none; max-width:230px; }
.perf-root #tip b { font-weight:700; }

/* ===================== responsive ===================== */
/* ===== two-zone IA (T9): overview band vs deep-dive explorer =====
   The zones are structural wrappers only — sections inside keep their ids —
   with a quiet visual seam so the "at a glance" half and the interactive
   explorer read as two deliberate chapters, not one endless scroll. */
.perf-root .perf-zone-deep { margin-top:34px; padding-top:26px; border-top:1px solid var(--border-subtle); }
.perf-root .section-intro { background:transparent; border:0; padding:6px 0 0; margin-bottom:6px; }

/* REMOVED 2026-07-17: `@media (max-width:1400px){ .perf-root .wrap{max-width:1200px} }`
   recreated the gutter inversion (1366→98px gutters vs 1440→20px) and also
   leaked into the admin Performance tab, overriding
   `.perfpub-report-mount .wrap{max-width:none}` at ≤1400 by source order.
   The 1320px base ceiling covers this range. */
@media (max-width:1100px){
  /* horizontal gutter stays on the base clamp so it never steps DOWN as the
     viewport shrinks (a fixed 16px here meant 1101px got 44px and 1100px got
     16px); only the vertical rhythm tightens. */
  .perf-root .wrap { padding:24px clamp(16px, 4vw, 48px) 70px; }
  .perf-root header.page h1 { font-size:1.6rem; }
  /* mid-band (tablet/small laptop, T11): comfortable touch targets on the
     interactive explorer chrome */
  .perf-root .perf-tab { padding:10px 16px; min-height:40px; }
  .perf-root .scrubber input[type="range"] { min-height:28px; }
  .perf-root .comp-grid { grid-template-columns:1fr 1fr; }
}
@media (max-width:980px){
  .perf-root .comp-grid { grid-template-columns:1fr 1fr; }
}
@media (max-width:700px){
  /* horizontal gutter stays on the base clamp (floors at 16px). */
  .perf-root .wrap { padding:20px clamp(16px, 4vw, 48px) 64px; }
  .perf-root header.page h1 { font-size:1.4rem; }
  .perf-root .comp-grid { grid-template-columns:1fr; }
  .perf-root .section { padding:16px 14px; }
  .perf-root .method dl { grid-template-columns:1fr; gap:2px 0; }
  .perf-root .method dt { margin-top:7px; }
  .perf-root .agg-row { grid-template-columns:96px repeat(4, minmax(48px,1fr)); gap:7px; font-size:.76rem; }
}
@media (max-width:480px){
  .perf-root header.page h1 { font-size:1.3rem; }
  .perf-root .hero-grid { grid-template-columns:1fr 1fr; }
  .perf-root .hcard .v { font-size:1.35rem; }
  /* comp-row: narrow columns on phones — label ellipsis, bar fills remaining space */
  .perf-root .comp-row { grid-template-columns:76px 1fr 30px; gap:7px; }
  .perf-root .agg-row { grid-template-columns:74px repeat(4, minmax(40px,1fr)); }
}
/* Defect 4a: comp-row must never overflow its container on any mobile width.
   box-sizing already scoped via .perf-root * — belt-and-suspenders max-width. */
.perf-root .comp-row { max-width:100%; }
.perf-root .comp-row .ctrack { min-width:0; overflow:hidden; }
.perf-root .comp-block { min-width:0; overflow:hidden; }

/* Defect 4b: settings heatmap (#matrix grid) and combo table (#combo)
   must scroll horizontally on mobile instead of clipping.
   #matrix IS the .matrix-grid element (same div carries both class + id).
   Its auto-fit columns collapse to 1 col on ≤700px, so the content fits
   without a min-width — no scroll needed. The overflow-x:auto here is a
   belt-and-suspenders guard in case future content widens it.
   (The old ".perf-root #matrix .matrix-grid" rule selected a non-existent
   child and has been removed.) */
@media (max-width:700px) {
  .perf-root #matrix { overflow-x:auto; -webkit-overflow-scrolling:touch; }
  /* combo-scroll wraps <table class="combo"> with overflow-x:auto already;
     reinforce min-width so the table scrolls rather than squashing columns */
  .perf-root .combo-scroll { overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .perf-root table.combo { min-width:560px; }
}

/* ===================== markets-closed / resting framing ===================== */
/* A weekend wall of "stale" heartbeats is the fleet RESTING, not an outage.
   The resting token is a calm neutral (text-sub), never the alarm-red loss. */
.perf-root .healthcard .hd.resting { background: var(--text-sub); box-shadow:0 0 0 4px var(--surface-1); }
/* full-width calm banner above the health tiles when markets are closed */
.perf-root .health-banner { grid-column:1 / -1; display:flex; align-items:flex-start; gap:11px;
  background:var(--surface-1); border:1px solid var(--border); border-radius:12px;
  padding:12px 15px; font-size:.82rem; color:var(--text-sub); line-height:1.5; }
.perf-root .health-banner b { color:var(--text-main); font-weight:700; }
.perf-root .health-banner .hb-dot { width:10px; height:10px; border-radius:50%; flex:none; margin-top:3px; }
.perf-root .health-banner .hb-dot.resting { background:var(--text-sub); box-shadow:0 0 0 4px var(--bg-card); }

/* per-account card heartbeat dot: resting = neutral, NOT red */
.perf-root .dot.resting { background: var(--text-sub); }

/* ===================== collapse all-zero settings tables ===================== */
.perf-root .combo-collapse { border:1px solid var(--border-subtle); border-radius:12px; background:var(--surface-1); overflow:hidden; }
.perf-root .combo-collapse > summary { list-style:none; cursor:pointer; display:flex; align-items:center; gap:9px;
  padding:12px 15px; font-size:.86rem; font-weight:700; color:var(--text-sub); user-select:none; }
.perf-root .combo-collapse > summary::-webkit-details-marker { display:none; }
.perf-root .combo-collapse > summary .cc-meta { font-size:.74rem; font-weight:600; color:var(--text-dim); }
.perf-root .combo-collapse > summary .cc-toggle { margin-left:auto; font-size:.72rem; font-weight:700; color:var(--accent);
  border:1px solid var(--border); border-radius:8px; padding:4px 10px; }
.perf-root .combo-collapse[open] > summary .cc-toggle::after { content:' ▲'; }
.perf-root .combo-collapse:not([open]) > summary .cc-toggle::after { content:' ▼'; }
.perf-root .combo-collapse > .combo-scroll { padding:0 12px 12px; }

/* ranked-list compact summary when every account is tied at zero */
.perf-root .rank-summary { font-size:.84rem; color:var(--text-sub); background:var(--surface-1);
  border-radius:12px; padding:16px 18px; line-height:1.55; }
.perf-root .rank-summary b { color:var(--text-main); font-weight:800; }

/* ===== Monthly table <details class="monthly-table-details"> ===== */
/* Mirrors .combo-collapse / .perf-methodology patterns for a consistent collapse affordance */
.perf-root .monthly-table-details { border:1px solid var(--border-subtle); border-radius:12px; background:var(--surface-1); overflow:hidden; }
.perf-root .monthly-table-details > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 15px;
  font-size: .86rem;
  font-weight: 700;
  color: var(--text-sub);
  user-select: none;
  transition: color .15s;
}
.perf-root .monthly-table-details > summary::-webkit-details-marker { display: none; }
.perf-root .monthly-table-details > summary::marker { display: none; }
.perf-root .monthly-table-details > summary::after {
  content: '▼';
  font-size: .62rem;
  color: var(--accent);
  margin-left: auto;
  transition: transform .2s;
}
.perf-root .monthly-table-details[open] > summary::after { transform: rotate(180deg); }
.perf-root .monthly-table-details > summary:hover { color: var(--text-main); }
.perf-root .monthly-table-details > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 5px;
}
.perf-root .monthly-table-details[open] > summary {
  border-bottom: 1px solid var(--border-subtle);
}
.perf-root .monthly-table-details > .tbl-scroll { padding: 12px; }

/* hero grid: keep cards from stranding a lone orphan on a second row */
.perf-root .hero-grid { justify-content:start; }


/* ==============================================================================
   SECTION-SPECIFIC styles — migrated from the former inline <style> block in
   templates/performance.html (head-to-head, heatmap, scatter/overlay, race,
   distribution, strips, behavior, leaderboard, combo table, scrubber, grid
   cards, toolbar, responsive). ALL selectors scoped under .perf-root so they
   render identically on the standalone page AND inside the admin Performance
   "Report" tab without bleeding into the admin shell (.section/.badge/.card etc.
   are also used by admin.html — the .perf-root prefix keeps them isolated).
   ============================================================================== */
  /* NOTE: page-local tokens, base body/header/section primitives, #tip and the
     gradient-title rule now live in css/perf-page.css (linked in <head>).
     This inline block keeps the section-specific visual styles for the
     EXISTING populated sections (head-to-head, heatmap, scatter, overlay,
     leaderboard, combo table, behavior, scrubber, grid cards). */

  /* top KPI chips */
  .perf-root .chips { display:flex; flex-wrap:wrap; gap:12px; margin: 6px 0 22px; }
  .perf-root .chip { background: var(--bg-card); border:1px solid var(--border); border-radius:12px;
          padding:12px 16px; min-width:150px; }
  .perf-root .chip .k { font-size:.72rem; text-transform:uppercase; letter-spacing:.06em; color: var(--text-dim); }
  .perf-root .chip .v { font-size:1.4rem; font-weight:700; margin-top:3px; }
  .perf-root .chip .sm { font-size:.8rem; color:var(--text-dim); }

  /* badges — .chip geometry; overrides cascade from base block */
  .perf-root .badge {
    display: inline-flex; align-items: center; gap: var(--space-1, 4px);
    padding: 2px var(--space-2, 8px);
    border-radius: var(--radius-pill, 100px);
    font-size: var(--font-caption, 11px); font-weight: 600;
    line-height: 1.4; letter-spacing: .05em;
    text-transform: uppercase; white-space: nowrap;
  }
  .perf-root .badge.amber { background:var(--amber-tint); color:var(--amber); }
  .perf-root .badge.green { background:var(--green-tint); color:var(--green-ea); }
  .perf-root .badge.flag { background:var(--flag-tint); color:var(--flag); text-transform:none; letter-spacing:0; cursor:help; }
  .perf-root .swatch { width:10px; height:10px; border-radius:3px; display:inline-block; vertical-align:middle; }
  .perf-root .swatch.amber { background:var(--amber); } .perf-root .swatch.green { background:var(--green-ea); }

  /* ===== Amber vs Green head-to-head ===== */
  .perf-root .vs { display:grid; grid-template-columns: 1fr 64px 1fr; gap:0 14px; align-items:stretch; }
  .perf-root .vs .col { padding:4px 2px; }
  .perf-root .vs .colhead { display:flex; align-items:center; gap:9px; font-weight:700; font-size:1.05rem; margin-bottom:12px; }
  .perf-root .vs .colhead.r { justify-content:flex-end; }
  .perf-root .vs .mlabel { grid-column:1 / -1; text-align:center; font-size:.7rem; text-transform:uppercase; letter-spacing:.06em;
                color:var(--text-dim); }
  .perf-root .vs .mrow { display:flex; align-items:center; gap:8px; }
  .perf-root .vs .mrow.l { justify-content:flex-end; }
  .perf-root .vs .mval { font-size:1.15rem; font-weight:800; font-variant-numeric:tabular-nums; min-width:74px; }
  .perf-root .vs .mval.l { text-align:right; } .perf-root .vs .mval.r { text-align:left; }
  .perf-root .vs .mbar { flex:1; height:9px; background:var(--surface-1); border-radius:5px; overflow:hidden; display:flex; }
  .perf-root .vs .mbar.l { justify-content:flex-end; }
  .perf-root .vs .mbar i { display:block; height:100%; border-radius:5px; }
  .perf-root .vs .mbar.l i { background:var(--amber); } .perf-root .vs .mbar.r i { background:var(--green-ea); }
  .perf-root .vs .spine { display:flex; align-items:center; justify-content:center; }
  .perf-root .vs .spine span { writing-mode:vertical-rl; text-orientation:mixed; font-size:.62rem; letter-spacing:.18em;
                    color:var(--text-dim); text-transform:uppercase; transform:rotate(180deg); }
  .perf-root .vs .win { font-size:.6rem; font-weight:700; padding:1px 6px; border-radius:999px; background:var(--surface-1);
             color:var(--text-sub); }
  .perf-root .vs .win.on-l, .perf-root .vs .win.on-r { background:var(--profit-bg); color:var(--profit); }

  /* ===== Settings heatmap matrix ===== */
  .perf-root .matrix-grid { display:grid; gap:18px; grid-template-columns: repeat(auto-fit, minmax(250px,1fr)); }
  .perf-root .mblock h3 { font-size:.82rem; margin:0 0 4px; color:var(--text-sub); }
  .perf-root .mblock .sub { font-size:.7rem; color:var(--text-dim); margin:0 0 9px; }
  .perf-root .hrow { display:grid; grid-template-columns: 96px 1fr; align-items:center; gap:8px; margin-bottom:7px; }
  .perf-root .hrow .hlbl { font-size:.78rem; color:var(--text-sub); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .perf-root .hcell { position:relative; height:30px; border-radius:7px; display:flex; align-items:center; justify-content:space-between;
           padding:0 9px; font-size:.78rem; font-weight:700; font-variant-numeric:tabular-nums; border:1px solid transparent;
           color:var(--text-main); }
  .perf-root .hcell .n { font-size:.62rem; font-weight:600; opacity:.7; }
  .perf-root .hcell.best { outline:2px solid var(--accent); outline-offset:-2px; box-shadow:0 0 0 3px var(--accent-bg, transparent); }
  .perf-root .hcell.best::after { content:'BEST'; position:absolute; top:-7px; right:6px; font-size:.5rem; font-weight:800; letter-spacing:.05em;
                       color:var(--accent); background:var(--bg-card); padding:0 3px; border-radius:3px; }
  .perf-root .hcell.empty { background:var(--surface-1); color:var(--text-dim); }
  .perf-root .bestpill { display:inline-block; margin-left:7px; font-size:.6rem; font-weight:700; color:var(--accent); }

  /* ===== scatter ===== */
  .perf-root .scatter-wrap { position:relative; }
  /* Height is set in JS (sizeChart) to match the viewBox 1:1 (no distortion).
     min-height is just a pre-JS fallback so the box reserves space; it sits below
     the chart's design height so it never clamps the JS value into a letterbox. */
  .perf-root svg.scatter { width:100%; height:auto; display:block; min-height:300px; }
  .perf-root .scatter text { fill: var(--text-dim); font-size:11px; }
  .perf-root .scatter .axis { stroke: var(--border); stroke-width:1; }
  .perf-root .scatter .gridln { stroke: var(--border); stroke-width:1; stroke-dasharray:2 4; opacity:.5; }
  .perf-root .scatter .zeroln { stroke: var(--text-dim); stroke-width:1; stroke-dasharray:4 3; opacity:.7; }
  .perf-root .scatter circle { cursor:pointer; transition:r .1s; }
  .perf-root .scatter circle:hover { stroke:var(--hairline); stroke-width:1.5; }
  /* scatter / dist / race legend: minimum 11px per defect-3 fix */
  .perf-root .legend { display:flex; gap:16px; flex-wrap:wrap; font-size:var(--font-caption, 11px); color:var(--text-sub); margin-top:8px; }
  .perf-root .legend .li { display:flex; align-items:center; gap:6px; }

  /* ===== equity overlay ===== */
  .perf-root svg.overlay { width:100%; height:auto; display:block; min-height:300px; }
  .perf-root .overlay .axis { stroke: var(--border); stroke-width:1; }
  .perf-root .overlay .gridln { stroke: var(--border); stroke-width:1; stroke-dasharray:2 4; opacity:.45; }
  .perf-root .overlay .zeroln { stroke: var(--text-dim); stroke-width:1; stroke-dasharray:4 3; opacity:.7; }
  .perf-root .overlay text { fill: var(--text-dim); font-size:11px; }
  .perf-root .overlay path.curve { fill:none; stroke-width:1.5; opacity:.7; }
  .perf-root .overlay path.amber { stroke:var(--amber); } .perf-root .overlay path.green { stroke:var(--green-ea); }

  /* ===== overlay+scatter side-by-side ===== */
  .perf-root .so-cols { display:grid; grid-template-columns:1fr 1fr; gap:18px; align-items:start; }
  .perf-root .so-cols > .section { margin-bottom:0; }
  @media (max-width:980px){ .perf-root .so-cols {grid-template-columns:1fr;} }

  /* ===== leaderboard ===== */
  .perf-root .lb-cols { display:grid; grid-template-columns:1fr 1fr; gap:18px; }
  .perf-root .lb h3 { font-size:.82rem; margin:0 0 9px; color:var(--text-sub); }
  .perf-root .lb .row { display:grid; grid-template-columns:22px 1fr auto auto; align-items:center; gap:10px; padding:7px 9px; border-radius:9px;
             background:var(--surface-1); margin-bottom:6px; font-size:.84rem; }
  .perf-root .lb .rk { font-size:.74rem; color:var(--text-dim); font-weight:700; text-align:center; }
  .perf-root .lb .who { display:flex; align-items:center; gap:7px; min-width:0; }
  .perf-root .lb .who .cfg { font-size:.68rem; color:var(--text-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .perf-root .lb .v { font-weight:800; font-variant-numeric:tabular-nums; }

  /* toolbar */
  .perf-root .toolbar { display:flex; flex-wrap:wrap; gap:10px 14px; align-items:center; margin-bottom:16px; }
  .perf-root .toolbar .grp { display:flex; flex-direction:column; gap:4px; }
  .perf-root .toolbar .grp > .glbl { font-size:.66rem; text-transform:uppercase; letter-spacing:.05em; color:var(--text-dim); }
  .perf-root .toolbar .seg { display:flex; border:1px solid var(--border); border-radius:10px; overflow:hidden; }
  .perf-root .toolbar .seg button { background:transparent; color:var(--text-sub); border:0; padding:8px 14px; cursor:pointer; font-size:.85rem; transition:background .15s,color .15s; }
  /* toolbar segmented active: mirrors the root .seg button.active treatment */
  .perf-root .toolbar .seg button.active {
    background: var(--ds-accent-tint-strong, color-mix(in srgb, var(--accent) 18%, var(--surface-1)));
    color: var(--accent);
    font-weight: var(--fw-semi, 600);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
  }
  .perf-root .toolbar select { background: var(--bg-card); color:var(--text-main); border:1px solid var(--border);
                    border-radius:10px; padding:8px 12px; font-size:.85rem; }
  .perf-root .toolbar .spacer { flex:1; }
  .perf-root .toolbar .toggle { display:inline-flex; align-items:center; gap:7px; cursor:pointer; font-size:.82rem; color:var(--text-sub);
                     border:1px solid var(--border); border-radius:10px; padding:7px 12px; user-select:none; }
  .perf-root .toolbar .toggle input { accent-color:var(--accent); width:15px; height:15px; }
  .perf-root .toolbar .toggle.on { border-color:var(--accent); color:var(--text-main); }

  /* ranked bars */
  .perf-root .barrow { display:grid; grid-template-columns: 200px 1fr 70px; align-items:center; gap:10px; padding:3px 0; font-size:.8rem; }
  .perf-root .barrow .lbl { color:var(--text-sub); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .perf-root .bartrack { position:relative; height:14px; background:var(--surface-1); border-radius:7px; }
  .perf-root .barfill { position:absolute; top:0; bottom:0; border-radius:7px; min-width:2px; }
  .perf-root .barfill.pos { background: var(--profit); }
  .perf-root .barfill.neg { background: var(--loss); }
  .perf-root .barrow .val { text-align:right; font-variant-numeric:tabular-nums; font-weight:600; }
  .perf-root .midline { position:absolute; left:50%; top:-3px; bottom:-3px; width:1px; background:var(--border); }

  /* grid cards */
  .perf-root .grid { display:grid; grid-template-columns: repeat(auto-fill, minmax(290px,1fr)); gap:16px; }
  .perf-root .card { background:var(--bg-card); border:1px solid var(--border); border-radius:16px; padding:15px 15px 13px; position:relative; transition:border-color .15s, transform .15s; }
  .perf-root .card:hover { border-color: var(--accent); transform: translateY(-2px); }
  .perf-root .card.flagged { border-color: var(--flag); }
  .perf-root .card .top { display:flex; justify-content:space-between; align-items:flex-start; gap:8px; flex-wrap:wrap; }
  .perf-root .card .top .ids { display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
  .perf-root .card .cfg { font-size:.74rem; color:var(--text-dim); margin-top:8px; }
  .perf-root .card .cfg b { color:var(--text-sub); font-weight:600; }
  .perf-root .card .ret { font-size:1.85rem; font-weight:800; letter-spacing:-.02em; margin:8px 0 2px; font-variant-numeric:tabular-nums; }
  .perf-root .card .retsub { font-size:.76rem; color:var(--text-dim); }
  .perf-root .pos { color: var(--profit); } .perf-root .neg { color: var(--loss); } .perf-root .flat { color: var(--text-sub); }
  .perf-root .spark { width:100%; height:38px; margin:9px 0 6px; display:block; }
  /* inline mini sparkline — one consistent style everywhere (leaderboard rows,
     combo-table column). Fixed 90×24 box, vertically centred, crisp on retina
     via viewBox. Empty placeholder = a faint centred dash. */
  .perf-root .ispark { display:inline-block; vertical-align:middle; width:90px; height:24px; flex:none; }
  .perf-root .ispark.wide { width:90px; height:24px; }
  .perf-root .ispark.empty-dash { position:relative; }
  .perf-root .ispark.empty-dash::before { content:''; position:absolute; left:50%; top:50%; width:14px; height:1.5px;
                               transform:translate(-50%,-50%); background:var(--text-dim); opacity:.45; border-radius:1px; }
  /* subtle value-change pulse when numbers refresh */
  @keyframes valPulse { 0% { background:var(--accent-bg, var(--surface-1)); } 100% { background:transparent; } }
  .perf-root .val-anim { animation: valPulse .6s ease-out; border-radius:5px; }
  @media (prefers-reduced-motion: reduce){ .perf-root .val-anim { animation:none; } }
  .perf-root .ministats { display:grid; grid-template-columns: repeat(3,1fr); gap:8px 6px; margin-top:8px; }
  .perf-root .ministats .ms { background:var(--surface-1); border-radius:8px; padding:7px 8px; }
  .perf-root .ministats .ms .k { font-size:.64rem; text-transform:uppercase; letter-spacing:.04em; color:var(--text-dim); }
  .perf-root .ministats .ms .v { font-size:.92rem; font-weight:700; font-variant-numeric:tabular-nums; margin-top:1px; }
  /* secondary metrics row (Peak DD / Peak Margin / Return EUR / EUR-trade / Eff.Bal / Vault) */
  .perf-root .metrics2 { display:grid; grid-template-columns: repeat(3,1fr); gap:6px; margin-top:7px; }
  .perf-root .metrics2 .m2 { border:1px solid var(--border-subtle); border-radius:8px; padding:6px 8px; }
  .perf-root .metrics2 .m2 .k { font-size:.6rem; text-transform:uppercase; letter-spacing:.03em; color:var(--text-dim); }
  .perf-root .metrics2 .m2 .v { font-size:.82rem; font-weight:700; font-variant-numeric:tabular-nums; margin-top:1px; }
  .perf-root .hb { font-size:.66rem; margin-top:9px; display:flex; align-items:center; gap:6px; color:var(--text-dim); flex-wrap:wrap; }
  .perf-root .dot { width:7px; height:7px; border-radius:50%; background:var(--text-dim); }
  .perf-root .dot.live { background: var(--profit); box-shadow:0 0 0 3px var(--profit-bg); }
  .perf-root .dot.stale { background: var(--loss); }
  .perf-root .empty { text-align:center; padding:60px 20px; color:var(--text-dim); }
  .perf-root .nodata { font-size:.78rem; color:var(--text-dim); padding:14px 2px; }
  .perf-root .footnote { margin-top:30px; font-size:.74rem; color:var(--text-dim); line-height:1.6; }
  .perf-root .footnote .flagnote { color:var(--flag); }

  /* tooltip (#tip) styles live in perf-page.css */

  /* ===== settings-combo table ===== */
  .perf-root .combo-fam { margin-bottom:22px; }
  .perf-root .combo-fam:last-child { margin-bottom:0; }
  .perf-root .combo-fam > h3 { font-size:.86rem; margin:0 0 9px; color:var(--text-sub); display:flex; align-items:center; gap:8px; }
  .perf-root .combo-scroll { overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .perf-root table.combo { width:100%; border-collapse:separate; border-spacing:0; font-size:.82rem; font-variant-numeric:tabular-nums; min-width:560px; }
  .perf-root table.combo th, .perf-root table.combo td { padding:7px 12px; white-space:nowrap; vertical-align:middle; }
  /* consistent column-alignment discipline: config left, numbers right (tabular),
     trend a fixed-width centred sparkline cell. Header alignment mirrors the body. */
  .perf-root table.combo th.col-cfg, .perf-root table.combo td.col-cfg { text-align:left; }
  .perf-root table.combo th.col-num, .perf-root table.combo td.col-num { text-align:right; font-variant-numeric:tabular-nums; }
  .perf-root table.combo th.col-trend, .perf-root table.combo td.col-trend { text-align:center; width:104px; min-width:104px; padding-left:8px; padding-right:8px; }
  .perf-root table.combo td.col-trend .ispark { vertical-align:middle; }
  .perf-root table.combo th.nosort { cursor:default; }
  .perf-root table.combo th.nosort:hover { color:var(--text-dim); }
  /* sticky first column so the config label stays visible while scrolling wide tables */
  .perf-root table.combo th:first-child, .perf-root table.combo td:first-child {
    position:sticky; left:0; z-index:1; background:var(--bg-card);
  }
  .perf-root table.combo thead th:first-child { z-index:2; }
  .perf-root table.combo tbody tr.best td:first-child { background:var(--accent-bg, var(--surface-1)); }
  .perf-root table.combo thead th { font-size:.66rem; text-transform:uppercase; letter-spacing:.05em; color:var(--text-dim);
                         border-bottom:1px solid var(--border); cursor:pointer; user-select:none; font-weight:700; }
  .perf-root table.combo thead th:hover { color:var(--text-main); }
  .perf-root table.combo thead th .arr { font-size:.62rem; opacity:.7; margin-left:2px; }
  .perf-root table.combo tbody td { border-bottom:1px solid var(--border-subtle); }
  .perf-root table.combo tbody tr:last-child td { border-bottom:0; }
  .perf-root table.combo tbody tr.best { background:var(--accent-bg, var(--surface-1)); box-shadow:inset 3px 0 0 var(--accent); }
  .perf-root table.combo tbody tr.best td { font-weight:700; }
  .perf-root table.combo tbody tr.best td:first-child { color:var(--text-main); }
  .perf-root table.combo td.cfgcell { color:var(--text-sub); }
  .perf-root table.combo .bestpill { display:inline-block; font-size:.55rem; font-weight:800; letter-spacing:.04em; color:var(--accent);
                          background:var(--accent-bg, var(--surface-1)); border:1px solid var(--accent); border-radius:4px;
                          padding:0 5px; margin-left:7px; vertical-align:middle; }

  /* Real-money (live broker) account marker — distinguishes the 2 live
     customer accounts from the demonstration fleet on the public table. */
  /* .livemoneypill — .chip geometry + green-ea semantic color */
  .perf-root .livemoneypill { display:inline-flex; align-items:center; font-size:var(--font-caption,11px); font-weight:700; letter-spacing:.04em;
                          color:var(--green-ea); background:var(--green-tint); border:1px solid color-mix(in srgb, var(--green-ea) 45%, transparent);
                          border-radius:var(--radius-pill,100px); padding:2px var(--space-2,8px); margin-left:5px; vertical-align:middle; white-space:nowrap; }

  /* ===== time-range + actions ===== */
  .perf-root .toolbar .seg.compact button { padding:7px 11px; font-size:.82rem; }
  .perf-root .toolbar .btn { display:inline-flex; align-items:center; gap:7px; background:var(--bg-card); color:var(--text-sub);
                  border:1px solid var(--border); border-radius:10px; padding:8px 13px; cursor:pointer; font-size:.82rem;
                  font-weight:600; line-height:1; transition:border-color .15s,color .15s; white-space:nowrap; }
  .perf-root .toolbar .btn:hover { border-color:var(--accent); color:var(--text-main); }
  .perf-root .refresh-cd { display:inline-flex; align-items:center; gap:7px; font-size:.74rem; color:var(--text-dim); white-space:nowrap; }
  .perf-root .data-as-of { font-size:.72rem; color:var(--text-dim); white-space:nowrap; margin-left:10px; opacity:.85; }
  .perf-root .refresh-cd .ring { width:13px; height:13px; transform:rotate(-90deg); }
  .perf-root .refresh-cd .ring circle { fill:none; stroke-width:2.5; }
  .perf-root .refresh-cd .ring .track { stroke:var(--border); }
  .perf-root .refresh-cd .ring .prog { stroke:var(--accent); stroke-linecap:round; transition:stroke-dashoffset 1s linear; }

  /* ===================== responsive (fluid breakpoints) ===================== */
  /* large desktop → tablet-landscape: tighten outer padding, relax fixed col */
  @media (max-width:1400px){
    /* `.perf-root .wrap{max-width:1200px}` removed 2026-07-17 — duplicate of the
       rule in the first responsive section; both recreated the gutter inversion.
       The 1320px base ceiling governs this range now. */
    .perf-root .barrow { grid-template-columns:180px 1fr 70px; }
  }
  @media (max-width:1100px){
    /* horizontal gutter stays on the base clamp — see the note in the first
       responsive section. Only vertical rhythm tightens. */
    .perf-root .wrap { padding:24px clamp(16px, 4vw, 48px) 70px; }
    .perf-root header.page h1 { font-size:1.55rem; }
    .perf-root .so-cols { grid-template-columns:1fr; }            /* scatter + overlay stack */
    .perf-root .lb-cols { grid-template-columns:1fr; }            /* leaderboard stacks */
    .perf-root .barrow { grid-template-columns:160px 1fr 64px; }
  }
  /* tablet-portrait */
  @media (max-width:900px){
    .perf-root header.page h1 { font-size:1.45rem; }
    .perf-root header.page .sub { font-size:.86rem; }
    .perf-root .matrix-grid { grid-template-columns:1fr 1fr; }
    .perf-root .ministats { grid-template-columns:repeat(3,1fr); }
    .perf-root .metrics2 { grid-template-columns:repeat(3,1fr); }
    .perf-root .chips { gap:8px; } .perf-root .chip { min-width:0; flex:1 1 calc(33.333% - 8px); }
    .perf-root .chip .v { font-size:1.25rem; }
  }
  /* phablet / small tablet */
  @media (max-width:700px){
    /* horizontal gutter stays on the base clamp (floors at 16px) — a fixed
       12px here stepped the gutter DOWN below 700px. */
    .perf-root .wrap { padding:20px clamp(16px, 4vw, 48px) 64px; }
    .perf-root header.page h1 { font-size:1.35rem; }
    .perf-root .matrix-grid { grid-template-columns:1fr; }
    .perf-root .ministats { grid-template-columns:repeat(2,1fr); }
    .perf-root .metrics2 { grid-template-columns:repeat(2,1fr); }
    .perf-root .chips { gap:8px; } .perf-root .chip { flex:1 1 calc(50% - 8px); padding:10px 13px; }
    .perf-root .toolbar { gap:8px 10px; } .perf-root .toolbar select { padding:7px 9px; font-size:.8rem; }
    .perf-root .barrow { grid-template-columns:120px 1fr 56px; }
    .perf-root .section { padding:16px 14px; }
    /* head-to-head: stack vertically (Amber over Green), one metric block at a time */
    .perf-root .vs { display:flex; flex-direction:column; gap:0; }
    .perf-root .vs .col { width:100%; padding:2px 0; }
    .perf-root .vs .colhead { font-size:1rem; }
    .perf-root .vs .colhead.r { justify-content:flex-start; }     /* left-align green header when stacked */
    .perf-root .vs .spine { width:100%; justify-content:flex-start; padding:8px 0 2px; }
    .perf-root .vs .spine span { writing-mode:initial !important; text-orientation:initial !important; transform:none !important;
                     letter-spacing:.05em; font-size:.62rem; font-weight:700; }
    .perf-root .vs .mrow.l { justify-content:flex-start; }         /* amber row: bar grows L→R like green */
    .perf-root .vs .mval.l { text-align:left; }
    .perf-root .vs .mbar.l { justify-content:flex-start; }
    .perf-root .vs .mbar.l i { margin-left:0; }
    .perf-root .vs .mrow { margin-bottom:8px !important; }
  }
  /* phones */
  @media (max-width:480px){
    .perf-root header.page h1 { font-size:1.3rem; }
    .perf-root .grid { grid-template-columns:1fr; }
    .perf-root .chip { flex:1 1 100%; }
    .perf-root .chip .v { font-size:1.4rem; }
    .perf-root .card .ret { font-size:1.6rem; }
    .perf-root .ministats { grid-template-columns:repeat(2,1fr); }
    .perf-root .barrow { grid-template-columns:100px 1fr 52px; font-size:.74rem; }
    .perf-root .lb .row { grid-template-columns:20px 1fr auto auto; gap:8px; }
    /* keep sparklines crisp but a touch narrower on phones (still fixed box) */
    .perf-root .ispark, .perf-root .ispark.wide { width:64px; }
    /* hide the combo-table Trend column under 480px rather than break the layout */
    .perf-root table.combo th.col-trend, .perf-root table.combo td.col-trend { display:none; }
  }

  /* ===================== timeline scrubber ===================== */
  .perf-root .scrubber { display:flex; align-items:center; gap:14px; background:var(--bg-card); border:1px solid var(--border);
              border-radius:14px; padding:12px 16px; margin:0 0 18px; }
  .perf-root .scrubber.viewing { border-color:var(--accent); box-shadow:0 0 0 1px var(--accent); }
  .perf-root .scrubber .sc-ico { flex:none; color:var(--text-dim); display:flex; }
  .perf-root .scrubber .sc-body { flex:1; min-width:0; }
  .perf-root .scrubber .sc-row { display:flex; align-items:center; gap:12px; }
  .perf-root .scrubber .sc-lbl { font-size:.7rem; text-transform:uppercase; letter-spacing:.06em; color:var(--text-dim); white-space:nowrap; }
  .perf-root .scrubber input[type=range] { -webkit-appearance:none; appearance:none; flex:1; height:5px; border-radius:5px;
            background:var(--surface-1); outline:none; cursor:pointer; min-width:80px; }
  .perf-root .scrubber input[type=range]::-webkit-slider-thumb { -webkit-appearance:none; appearance:none; width:16px; height:16px;
            border-radius:50%; background:var(--accent); border:2px solid var(--bg-card); box-shadow:0 1px 3px var(--shadow-color); cursor:pointer; }
  .perf-root .scrubber input[type=range]::-moz-range-thumb { width:16px; height:16px; border-radius:50%; background:var(--accent);
            border:2px solid var(--bg-card); cursor:pointer; }
  .perf-root .scrubber input[type=range]:disabled { opacity:.5; cursor:not-allowed; }
  .perf-root .scrubber .sc-time { font-size:.78rem; font-variant-numeric:tabular-nums; color:var(--text-sub); white-space:nowrap; min-width:120px; text-align:right; }
  .perf-root .scrubber .sc-badge { display:inline-flex; align-items:center; gap:6px; font-size:.7rem; font-weight:700; letter-spacing:.03em;
            padding:4px 10px; border-radius:999px; background:var(--accent-bg, var(--surface-1)); color:var(--accent); white-space:nowrap; }
  .perf-root .scrubber .sc-live { display:inline-flex; align-items:center; gap:6px; background:transparent; color:var(--text-sub);
            border:1px solid var(--border); border-radius:10px; padding:6px 12px; cursor:pointer; font-size:.78rem; font-weight:600;
            white-space:nowrap; transition:border-color .15s,color .15s; }
  .perf-root .scrubber .sc-live:hover { border-color:var(--accent); color:var(--text-main); }
  .perf-root .scrubber .sc-live[disabled] { opacity:.45; cursor:default; }
  .perf-root .scrubber .sc-live .dot { width:7px; height:7px; border-radius:50%; background:var(--profit); box-shadow:0 0 0 3px var(--profit-bg); }
  .perf-root .scrubber .sc-empty { font-size:.76rem; color:var(--text-dim); }
  @media (max-width:700px){
    .perf-root .scrubber { flex-wrap:wrap; gap:10px; }
    .perf-root .scrubber .sc-time { min-width:0; text-align:left; }
    .perf-root .scrubber .sc-body { flex:1 1 100%; order:3; }
  }

  /* ===================== analysis: cumulative P/L race ===================== */
  .perf-root svg.race { width:100%; height:auto; display:block; min-height:300px; }
  .perf-root .race .axis { stroke:var(--border); stroke-width:1; }
  .perf-root .race .gridln { stroke:var(--border); stroke-width:1; stroke-dasharray:2 4; opacity:.45; }
  .perf-root .race .zeroln { stroke:var(--text-dim); stroke-width:1; stroke-dasharray:4 3; opacity:.7; }
  .perf-root .race text { fill:var(--text-dim); font-size:11px; }
  .perf-root .race path.rl { fill:none; stroke-width:1.4; opacity:.6; }
  .perf-root .race path.rl.amber { stroke:var(--amber); } .perf-root .race path.rl.green { stroke:var(--green-ea); }
  .perf-root .race path.rl.leader { stroke-width:2.6; opacity:1; }
  .perf-root .race .leadlbl { font-size:11px; font-weight:700; }

  /* ===================== analysis: return distribution ===================== */
  .perf-root svg.dist { width:100%; height:auto; display:block; min-height:300px; }
  .perf-root .dist .axis { stroke:var(--border); stroke-width:1; }
  .perf-root .dist .gridln { stroke:var(--border); stroke-width:1; stroke-dasharray:2 4; opacity:.4; }
  .perf-root .dist .zeroln { stroke:var(--text-dim); stroke-width:1; stroke-dasharray:4 3; opacity:.7; }
  .perf-root .dist text { fill:var(--text-dim); font-size:11px; }
  /* fill-opacity is generic so a family without its own rule below (Iris, or
     any future one) still matches the others. The per-family `fill` rules must
     stay: a CSS declaration BEATS the inline fill="" presentation attribute the
     renderer emits, so without a .bar-iris rule Iris would take its colour from
     the attribute but miss the opacity and render solid beside 50% bars. */
  .perf-root .dist rect[class^="bar-"] { fill-opacity:.5; }
  .perf-root .dist rect.bar-amber { fill:var(--amber); }
  .perf-root .dist rect.bar-green { fill:var(--green-ea); }
  .perf-root .dist rect.bar-iris { fill:var(--iris-ea); }

  /* ===================== analysis: per-dimension strips ===================== */
  .perf-root .strips { display:grid; gap:16px; grid-template-columns:1fr; }
  /* Big screens: 2-col so each strip is ~690px (denser dots, ~3.3:1) instead of
     a single ~1406px-wide flat band (6.5–8.7:1). Single column below 1100px. */
  @media (min-width:1100px){ .perf-root .strips { grid-template-columns: repeat(2, 1fr); } }
  .perf-root .strip-block h3 { font-size:.82rem; margin:0 0 8px; color:var(--text-sub); }
  .perf-root svg.strip { width:100%; height:auto; display:block; }
  .perf-root .strip .axis { stroke:var(--border); stroke-width:1; }
  .perf-root .strip .rowln { stroke:var(--border); stroke-width:1; stroke-dasharray:2 4; opacity:.4; }
  .perf-root .strip .zeroln { stroke:var(--text-dim); stroke-width:1; stroke-dasharray:4 3; opacity:.6; }
  .perf-root .strip text { fill:var(--text-dim); font-size:11px; }
  .perf-root .strip text.rowlbl { fill:var(--text-sub); font-size:11px; }
  .perf-root .strip circle { cursor:pointer; }
  .perf-root .strip circle:hover { stroke:var(--hairline); stroke-width:1.5; }
  .perf-root .ana-cols { display:grid; grid-template-columns:1fr 1fr; gap:18px; align-items:start; }
  .perf-root .ana-cols > .section { margin-bottom:0; }
  @media (max-width:980px){ .perf-root .ana-cols { grid-template-columns:1fr; } }

/* Defect 4c: within-setting strip dots are tiny on phones because the SVG
   height collapses. Enforce a minimum container height so the viewBox has
   room to render legible dots (SVG uses xMidYMid meet, so min-height floors it). */
@media (max-width:480px) {
  .perf-root .strip-block { min-height:0; }
  .perf-root svg.strip { min-height:120px; }
}

  /* ===================== trading behavior ===================== */
  /* two-up grid of behavior cards; stacks under 900px per spec */
  .perf-root .beh-grid { display:grid; grid-template-columns:1fr 1fr; gap:18px; align-items:start; }
  .perf-root .beh-grid > .beh-card { margin:0; }
  .perf-root .beh-card { background:var(--bg-card); border:1px solid var(--border); border-radius:14px; padding:16px 16px 14px; }
  .perf-root .beh-card h3 { font-size:.9rem; margin:0 0 3px; display:flex; align-items:center; gap:8px; }
  .perf-root .beh-card .bh { font-size:.72rem; color:var(--text-dim); margin:0 0 12px; }
  .perf-root .beh-card .nodata { padding:24px 4px; text-align:center; }
  @media (max-width:900px){ .perf-root .beh-grid { grid-template-columns:1fr; } }

  /* legend reused inside behavior cards — minimum 11px for legibility */
  .perf-root .beh-legend { display:flex; gap:14px; flex-wrap:wrap; font-size:var(--font-caption, 11px); color:var(--text-sub); margin-top:10px; }
  .perf-root .beh-legend .li { display:flex; align-items:center; gap:6px; }

  /* (a) duration profile — paired horizontal bars per bucket */
  .perf-root .durp { display:flex; flex-direction:column; gap:11px; }
  .perf-root .durp .row { display:grid; grid-template-columns:64px 1fr; align-items:center; gap:10px; }
  .perf-root .durp .blbl { font-size:.76rem; color:var(--text-sub); font-variant-numeric:tabular-nums; white-space:nowrap; }
  .perf-root .durp .pair { display:flex; flex-direction:column; gap:5px; }
  .perf-root .durp .pbar { display:flex; align-items:center; gap:8px; }
  .perf-root .durp .ptrack { position:relative; flex:1; height:14px; background:var(--surface-1); border-radius:7px; overflow:hidden; }
  .perf-root .durp .pfill { position:absolute; left:0; top:0; bottom:0; border-radius:7px; min-width:2px; }
  .perf-root .durp .pfill.amber { background:var(--amber); } .perf-root .durp .pfill.green { background:var(--green-ea); }
  /* avg-P/L tint dot sits at the end of each bar */
  .perf-root .durp .pmeta { font-size:.7rem; color:var(--text-dim); font-variant-numeric:tabular-nums; white-space:nowrap; min-width:96px; text-align:right; }
  .perf-root .durp .pmeta .sw { width:8px; height:8px; border-radius:2px; display:inline-block; vertical-align:middle; margin-right:4px; }

  /* (b) activity clock — overlaid 24-bin bars */
  .perf-root svg.clock { width:100%; height:auto; display:block; }
  .perf-root .clock .axis { stroke:var(--border); stroke-width:1; }
  .perf-root .clock .gridln { stroke:var(--border); stroke-width:1; stroke-dasharray:2 4; opacity:.4; }
  .perf-root .clock text { fill:var(--text-dim); font-size:10px; }
  .perf-root .clock rect.c-amber { fill:var(--amber); fill-opacity:.62; }
  .perf-root .clock rect.c-green { fill:var(--green-ea); fill-opacity:.62; }

  /* (c) win/loss profile — paired bars + max markers */
  .perf-root .wlp { display:flex; flex-direction:column; gap:16px; }
  .perf-root .wlp .fam { }
  .perf-root .wlp .famhd { display:flex; align-items:center; gap:8px; font-size:.78rem; font-weight:700; margin-bottom:8px; color:var(--text-sub); }
  .perf-root .wlp .famhd .ct { font-size:.68rem; color:var(--text-dim); font-weight:600; margin-left:auto; }
  .perf-root .wlp .wrow { display:grid; grid-template-columns:58px 1fr 88px; align-items:center; gap:9px; margin-bottom:7px; }
  .perf-root .wlp .wlbl { font-size:.72rem; color:var(--text-dim); white-space:nowrap; }
  .perf-root .wlp .wtrack { position:relative; height:15px; background:var(--surface-1); border-radius:7px; }
  .perf-root .wlp .wfill { position:absolute; top:0; bottom:0; border-radius:7px; min-width:2px; }
  .perf-root .wlp .wfill.win { background:var(--profit); left:0; } .perf-root .wlp .wfill.loss { background:var(--loss); left:0; }
  /* max marker = a thin contrasting tick at the max-magnitude position */
  .perf-root .wlp .wmark { position:absolute; top:-2px; bottom:-2px; width:2px; background:var(--text-main); opacity:.55; border-radius:2px; }
  .perf-root .wlp .wval { font-size:.74rem; font-variant-numeric:tabular-nums; text-align:right; }

  /* (d) per-symbol signed bars */
  .perf-root .sympl { display:flex; flex-direction:column; gap:7px; }
  .perf-root .sympl .srow { display:grid; grid-template-columns:96px 1fr 84px; align-items:center; gap:9px; font-size:.78rem; }
  .perf-root .sympl .slbl { color:var(--text-sub); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:flex; align-items:center; gap:6px; }
  .perf-root .sympl .strack { position:relative; height:15px; background:var(--surface-1); border-radius:7px; }
  .perf-root .sympl .smid { position:absolute; left:50%; top:-3px; bottom:-3px; width:1px; background:var(--border); }
  .perf-root .sympl .sfill { position:absolute; top:0; bottom:0; border-radius:7px; min-width:2px; }
  .perf-root .sympl .sfill.amber { background:var(--amber); } .perf-root .sympl .sfill.green { background:var(--green-ea); }
  .perf-root .sympl .sval { text-align:right; font-variant-numeric:tabular-nums; font-weight:600; }
  @media (max-width:480px){
    .perf-root .durp .row { grid-template-columns:54px 1fr; }
    .perf-root .wlp .wrow { grid-template-columns:48px 1fr 74px; }
    .perf-root .sympl .srow { grid-template-columns:78px 1fr 70px; }
  }

  /* combo: low-sample greying of the risk-adjusted score */
  .perf-root table.combo td.col-num.lowsample { color:var(--text-dim); opacity:.6; }
  .perf-root .combo-tag { display:inline-block; font-size:.55rem; font-weight:700; letter-spacing:.03em; color:var(--text-dim);
               background:var(--surface-1); border:1px solid var(--border); border-radius:4px; padding:0 5px; margin-left:6px;
               vertical-align:middle; text-transform:uppercase; }

/* ================================================================
   2026-06-08 — DENSITY / COMPACTION PASS + sticky section nav
   Keeps the full window width but tightens vertical rhythm so the
   page is markedly shorter and easier to scan. `.perf-root.compact`
   (density toggle) squeezes it further on demand.
   ================================================================ */
.perf-root .wrap { padding-bottom: 40px; }
.perf-root .section { padding: 13px 16px; margin-bottom: 12px; }
.perf-root .section > h2 { font-size: 1rem; }
.perf-root .section > .hint { margin-bottom: 9px; font-size: .75rem; }
.perf-root .hero-grid { gap: 10px; margin: 4px 0 12px; grid-template-columns: repeat(auto-fit, minmax(158px,1fr)); }
.perf-root .hcard { padding: 12px 13px; }
.perf-root .comp-grid { gap: 12px; }
.perf-root .risk-grid, .perf-root .health-grid { gap: 10px; }
.perf-root .riskcard { padding: 11px 13px; }
.perf-root .healthcard { padding: 11px 13px; }
.perf-root table.perf th, .perf-root table.perf td { padding: 5px 10px; }
.perf-root .method { margin-top: 18px; padding: 15px 18px; }

/* per-account card grid — denser, more per row, sparkline kept */
.perf-root .grid { grid-template-columns: repeat(auto-fill, minmax(232px,1fr)); gap: 11px; }
.perf-root .card { padding: 11px 12px 10px; border-radius: 13px; }
.perf-root .card .ret { font-size: 1.4rem; margin: 5px 0 1px; }
.perf-root .card .cfg { margin-top: 6px; }
.perf-root .ministats { gap: 6px 5px; margin-top: 7px; }
.perf-root .ministats .ms { padding: 5px 7px; }

/* sticky section nav + density toggle */
.perf-root .perf-nav { position: sticky; top: 0; z-index: 40; display: flex; align-items: center;
  justify-content: space-between; gap: 10px; flex-wrap: wrap;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
  padding: 6px 8px; margin: 0 0 14px; box-shadow: 0 4px 16px var(--shadow-color); }
.perf-root .perf-nav-links { display: flex; flex-wrap: wrap; gap: 2px; min-width: 0; overflow-x: auto; }
.perf-root .perf-nav-links .pnl { font-size: .78rem; font-weight: 600; color: var(--text-sub);
  text-decoration: none; padding: 5px 11px; border-radius: 8px; white-space: nowrap;
  transition: background .15s, color .15s; }
.perf-root .perf-nav-links .pnl:hover { color: var(--text-main); background: var(--surface-1); }
.perf-root .perf-nav-links .pnl.active { color: var(--accent); background: var(--profit-bg); }
.perf-root .perf-density-toggle { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  flex: none; font-size: .76rem; font-weight: 600; color: var(--text-sub); background: var(--surface-1);
  border: 1px solid var(--border); border-radius: 8px; padding: 5px 10px; }
.perf-root .perf-density-toggle:hover { color: var(--text-main); border-color: var(--accent); }
.perf-root .perf-density-toggle[aria-pressed="true"] { color: var(--accent); border-color: var(--accent); background: var(--profit-bg); }
html { scroll-behavior: smooth; }
/* offset anchored scroll so the sticky bar never covers a section title */
.perf-root .section, .perf-root #top, .perf-root .grid { scroll-margin-top: 60px; }

/* ===================== C2/I1 — stack sticky nav UNDER the standalone header =====
   On the public standalone page a sticky .perf-site-header now sits at top:0, so
   the sticky section nav must stick BELOW it (not overlap). Inside the admin tab
   there is no .perf-standalone header, so .perf-nav keeps top:0 (unchanged). The
   anchored-scroll offset is bumped to clear both bars. ~44px header height. */
body.perf-standalone .perf-root .perf-nav { top: 48px; }
body.perf-standalone .perf-root .section,
body.perf-standalone .perf-root #top,
body.perf-standalone .perf-root .grid { scroll-margin-top: 108px; }

/* I1 — keep the PRIMARY in-page nav reachable on mobile without scrolling up.
   The section jump-nav (.perf-nav) is already sticky; the deep-dive TAB STRIP
   (.perf-tabs) was static, so switching tabs on a phone meant scrolling back to
   it. Make the tab strip sticky on phones/small tablets too, parked just under
   the sticky section nav. Kept compact (single row, horizontal-scroll) so it
   doesn't eat vertical space. Standalone page only (admin tab unaffected). */
@media (max-width: 700px) {
  body.perf-standalone .perf-root .perf-nav { top: 44px; }
  body.perf-standalone .perf-root .perf-tabs {
    position: sticky;
    /* sit below the standalone header (~44px) + the section nav row.
       The nav can wrap on phones; this keeps the tab strip visible while
       scrolling through a tab's content. */
    top: 44px;
    z-index: 38;
    background: var(--bg-main);
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin-left: -12px; margin-right: -12px;
    padding-left: 12px; padding-right: 12px;
  }
  body.perf-standalone .perf-root .section,
  body.perf-standalone .perf-root #top,
  body.perf-standalone .perf-root .grid { scroll-margin-top: 104px; }
}

/* ---- COMPACT density mode (toggle) ---- */
.perf-root.compact .section { padding: 9px 13px; margin-bottom: 8px; }
.perf-root.compact .section > .hint { display: none; }
.perf-root.compact .hero-grid { gap: 8px; margin: 2px 0 8px; }
.perf-root.compact .hcard { padding: 9px 11px; }
.perf-root.compact .grid { grid-template-columns: repeat(auto-fill, minmax(206px,1fr)); gap: 8px; }
.perf-root.compact .card { padding: 9px 10px 8px; }
.perf-root.compact .card .ret { font-size: 1.2rem; }
.perf-root.compact .card .metrics2 { display: none; }
.perf-root.compact table.perf th, .perf-root.compact table.perf td { padding: 3px 8px; font-size: .78rem; }

/* live open-trades by project (Amber / Green) — full-width row under health cards */
.perf-root .proj-trades { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px 16px; margin-top: 4px; padding: 10px 13px; border-radius: 11px;
  background: var(--surface-1); border: 1px solid var(--border-subtle); }
.perf-root .proj-trades .ptl { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em;
  font-weight: 700; color: var(--text-dim); margin-right: 2px; }
.perf-root .proj-trades .pt { display: inline-flex; align-items: center; gap: 6px;
  font-size: .82rem; font-weight: 600; color: var(--text-sub); }
.perf-root .proj-trades .pt b { font-size: .95rem; color: var(--text-main); font-variant-numeric: tabular-nums; }
.perf-root .proj-trades .pt .dot { width: 9px; height: 9px; border-radius: 50%; }
.perf-root .proj-trades .pt.amber .dot { background: var(--amber); }
.perf-root .proj-trades .pt.green .dot { background: var(--profit); }
.perf-root .proj-trades .pt .sub { font-size: .68rem; font-weight: 600; color: var(--text-dim); }

/* ===== per-project (Amber/Green) summary strip ===== */
.perf-root .proj-strip { display:grid; grid-template-columns:1fr 1fr; gap:11px; margin:0 0 12px; }
@media (max-width:640px){ .perf-root .proj-strip { grid-template-columns:1fr; } }
.perf-root .ps-card { border:1px solid var(--border); border-radius:13px; padding:12px 14px; background:var(--bg-card); }
.perf-root .ps-card.amber { border-left:3px solid var(--amber); }
.perf-root .ps-card.green { border-left:3px solid var(--profit); }
/* IRIS (CEO 2026-07-17: the page now compares Multi-market vs Iris). Only
   .amber/.green existed, so an Iris card rendered with no left rule and no dot
   — the one card the comparison is FOR would have been the only unstyled one.
   .unknown is the neutral fallback for a family the client doesn't know: it must
   look plainly foreign rather than borrow another family's identity. */
.perf-root .ps-card.iris { border-left:3px solid var(--iris-ea); }
.perf-root .ps-card.unknown { border-left:3px dashed var(--ps-unknown, #8b93a7); }
.perf-root .ps-head { display:flex; align-items:center; gap:7px; font-weight:700; font-size:.9rem; color:var(--text-main); margin-bottom:9px; }
.perf-root .ps-head .ps-n { margin-left:auto; font-size:.68rem; font-weight:600; color:var(--text-dim); }
.perf-root .ps-head .ps-title { font-weight:700; }
.perf-root .ps-head .ps-online { color:var(--profit); font-weight:700; }
.perf-root .ps-head .ps-online.warn { color:var(--loss); }
.perf-root .ps-card.amber .ps-dot { width:9px; height:9px; border-radius:50%; background:var(--amber); }
.perf-root .ps-card.green .ps-dot { width:9px; height:9px; border-radius:50%; background:var(--profit); }
.perf-root .ps-card.iris .ps-dot { width:9px; height:9px; border-radius:50%; background:var(--iris-ea); }
.perf-root .ps-card.unknown .ps-dot { width:9px; height:9px; border-radius:50%; background:var(--ps-unknown, #8b93a7); }
/* Provenance row — what KIND of money produced the numbers on this card, and on
   what base. CEO 2026-07-17 wants Iris shown from day one, so this row (not a
   hidden number) is what stops a young demo figure reading as a track record.
   .ps-basis carries the capital the € figures were earned on: Iris forward-tests
   2 x EUR 50k against Green's 3 x ~EUR 5k, so the euro sums look like a tie while
   the returns differ ~7x. Muted deliberately — it is context for the € values,
   not a headline competing with the % ones. */
.perf-root .ps-provrow { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:-4px 0 9px; }
.perf-root .ps-prov { display:inline-flex; align-items:center; font-size:var(--font-caption,11px);
  font-weight:700; letter-spacing:.03em; text-transform:uppercase; padding:1px 7px; border-radius:999px; }
.perf-root .ps-prov.live  { color:var(--green-ea); background:var(--green-tint); }
.perf-root .ps-prov.demo  { color:var(--iris-ea); background:var(--iris-tint); }
.perf-root .ps-prov.mixed { color:var(--amber); background:var(--amber-tint, rgba(217,164,65,.14)); }
.perf-root .ps-basis { font-size:var(--font-caption,11px); color:var(--text-dim); font-weight:600; }
.perf-root .ps-metrics { display:grid; grid-template-columns:repeat(auto-fit,minmax(78px,1fr)); gap:8px; }
.perf-root .ps-m .psk { font-size:.62rem; text-transform:uppercase; letter-spacing:.04em; color:var(--text-dim); }
.perf-root .ps-m .psv { font-size:1.02rem; font-weight:700; font-variant-numeric:tabular-nums; color:var(--text-main); margin-top:1px; }
/* two-tier card: highlighted TODAY tier above the OVERALL context tier */
.perf-root .ps-tier-lbl { font-size:.58rem; font-weight:800; text-transform:uppercase; letter-spacing:.07em; color:var(--text-dim); margin-bottom:5px; }
.perf-root .ps-today { background:color-mix(in srgb, var(--accent) 7%, transparent); border:1px solid color-mix(in srgb, var(--accent) 18%, transparent); border-radius:9px; padding:8px 9px; margin-bottom:8px; }
.perf-root .ps-today .ps-tier-lbl { color:var(--accent); }
.perf-root .ps-overall { padding:0 1px; }
.perf-root .ps-best { font-size:.7rem; font-weight:600; color:var(--text-dim); margin-top:7px; }
.perf-root .ps-best .best-acct { color:var(--text-main); font-weight:800; font-variant-numeric:tabular-nums; }
.perf-root .ps-best .ps-muted { color:var(--text-dim); font-style:italic; opacity:.85; }
.perf-root .ps-m .psv .ps-sub { font-size:.62rem; font-weight:600; color:var(--text-dim); white-space:nowrap; }
/* weekend resting note replaces the zeroed Today metrics */
.perf-root .ps-closed { font-size:.74rem; font-weight:600; color:var(--text-dim); padding:5px 1px 2px; }
/* per-family 7-day trend spark, pinned to the card footer */
.perf-root .ps-spark { display:flex; align-items:center; gap:8px; margin-top:9px; padding-top:8px; border-top:1px solid var(--border-subtle, var(--border)); }
.perf-root .ps-spark-lbl { font-size:.58rem; font-weight:800; text-transform:uppercase; letter-spacing:.07em; color:var(--text-dim); }
.perf-root .ps-spark .ispark.pscard { width:120px; height:26px; flex:0 0 auto; margin-left:auto; }

/* ===== per-account COMPACT SORTABLE TABLE (replaces card grid) ===== */
.perf-root .grid.as-table { display:block; }
.perf-root .acct-table-wrap { overflow-x:auto; border:1px solid var(--border); border-radius:13px; -webkit-overflow-scrolling:touch; }
.perf-root table.acct-table { width:100%; border-collapse:collapse; font-size:.82rem; font-variant-numeric:tabular-nums; }
.perf-root table.acct-table th, .perf-root table.acct-table td { padding:7px 11px; text-align:left; white-space:nowrap; border-bottom:1px solid var(--border-subtle); }
.perf-root table.acct-table th { background:var(--surface-1); font-size:.66rem; text-transform:uppercase; letter-spacing:.04em; color:var(--text-dim); font-weight:700; }
.perf-root table.acct-table th.num, .perf-root table.acct-table td.num { text-align:right; }
/* sticky first column (account #) so it stays anchored while the wide table
   horizontal-scrolls — mirrors the combo table treatment */
.perf-root table.acct-table th:first-child, .perf-root table.acct-table td:first-child {
  position:sticky; left:0; z-index:1; background:var(--bg-card); }
.perf-root table.acct-table thead th:first-child { z-index:2; background:var(--surface-1); }
.perf-root table.acct-table tbody tr:hover td:first-child { background:var(--surface-1); }
.perf-root table.acct-table th.sortable { cursor:pointer; user-select:none; }
.perf-root table.acct-table th.sortable:hover { color:var(--text-main); }
.perf-root table.acct-table th.sorted { color:var(--accent); }
.perf-root table.acct-table th .sc { margin-left:3px; }
.perf-root table.acct-table tbody tr:hover { background:var(--surface-1); }
.perf-root table.acct-table tbody tr:last-child td { border-bottom:0; }
.perf-root table.acct-table td.mono { font-variant-numeric:tabular-nums; color:var(--text-sub); }
.perf-root table.acct-table td.cfgcell { color:var(--text-dim); font-size:.76rem; }
.perf-root table.acct-table td.num .subt { color:var(--text-dim); font-size:.82em; font-weight:600; }
.perf-root table.acct-table .badge { font-size:.64rem; padding:1px 7px; }
.perf-root table.acct-table .tnow { display:inline-flex; align-items:center; gap:5px; color:var(--profit); font-weight:700; justify-content:flex-end; }
.perf-root table.acct-table .tnow .tdot { width:7px; height:7px; border-radius:50%; background:var(--profit); box-shadow:0 0 0 0 var(--profit); animation:perf-trade-pulse 1.8s ease-out infinite; }
.perf-root table.acct-table .tidle { color:var(--text-dim); }
.perf-root table.acct-table td.hbcol, .perf-root table.acct-table th.hbcol { width:22px; text-align:center; padding-left:4px; padding-right:8px; }
.perf-root table.acct-table td.hbcol .dot { width:7px; height:7px; border-radius:50%; display:inline-block; background:var(--text-dim); }
.perf-root table.acct-table td.hbcol .dot.live { background:var(--profit); }
.perf-root table.acct-table td.hbcol .dot.stale { background:var(--loss); }
/* compact density (header density toggle): tighter cells so more of the
   now-wide Accounts table fits at once */
.perf-root.compact table.acct-table { font-size:.78rem; }
.perf-root.compact table.acct-table th, .perf-root.compact table.acct-table td { padding:4px 7px; }
.perf-root.compact table.acct-table th { font-size:.62rem; }

/* expandable live-trades detail */
.perf-root .proj-trades { cursor:pointer; }
.perf-root .proj-trades .pt-chev { margin-left:auto; color:var(--text-dim); font-size:.8rem; }
.perf-root .proj-detail { grid-column:1 / -1; margin-top:8px; }
.perf-root .pd-load { padding:14px; text-align:center; color:var(--text-dim); font-size:.82rem; }
.perf-root .pd-grid { display:grid; grid-template-columns:1fr 1fr; gap:11px; }
@media (max-width:640px){ .perf-root .pd-grid { grid-template-columns:1fr; } }
.perf-root .pd-col { border:1px solid var(--border-subtle); border-radius:11px; padding:10px 12px; background:var(--bg-card); }
.perf-root .pd-h { font-weight:700; font-size:.84rem; color:var(--text-main); margin-bottom:7px; }
.perf-root .pd-h.amber { border-left:3px solid var(--amber); padding-left:7px; }
.perf-root .pd-h.green { border-left:3px solid var(--profit); padding-left:7px; }
.perf-root .pd-h .pd-sub { font-weight:600; font-size:.68rem; color:var(--text-dim); }
.perf-root .pd-empty { color:var(--text-dim); font-size:.78rem; padding:6px 2px; }
.perf-root .pd-rows { font-size:.8rem; font-variant-numeric:tabular-nums; }
.perf-root .pd-row { display:grid; grid-template-columns:1fr 56px 28px 78px; align-items:center; gap:6px; padding:3px 0; }
.perf-root .pd-row.pd-head { font-size:.62rem; text-transform:uppercase; letter-spacing:.04em; color:var(--text-dim); font-weight:700; border-bottom:1px solid var(--border-subtle); padding-bottom:4px; margin-bottom:2px; }
.perf-root .pd-row .pd-sym { font-weight:600; color:var(--text-sub); }
.perf-root .pd-row .pd-dir .lg { color:var(--profit); margin-right:4px; }
.perf-root .pd-row .pd-dir .sh { color:var(--loss); }
.perf-root .pd-row .pd-cnt { text-align:right; color:var(--text-dim); }
.perf-root .pd-row .pd-fl { text-align:right; font-weight:600; }

/* nav right cluster: global family filter + density toggle */
.perf-root .perf-nav-right { display:flex; align-items:center; gap:8px; flex:none; }
.perf-root .nav-famseg { display:inline-flex; background:var(--surface-1); border:1px solid var(--border); border-radius:8px; padding:2px; }
/* global demo/live account-type filter — #grpAcctType is a display-gate wrapper that
   populateFilters() reveals only when live accounts exist; the inner #acctseg reuses
   nav-famseg pill styling so it sits flush beside the Amber/Green family filter. */
.perf-root .nav-acctseg-wrap { display:inline-flex; align-items:center; }
.perf-root .nav-famseg button { background:transparent; border:0; cursor:pointer; font-size:.74rem; font-weight:600;
  color:var(--text-sub); padding:4px 10px; border-radius:6px; transition:background .15s, color .15s; }
.perf-root .nav-famseg button:hover { color:var(--text-main); }
/* nav-famseg active: accent-coloured pill so it pops clearly from the muted inactive buttons */
.perf-root .nav-famseg button.active {
  color: var(--accent);
  background: var(--ds-accent-tint-strong, color-mix(in srgb, var(--accent) 18%, var(--surface-1)));
  font-weight: var(--fw-semi, 600);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}

/* band dividers — group the long page into logical reading sections */
.perf-root .band { display:flex; align-items:center; gap:12px; margin:22px 0 12px; }
.perf-root .band::before, .perf-root .band::after { content:""; height:1px; background:var(--border); flex:1; }
.perf-root .band .band-t { font-size:.7rem; font-weight:800; text-transform:uppercase; letter-spacing:.09em; color:var(--text-sub);
  white-space:nowrap; padding:3px 12px; border:1px solid var(--border); border-radius:999px; background:var(--bg-card); }
.perf-root.compact .band { margin:14px 0 8px; }

/* growth-target cell (per-account table) */
.perf-root table.acct-table .tgt-hit { color:var(--profit); font-weight:700; white-space:nowrap; }
.perf-root table.acct-table .tgt-prog { color:var(--text-sub); font-variant-numeric:tabular-nums; }
.perf-root table.acct-table .tgt-unl { color:var(--text-dim); }

/* ── Visual refinement 2026-06-19: premium hairlines, numeric polish, profit-tinted "best" ── */
.perf-root .section,
.perf-root .hcard,
.perf-root .card,
.perf-root .chip,
.perf-root .scrubber,
.perf-root .perf-nav { border-color: var(--border-subtle); }
.perf-root .chip .v,
.perf-root .vs .colhead { font-variant-numeric: tabular-nums; }
.perf-root .hcard.best { border-color: var(--profit); box-shadow: inset 0 0 0 1px var(--profit), 0 6px 22px var(--shadow-color); }
.perf-root .hcard.best::before { background: var(--profit); opacity: 1; }
/* Hero promotion: the fleet "Net return · all-time" is the ONE card carrying a
   real accent — full-opacity accent stripe + a very faint accent tint wash — so
   the accent reads as deliberate hierarchy, not scattered colour. --accent is
   theme-aware, so the tint resolves correctly in both light and dark. */
/* Hero card = the ONE accented focal element: full-opacity accent stripe + a
   faint accent tint wash + the largest value. In the HERO+CHIPS layout the hero
   is its own grid column (id rules above), so it must NOT span columns. */
.perf-root #heroGrid .hcard.hero-primary { grid-column: auto;
  background: var(--ds-accent-tint, color-mix(in srgb, var(--accent) 5%, var(--bg-card))); }
.perf-root #heroGrid .hcard.hero-primary::before { width:3px; background:var(--accent); opacity:1; }
.perf-root #heroGrid .hcard.hero-primary .v { font-size: 2.6rem; line-height: 1.05; font-weight:800; }
@media (max-width:480px){
  .perf-root #heroGrid .hcard.hero-primary .v { font-size: 2.2rem; }
}

/* ── Visual refinement 2026-06-19: rounded chart line joins (smoother lines) ── */
.perf-root .growth path.gcurve,
.perf-root .growth path.garea,
.perf-root .overlay path.curve,
.perf-root .race path.rl,
.perf-root svg.scatter path,
.perf-root path.gcurve { stroke-linejoin: round; stroke-linecap: round; }

/* Section rhythm — give the numbered badges a quiet accent identity so the
   sections read as a deliberate sequence, without reintroducing heavy
   dividers (hairlines stay soft per the refinement above). */
.perf-root .secnum {
  color: var(--accent, var(--text-sub));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent, var(--text-sub)) 30%, transparent);
  background: color-mix(in srgb, var(--accent, var(--text-sub)) 8%, var(--surface-1));
}

/* =====================================================================
   Task 13 — NEW layout styles: tabs, scorecard, heatmap, underwater,
   methodology, net-of-fees legend swatch.
   All rules scoped under .perf-root.
   ===================================================================== */

/* ===== Tab strip ===== */
.perf-root .perf-tabs {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  padding: 0 2px 0;
  margin: 0 0 18px;
}
.perf-root .perf-tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: var(--radius-chip, 8px) var(--radius-chip, 8px) 0 0;
  color: var(--text-sub);
  cursor: pointer;
  font-size: .84rem;
  font-weight: 600;
  line-height: 1;
  margin-bottom: -1px; /* sit on the strip border */
  padding: 10px 16px 11px;
  transition: color .15s, border-color .15s, background .15s;
  white-space: nowrap;
}
.perf-root .perf-tab:hover {
  color: var(--text-main);
  background: var(--surface-1);
}
.perf-root .perf-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-chip, 8px);
}
.perf-root .perf-tab[aria-selected="true"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* Tab panels — hidden attr hides them natively; ensure no CSS fights it.
   Only add layout rules on the visible panel. */
.perf-root .perf-tabpanel:not([hidden]) {
  display: block;
}

/* ===== Hero scorecard (#heroGrid) — 6 cards, collapses across breakpoints ===== */
/* The hero-grid rule already exists (repeat(auto-fit, minmax(158px,1fr))).
   Add the hero-spark sparkline sizing and sc-empty empty-state. */
.perf-root .hero-spark {
  width: 100%;
  height: 60px;
  margin: 10px 0 2px;
  display: block;
  overflow: hidden;
}
.perf-root .hero-spark svg,
.perf-root .hero-spark canvas {
  width: 100%;
  height: 100%;
  display: block;
}
.perf-root .sc-empty {
  font-size: .76rem;
  color: var(--text-dim);
  font-style: italic;
}

/* Scorecard responsive collapse: 6 → 3 → 2 → 1 columns */
@media (max-width: 1100px) {
  .perf-root .hero-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (max-width: 700px) {
  .perf-root .hero-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 480px) {
  .perf-root .hero-grid {
    grid-template-columns: 1fr 1fr;
  }
  /* hero-primary already spans full width on phones via existing rule */
}

/* ===== Monthly heatmap ===== */
/* 13 columns: year-label + Jan..Dec */
.perf-root .mhm-grid {
  display: grid;
  grid-template-columns: 40px repeat(12, 1fr);
  gap: 3px;
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
}
.perf-root .mhm-yr-lbl {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 6px;
  font-size: .68rem;
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
}
.perf-root .mhm-mo-lbl {
  text-align: center;
  font-size: .64rem;
  font-weight: 700;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: 2px 0 4px;
}
.perf-root .mhm-cell {
  /* background set by JS inline style — do NOT override */
  aspect-ratio: 1 / 1;
  border-radius: 5px;
  border: 1px solid var(--border-subtle);
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  cursor: default;
  transition: filter .1s;
}
.perf-root .mhm-cell:hover {
  filter: brightness(1.12);
  border-color: var(--border);
  z-index: 1;
}
.perf-root .mhm-cell span {
  font-size: .62rem;
  font-weight: 700;
  line-height: 1;
  /* Value text is neutral high-contrast (direction is already carried by the
     green/red fill + the +/- sign), so it stays legible on every fill intensity
     in both themes — the .pos/.neg green-on-green low-contrast case is gone. */
  color: var(--text-main);
  text-shadow: 0 1px 1.5px rgba(0, 0, 0, .45);
}
:root.light .perf-root .mhm-cell span { text-shadow: 0 1px 1.5px rgba(255, 255, 255, .55); }
@media (prefers-color-scheme: light) { .perf-root .mhm-cell span { text-shadow: 0 1px 1.5px rgba(255, 255, 255, .55); } }
.perf-root .mhm-null {
  background: var(--surface-1) !important;
  opacity: .35;
  cursor: default;
}
.perf-root .mhm-null:hover {
  filter: none;
  border-color: var(--border-subtle);
}
/* Center the faint "·" placeholder inside null heatmap cells */
.perf-root .mhm-dot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--text-dim);
}
/* New-fleet note (reuses .nd-card) — give it breathing room above the sparse grid */
.perf-root .mhm-newfleet {
  margin-bottom: var(--space-3, 12px);
}

/* light mode: cells already have inline background from JS; border slightly
   darker for contrast on white */
:root.light .perf-root .mhm-cell {
  border-color: rgba(0, 0, 0, .10);
}
@media (prefers-color-scheme: light) {
  .perf-root .mhm-cell {
    border-color: rgba(0, 0, 0, .10);
  }
}

/* heatmap responsive: scroll horizontally instead of clipping on phones/tablets.
   The 13-col grid (year + Jan..Dec) overflows a narrow card, so #monthlyHeatmap
   is the scroll container and the grid keeps a legible min-width floor. */
@media (max-width: 700px) {
  .perf-root #monthlyHeatmap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .perf-root .mhm-grid {
    grid-template-columns: 34px repeat(12, 30px);
    gap: 2px;
    font-size: .64rem;
    min-width: 420px; /* floor so Dec/Nov stay legible; scroll past it */
  }
  .perf-root .mhm-cell span { font-size: .56rem; }
}
@media (max-width: 480px) {
  /* allow horizontal scroll rather than crushing cells on narrow phones */
  .perf-root #monthlyHeatmap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .perf-root .mhm-grid {
    grid-template-columns: 32px repeat(12, 26px);
    gap: 2px;
    min-width: 380px; /* floor so cells stay legible */
  }
  .perf-root .mhm-yr-lbl { font-size: .6rem; padding-right: 4px; }
  .perf-root .mhm-mo-lbl { font-size: .58rem; }
  .perf-root .mhm-cell span { font-size: .52rem; }
}

/* ===== Underwater SVG ===== */
.perf-root svg.underwater {
  width: 100%;
  height: auto;
  display: block;
  /* Height is set in JS (sizeChart) to match the SVG viewBox 1:1 so the chart
     fills its box with no distortion and no letterbox. No min/max-height here —
     a CSS height differing from the JS value would reintroduce stretch/whitespace. */
}

/* Underwater curve text uses the chart text tokens; share the .growth fill */
.perf-root svg.underwater text { fill: var(--text-dim); font-size:11px; }
/* I7 — light mode: the gray tick labels on the underwater curve read a touch faint
   on white. Darken them to clear AA contrast. Scoped to light so dark is untouched.
   (The area-gradient opacity is bumped slightly in renderUnderwater for both modes,
   which lifts the faint light-mode fill without harming the dark page.) */
:root.light .perf-root svg.underwater text { fill: rgb(88,88,96); }
@media (prefers-color-scheme: light) {
  .perf-root svg.underwater text { fill: rgb(88,88,96); }
}

/* ===== Methodology <details> ===== */
/* Task 7 replaced the static <h3>Methodology</h3> with a <details class="perf-methodology">
   containing a <summary>. The existing .method h3 rule (line 254) styled the old heading;
   we now migrate that styling to .perf-methodology summary so the visual is preserved. */
.perf-root .perf-methodology {
  /* inherits .method container styles from the parent .method div */
}
.perf-root .perf-methodology > summary {
  /* migrated from: .perf-root .method h3 { font-size:.82rem; margin:0 0 9px; color:var(--text-main); } */
  font-size: .86rem;
  font-weight: 700;
  color: var(--text-main);
  margin: 0;
  cursor: pointer;
  list-style: none; /* suppress default marker */
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 0 10px;
  user-select: none;
  border-bottom: 1px solid transparent;
  transition: color .15s;
}
/* custom expand/collapse chevron */
.perf-root .perf-methodology > summary::after {
  content: '▼';
  font-size: .62rem;
  color: var(--text-dim);
  margin-left: auto;
  transition: transform .2s;
}
.perf-root .perf-methodology[open] > summary::after {
  transform: rotate(180deg);
}
/* suppress WebKit default disclosure triangle */
.perf-root .perf-methodology > summary::-webkit-details-marker { display: none; }
.perf-root .perf-methodology > summary::marker { display: none; }

.perf-root .perf-methodology > summary:hover {
  color: var(--accent);
}
.perf-root .perf-methodology > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 5px;
}
/* when open: subtle separator between summary and body */
.perf-root .perf-methodology[open] > summary {
  border-bottom-color: var(--border-subtle);
  margin-bottom: 10px;
}
/* the dl / disc content inherits .method dl/.method .disc rules already in file */

/* ===== Net-of-fees legend swatch (.glegend .dash without .linear) =====
   The growth chart draws the net companion line as a dashed SVG path.
   The legend swatch uses <span class="dash" style="background:var(--text-sub)">
   which renders as a solid 2px block — visually inconsistent with a dashed line.
   We override to a dashed appearance using a repeating-linear-gradient so it
   reads as dashes without needing markup changes.
   .dash.linear (gross line swatch) stays solid — only the bare .dash is targeted. */
.perf-root .glegend .dash:not(.linear) {
  background: repeating-linear-gradient(
    to right,
    var(--text-sub) 0px,
    var(--text-sub) 5px,
    transparent 5px,
    transparent 9px
  ) !important;
  border-radius: 0;
  height: 2px;
  width: 20px;
}

/* ===== Light-mode overrides for new components ===== */
:root.light .perf-root .perf-tab[aria-selected="true"] {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
:root.light .perf-root .mhm-null {
  background: var(--surface-1) !important;
  opacity: .4;
}
/* Segmented control active state: light mode gets a slightly stronger tint
   so the accent-coloured active button reads against the white/light card bg */
:root.light .perf-root .seg button.active,
:root.light .perf-root .toolbar .seg button.active {
  background: color-mix(in srgb, var(--accent) 14%, var(--bg-card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
}
:root.light .perf-root .nav-famseg button.active {
  background: color-mix(in srgb, var(--accent) 14%, var(--bg-card));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
}
/* Band divider light-mode: keep text and lines visible on white card background */
:root.light .perf-root .band .band-t {
  color: var(--text-main);
  border-color: var(--border);
  background: var(--bg-card);
}
:root.light .perf-root .band::before,
:root.light .perf-root .band::after { background: var(--border); }

@media (prefers-color-scheme: light) {
  .perf-root .perf-tab[aria-selected="true"] {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
  }
  .perf-root .mhm-null {
    background: var(--surface-1) !important;
    opacity: .4;
  }
  .perf-root .seg button.active,
  .perf-root .toolbar .seg button.active {
    background: color-mix(in srgb, var(--accent) 14%, var(--bg-card));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
  }
  .perf-root .nav-famseg button.active {
    background: color-mix(in srgb, var(--accent) 14%, var(--bg-card));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent);
  }
  .perf-root .band .band-t {
    color: var(--text-main);
    border-color: var(--border);
    background: var(--bg-card);
  }
  .perf-root .band::before,
  .perf-root .band::after { background: var(--border); }
}

/* ══════════════════════════════════════════════════════════════════════
   Today intraday card + Quality/Consistency (2026-07-02, today-forward)
   ══════════════════════════════════════════════════════════════════════ */
.perf-root .today-card { }
.perf-root .today-head { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; }
.perf-root .today-head h2 { margin:0; }
.perf-root .today-val { font-size:26px; font-weight:700; font-variant-numeric:tabular-nums; letter-spacing:-.01em; white-space:nowrap; }
.perf-root .today-val.pos { color:var(--profit); }
.perf-root .today-val.neg { color:var(--loss); }
.perf-root .today-val.flat { color:var(--text-sub); }
.perf-root svg.intraday { display:block; width:100%; min-height:0; margin-top:6px; }

/* quality tiles */
.perf-root .quality-row { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin:10px 0 14px; }
.perf-root .qtile { background:var(--bg-card); border:1px solid var(--border); border-radius:14px; padding:14px 16px; min-height:88px; }
.perf-root .qtile.empty { grid-column:1/-1; display:flex; align-items:center; justify-content:center; color:var(--text-sub); }
.perf-root .qtile .qk { font-size:12px; color:var(--text-sub); text-transform:uppercase; letter-spacing:.04em; }
.perf-root .qtile .qv { font-size:22px; font-weight:700; font-variant-numeric:tabular-nums; margin-top:4px; color:var(--text-main); }
.perf-root .qtile .qs { font-size:11px; color:var(--text-dim); margin-top:2px; }
.perf-root .qacc { font-size:12px; color:var(--text-dim); font-style:italic; }

/* consistency card */
.perf-root .consistency-card { display:grid; grid-template-columns:repeat(3,1fr); gap:1px; background:var(--border);
  border:1px solid var(--border); border-radius:14px; overflow:hidden; }
.perf-root .cstat { background:var(--bg-card); padding:12px 16px; display:flex; flex-direction:column; gap:2px; }
.perf-root .cstat .cl { font-size:12px; color:var(--text-sub); }
.perf-root .cstat .cv { font-size:18px; font-weight:700; font-variant-numeric:tabular-nums; color:var(--text-main); }
.perf-root .cstat .cv.pos { color:var(--profit); }
.perf-root .cstat .cv.neg { color:var(--loss); }
.perf-root .cstat .cv.flat { color:var(--text-sub); }
.perf-root .cstat .cm { font-size:11px; color:var(--text-dim); }
.perf-root .cempty { grid-column:1/-1; background:var(--bg-card); padding:16px; text-align:center; color:var(--text-sub); }

@media (max-width:720px){
  .perf-root .quality-row { grid-template-columns:repeat(2,1fr); }
  .perf-root .consistency-card { grid-template-columns:repeat(2,1fr); }
  .perf-root .today-val { font-size:22px; }
}

/* ============================================================================
   Clean-start teaser (PERF_DISPLAY_FLOOR) — Phase 2 of the perf overhaul.
   While .perf-warming is on .perf-root, every data section under .wrap is
   hidden and only the header + #warmingUp panel show. Theme-correct via tokens.
   ========================================================================== */
/* While warming, the teaser is the ONLY thing in .wrap — hide the marketing
   header and every data section so nothing contradicts the "coming soon". */
.perf-root.perf-warming .wrap > * { display: none !important; }
.perf-root.perf-warming .wrap > #warmingUp { display: flex !important; }
.perf-root.perf-warming .perf-nav { display: none !important; }

.perf-warming#warmingUp {
  min-height: min(72vh, 620px);
  align-items: center; justify-content: center;
  margin: 0; padding: 4vh 0 6vh;
}
.perf-warming .pwt-card {
  position: relative;
  width: 100%; max-width: 560px;
  margin: 0 auto;
  padding: clamp(34px, 5vw, 60px) clamp(24px, 5vw, 52px) clamp(30px, 4vw, 46px);
  text-align: center;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 22px;
  box-shadow: 0 24px 60px -30px var(--shadow-color, rgba(0,0,0,.45));
}
.perf-warming .pwt-art {
  display: block; width: clamp(180px, 46%, 260px); height: auto; margin: 0 auto 22px;
  opacity: .9;
}
.perf-warming .pwt-badge {
  display: inline-block; margin-bottom: 18px;
  padding: 5px 13px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
}
.perf-warming .pwt-title {
  margin: 0 0 8px; font-size: clamp(19px, 3vw, 26px); line-height: 1.25;
  font-weight: 700; color: var(--text-sub); letter-spacing: -.01em;
}
.perf-warming .pwt-date {
  margin: 0 0 4px; font-size: clamp(26px, 5vw, 40px); line-height: 1.1;
  font-weight: 800; letter-spacing: -.02em;
  background: linear-gradient(90deg, var(--amber), var(--green-ea));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--accent);
}
.perf-warming .pwt-count {
  margin: 6px 0 18px; font-size: 12.5px; font-weight: 600; letter-spacing: .02em;
  color: var(--text-dim);
}
.perf-warming .pwt-sub {
  margin: 0 auto; max-width: 44ch;
  font-size: clamp(13px, 1.7vw, 14.5px); line-height: 1.65; color: var(--text-sub);
}
.perf-warming .pwt-foot {
  margin: 22px auto 0; max-width: 42ch; padding-top: 18px;
  border-top: 1px solid var(--border-subtle, var(--border));
  font-size: 12px; line-height: 1.5; color: var(--text-dim);
}
.perf-warming .pwt-foot b { color: var(--text-sub); font-weight: 650; }

/* ===================== rolling average-return trend (2026-07-13) =====================
   Small line chart in the Quality & Consistency section, fed by fleet.avg_daily_trend.
   Sits below the consistency card; spans the full width of the section. */
.perf-root .avg-trend-wrap { margin-top:16px; padding-top:14px; border-top:1px solid var(--border-subtle); }
.perf-root .avg-trend-h { font-size:.82rem; margin:0 0 2px; color:var(--text-sub); font-weight:700; }
.perf-root .avg-trend-wrap .hint { margin:0 0 8px; }
.perf-root svg.avg-trend { width:100%; height:150px; display:block; }
.perf-root svg.avg-trend text { fill:var(--text-dim); font-size:10.5px; }
.perf-root svg.avg-trend .gridln { stroke:var(--border-subtle); stroke-width:1; }
.perf-root svg.avg-trend .zeroln { stroke:var(--text-dim); stroke-width:1; stroke-dasharray:3 3; opacity:.6; }
.perf-root svg.avg-trend .axis { stroke:var(--border); stroke-width:1; }

/* ===================== monthly breakdown table (rebuilt 2026-07-13) =====================
   11 columns now — widen the min-width so it scrolls inside .tbl-scroll rather than
   squashing, and style the Start → End balance chain so the eye follows the ledger. */
.perf-root table.perf.perf-monthly { min-width:920px; }
.perf-root table.perf.perf-monthly .mbal { display:inline-flex; align-items:center; gap:6px; font-variant-numeric:tabular-nums; }
.perf-root table.perf.perf-monthly .mbal-s { color:var(--text-dim); }
.perf-root table.perf.perf-monthly .mbal-arr { color:var(--text-dim); opacity:.7; }
.perf-root table.perf.perf-monthly .mbal-e { color:var(--text-main); font-weight:700; }
.perf-root .monthly-basis-note { border-left:2px solid var(--border); padding-left:10px; }

/* ============================================================================
   Account table → stacked cards on phones (2026-07-13, SilverFen)
   18 columns horizontal-scroll badly on mobile. Each td carries data-label
   (set in renderGrid); below 680px we drop the header row and render each
   account as a labelled card. Desktop is untouched.
   ============================================================================ */
@media (max-width: 680px) {
  .perf-root .acct-table-wrap { overflow-x: visible; border: 0; }
  .perf-root table.acct-table { width: 100%; font-size: .9rem; }
  /* keep the header for screen readers but pull it out of the visual flow */
  .perf-root table.acct-table thead {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  .perf-root table.acct-table,
  .perf-root table.acct-table tbody,
  .perf-root table.acct-table tr,
  .perf-root table.acct-table td { display: block; width: auto; }
  .perf-root table.acct-table tr {
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 8px 12px 10px;
    margin-bottom: 12px;
    background: rgba(255,255,255,0.02);
  }
  /* un-stick the frozen first column (it only exists for the desktop scroll) */
  .perf-root table.acct-table th:first-child,
  .perf-root table.acct-table td:first-child { position: static; background: transparent; }
  .perf-root table.acct-table td {
    display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
    padding: 5px 0; border: 0; text-align: right; white-space: normal;
  }
  .perf-root table.acct-table td::before {
    content: attr(data-label);
    text-align: left; flex: 0 0 auto;
    color: var(--text-dim); font-weight: 600;
    font-size: .72rem; text-transform: uppercase; letter-spacing: .03em;
  }
  /* account name = card header row */
  .perf-root table.acct-table td.acctname {
    font-size: 1.05rem; font-weight: 800;
    border-bottom: 1px solid var(--border);
    padding-bottom: 8px; margin-bottom: 4px;
    justify-content: flex-start; gap: 8px;
  }
  .perf-root table.acct-table td.acctname::before { display: none; }
  /* health-dot column has no label — right-align the dot, hide the pseudo-label */
  .perf-root table.acct-table td.hbcol { justify-content: flex-end; }
  .perf-root table.acct-table td.hbcol::before,
  .perf-root table.acct-table td:not([data-label])::before { display: none; }
}

/* ============================================================================
   DAILY-RETURNS CALENDAR HEATMAP (#dailyHeatmap) — GitHub-contributions style.
   The SVG is rendered at natural pixel size by perf-page.js; the host scrolls
   horizontally on narrow screens rather than distorting the day squares.
   ============================================================================ */
.perf-root .daily-heatmap-wrap { margin-top: 18px; }
.perf-root .daily-heatmap-wrap .dh-h {
  font-size: .95rem; font-weight: 700; margin: 0 0 4px;
  display: flex; align-items: center;
}
.perf-root #dailyHeatmap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.perf-root .daily-heatmap-svg { display: block; }
.perf-root .daily-heatmap-svg .dh-cell {
  stroke: var(--border-subtle); stroke-width: .5;
  transition: filter .1s;
}
.perf-root .daily-heatmap-svg .dh-cell:hover { filter: brightness(1.15); }
.perf-root .daily-heatmap-svg .dh-muted { stroke: var(--border-subtle); }
.perf-root .daily-heatmap-svg .dh-wd,
.perf-root .daily-heatmap-svg .dh-mo {
  fill: var(--text-dim); font-size: 9.5px; font-weight: 600;
}
:root.light .perf-root .daily-heatmap-svg .dh-cell { stroke: rgba(0,0,0,.10); }
@media (prefers-color-scheme: light) { .perf-root .daily-heatmap-svg .dh-cell { stroke: rgba(0,0,0,.10); } }
/* legend: loss ← neutral → gain swatches (mirrors heatColor intensity ramp) */
.perf-root .dh-legend {
  display: flex; align-items: center; gap: 3px;
  margin-top: 8px; font-size: .68rem; color: var(--text-dim);
}
.perf-root .dh-legend .dh-lg-lbl { margin: 0 4px; }
.perf-root .dh-sw {
  width: 12px; height: 12px; border-radius: 2.5px;
  border: 1px solid var(--border-subtle); display: inline-block;
}
.perf-root .dh-sw-l3 { background: rgba(var(--loss-rgb), .67); }
.perf-root .dh-sw-l2 { background: rgba(var(--loss-rgb), .40); }
.perf-root .dh-sw-l1 { background: rgba(var(--loss-rgb), .18); }
.perf-root .dh-sw-0  { background: rgba(127,127,127, .14); }
.perf-root .dh-sw-g1 { background: rgba(var(--profit-rgb), .18); }
.perf-root .dh-sw-g2 { background: rgba(var(--profit-rgb), .40); }
.perf-root .dh-sw-g3 { background: rgba(var(--profit-rgb), .67); }

/* Desktop: with only a few weeks of data the SVG renders ~126px wide and looks
   lost in the full-width section. It carries a viewBox, so scale it up by height
   (width follows proportionally) — bigger, readable squares without distortion.
   Mobile keeps natural size + horizontal scroll (2026-07-13, SilverFen). */
@media (min-width: 681px) {
  .perf-root .daily-heatmap-svg { height: clamp(180px, 15vw, 240px); width: auto; }
}

/* ============================================================================
   CLICK-TO-EXPLAIN — the "ⓘ" affordance + its popover. Small circled "i" button
   next to key metrics; opens a plain-language explanation on click / Enter.
   ============================================================================ */
.perf-root .perf-info {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; padding: 0; margin-left: 5px;
  border: 1px solid var(--border); border-radius: 50%;
  background: transparent; color: var(--text-dim);
  font-size: .64rem; font-weight: 700; font-style: normal; line-height: 1;
  font-family: Georgia, 'Times New Roman', serif;
  cursor: pointer; vertical-align: middle; flex: 0 0 auto;
  transition: color .12s, border-color .12s, background .12s;
}
.perf-root .perf-info::before { content: 'i'; }
.perf-root .perf-info:hover,
.perf-root .perf-info:focus-visible {
  color: var(--accent); border-color: var(--accent);
  background: var(--surface-1, var(--bg-card)); outline: none;
}
.perf-root .perf-info[aria-expanded="true"] {
  color: var(--accent); border-color: var(--accent);
  background: var(--surface-1, var(--bg-card));
}
/* keep the little "i" from inheriting the gradient text-fill some headings use */
.perf-root h2 .perf-info, .perf-root h3 .perf-info { -webkit-text-fill-color: initial; }

.perf-root .perf-explpop {
  position: fixed; z-index: 9999;
  max-width: 300px; width: max-content;
  background: var(--surface-1, var(--bg-card)); color: var(--text);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 34px var(--shadow-color, rgba(0,0,0,.35));
  padding: 11px 13px; display: none;
}
.perf-root .perf-explpop.on { display: block; }
.perf-root .perf-explpop .pxhd {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px; margin-bottom: 5px;
}
.perf-root .perf-explpop .pxttl {
  font-size: .82rem; font-weight: 700; color: var(--text); line-height: 1.25;
}
.perf-root .perf-explpop .pxclose {
  -webkit-appearance: none; appearance: none; border: 0; background: transparent;
  color: var(--text-dim); font-size: 1.05rem; line-height: 1; cursor: pointer;
  padding: 0 2px; margin: -2px -2px 0 0; flex: 0 0 auto;
}
.perf-root .perf-explpop .pxclose:hover { color: var(--text); }
.perf-root .perf-explpop .pxbd {
  font-size: .78rem; line-height: 1.5; color: var(--text-sub);
}
.perf-root .perf-explpop .pxbd b { color: var(--text); font-weight: 700; }
.perf-root .perf-explpop .pxfx {
  margin-top: 8px; font-size: .72rem; color: var(--text-dim);
  font-family: var(--font-mono, ui-monospace, 'SF Mono', Menlo, monospace);
  background: var(--bg-soft, rgba(127,127,127,.10));
  padding: 5px 7px; border-radius: 6px; line-height: 1.4;
}

/* .cprov — provenance qualifier inside a composition-strip family label
   (CEO 2026-07-17). The strip sits under a "Real-money accounts" heading, so an
   "Iris — 2" bar with no qualifier asserts two real-money Iris accounts; Iris is
   a demo forward test and is deliberately absent from the fleet totals, so its
   count legitimately exceeds accounts_total. This is what reconciles them. */
.perf-root .comp-row .cprov { font-size:var(--font-caption,11px); font-weight:700; letter-spacing:.02em;
  text-transform:uppercase; padding:0 5px; border-radius:999px; margin-left:5px; white-space:nowrap; }
.perf-root .comp-row .cprov.demo  { color:var(--iris-ea); background:var(--iris-tint); }
.perf-root .comp-row .cprov.mixed { color:var(--amber); background:var(--amber-tint, rgba(217,164,65,.14)); }
