/* ============================================================================
   Portfolio (the merged Positions + History surface)

   Token values only. Nothing here hardcodes a value app.css already names.

   THREE RULES THIS FILE HOLDS TO
   1. Shape. Three separate cards, each on --r-card, with a 14px gutter.
      app.css:16515 forces `border-radius: 0 !important` on every element at
      >=992px, excluding only #scoreboard-section, #positions-section,
      #history-section and .trollbox-widget. #portfolio-section is not
      excluded, so every radius here must be !important and id-scoped to
      out-rank it.
   2. Numerals. --num (Inter + tabular-nums) for a figure read as one value;
      --mono for a figure read down a table column. Token rule at
      app.css:38-48. The page hero matches .trade-spot-price (app.css:2409):
      1.8rem / 700 / #fff.
   3. Rows. The three tables reuse the trade-page strip's row HTML, so every
      rule here is a re-scoped copy of app.css:16222-16399. `.history-table`
      names three tables and `.user-positions-table` names two, so no
      selector here may use a bare class.
   ========================================================================= */

/* 32px of air under the header band, not 20. MEASURED on the Hyperliquid
   portfolio in Chrome on 2026-08-21: its nav band is 0..56 (the same 56px
   this header is), and the page title row starts 32px under the band below
   it. The four redesigned pages share this value. The TRADE page is not on
   it — a working surface starts at the chrome. */
#portfolio-section {
  padding: 32px 0 80px;
}
#portfolio-section .pf-wrap {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 20px;
}

/* ---------- page head ---------- */
/* Title left, every control right, on one row. */
#portfolio-section .pf-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
#portfolio-section .pf-title {
  margin: 0;
  color: var(--text-primary);
}
#portfolio-section .pf-head-l {
  display: flex;
  align-items: baseline;
  gap: 14px;
}
#portfolio-section .pf-sub {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--text-muted);
}
#portfolio-section .pf-sub span {
  font-variant-numeric: tabular-nums;
}
#portfolio-section .pf-sep {
  width: 1px;
  height: 11px;
  background: var(--border-light);
  display: block;
}
#portfolio-section .pf-head-r {
  display: flex;
  align-items: center;
  /* Wraps rather than overflows: title, filters and actions do not fit one
     line at 992px. */
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}
#portfolio-section .pf-btn {
  padding: 8px 14px;
  border: 1px solid var(--border-color);
  border-radius: var(--r-input) !important;
  background: transparent;
  color: var(--text-secondary);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
#portfolio-section .pf-btn:hover {
  border-color: var(--border-light);
  color: var(--text-primary);
}
/* Matches #trade-now-btn (app.css:5386): --accent background, --background
   text, so the two pages press the same button. */
#portfolio-section .pf-btn-pri {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--background);
}
#portfolio-section .pf-btn-pri:hover {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
  color: var(--background);
}

/* The filter bar. Page level, because the filters are page level in effect. */
#portfolio-section .pf-filters {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ---------- summary band: 316px rail + chart, two separate cards ----------
   Two cards with a gutter, not one box split by a hairline, so each card
   carries its own radius. */
#portfolio-section .pf-band {
  display: grid;
  grid-template-columns: 316px minmax(0, 1fr);
  gap: 14px;
}
/* The calendar takes the chart column, same as the line view — one card, one
   width, two marks inside it. `drawCalendar` (portfolio.js) solves the cell
   size for this width; do not fix the cell size here. */

/* `.pf-rail` is a column, not a card: no border of its own. */
#portfolio-section .pf-chart {
  border: 1px solid var(--border-color);
  border-radius: var(--r-card) !important;
  background: var(--card-bg);
}
/* Two cards in the rail, not one split by a hairline: the hero and the metric
   list are different questions ("how am I doing" vs "on what"). */
#portfolio-section .pf-rail {
  display: flex;
  flex-direction: column;
  gap: 14px;                 /* the same gutter the band uses */
}
#portfolio-section .pf-rail-hero,
#portfolio-section .pf-metrics {
  border: 1px solid var(--border-color);
  border-radius: var(--r-card) !important;
  background: var(--card-bg);
}
/* More padding than the metric card: the hero is the page's headline figure. */
#portfolio-section .pf-rail-hero {
  padding: 18px 16px 20px;
}
/* Label carries the filters and window ("TOTAL PNL · RANGERS · LAST 30
   DAYS"), so it must wrap rather than clip inside the 316px rail. */
#portfolio-section .pf-lbl {
  color: var(--text-muted);
  white-space: normal;
}
/* Same treatment as the trade page's spot price (app.css:2409): --num at
   700, tabular so a live figure cannot reflow its neighbours. */
#portfolio-section .pf-hero {
  margin-top: 10px;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
#portfolio-section .pf-wl {
  display: flex;
  gap: 2px;
  margin-top: 16px;
}
#portfolio-section .pf-wl i {
  display: block;
  height: 3px;
  min-width: 0;
}
#portfolio-section .pf-wl .pf-wl-w { background: var(--positive); }
#portfolio-section .pf-wl .pf-wl-l { background: var(--negative); }
#portfolio-section .pf-wl .pf-wl-o { background: var(--surface); }
/* Closed and expired: muted, neither a win nor a live position. */
#portfolio-section .pf-wl .pf-wl-x { background: var(--border-light); }
#portfolio-section .pf-wlk {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  font-variant-numeric: tabular-nums;
}
/* Win + loss + open counts must sum to the total shown. */
#portfolio-section .pf-wl-eq { color: var(--text-muted); }

/* A list, not a tile grid: label left, value right, no rules between rows.
   Values align in one column, and the row count is free. */
#portfolio-section .pf-metrics {
  display: flex;
  flex-direction: column;
  /* Fills the rail down to the bottom of the chart card beside it, so the two
     sides of the band line up. */
  flex: 1;
  padding: 6px 16px 10px;
}
#portfolio-section .pf-metric {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 7px 0;
}
#portfolio-section .pf-metric-l {
  color: var(--text-muted);
  white-space: nowrap;
}
/* Right-aligned so the column reads top to bottom. */
#portfolio-section .pf-metric-v {
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--text-primary);
}

/* ---------- chart ---------- */
/* One height for the card, stated once here. Both views (line, calendar)
   flex to fill it; neither sets a height of its own. A view switch may
   change what is drawn, but it must not move the page. */
#portfolio-section .pf-chart {
  display: flex;
  flex-direction: column;
  padding: 14px 16px 12px;
  /* Must exceed the natural height of both views, or the taller one pushes
     past this floor and the shift returns. `.pf-plot`'s own minimum stays
     below its share so flex can fill the difference. */
  min-height: 400px;
}
/* Flex column so `.pf-plot`'s `flex: 1` has a parent to grow inside. */
#portfolio-section #pf-view-line {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
#portfolio-section .pf-chart-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
#portfolio-section .pf-chart-title {
  color: var(--text-primary);
}
#portfolio-section .pf-chart-note {
  color: var(--text-muted);
}
#portfolio-section .pf-chart-ctl {
  display: flex;
  align-items: center;
  gap: 8px;
}
#portfolio-section .pf-chips,
#portfolio-section .pf-views {
  display: flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border-color);
  border-radius: var(--r-input) !important;
}
#portfolio-section .pf-chips[hidden],
#portfolio-section .pf-chip[hidden] { display: none; }
#portfolio-section .pf-view {
  padding: 4px 11px;
  border: 0;
  border-radius: var(--r-xs) !important;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
#portfolio-section .pf-view.active {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-primary);
}
#portfolio-section .pf-chip {
  padding: 4px 11px;
  border: 0;
  border-radius: var(--r-xs) !important;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
#portfolio-section .pf-chip.active {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-primary);
}
#portfolio-section .pf-chart-read {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-top: 14px;
}
/* Secondary to the rail hero: the rail is all-time, this is the selected
   window. Two figures at one size would read as a disagreement. */
#portfolio-section .pf-chart-value {
  font-variant-numeric: tabular-nums;
}
#portfolio-section .pf-chart-sub {
  margin-top: 4px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
#portfolio-section .pf-legend[hidden] { display: none; }
#portfolio-section .pf-legend {
  display: flex;
  gap: 14px;
  color: var(--text-muted);
}
#portfolio-section .pf-legend span {
  display: flex;
  align-items: center;
  gap: 6px;
}
#portfolio-section .pf-legend .pf-key-line {
  width: 14px;
  height: 2px;
  display: block;
}
#portfolio-section .pf-legend .pf-key-zero {
  width: 14px;
  border-top: 1px dashed var(--border-light);
  display: block;
}
#portfolio-section .pf-plot {
  position: relative;
  flex: 1;
  /* A floor for a narrow card, not the working height — that comes from
     `flex: 1` against `.pf-chart`'s min-height. Keep this below its share or
     the line view outgrows the card floor (see note above). */
  min-height: 200px;
  margin-top: 12px;
  cursor: crosshair;
}
/* Taken out of flow. `drawChart` sizes the svg from `plotEl.clientHeight`; an
   in-flow svg would define that height instead of receiving it, so height
   could only grow, never shrink. Absolute, so height comes only from
   `flex: 1` against the card. */
#portfolio-section .pf-plot svg {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}
/* Shown when the account holds a position but has not settled one. Not the
   empty state — rows exist below — so the band stays and only the plot
   changes. */
#portfolio-section .pf-plot-note {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  text-align: center;
  padding: 0 24px;
}
#portfolio-section .pf-plot-note[hidden] { display: none; }
#portfolio-section .pf-plot-note-t {
  color: var(--text-secondary);
}
#portfolio-section .pf-plot-note-s {
  max-width: 380px;
  color: var(--text-muted);
}
/* `left` and `top` are set by `onHover`. Do not fix either here, or the tip
   parks itself over the line it describes. */
#portfolio-section .pf-tip {
  position: absolute;
  padding: 8px 10px;
  border: 1px solid var(--border-light);
  border-radius: var(--r-input) !important;
  background: var(--panel-sunken);
  box-shadow: var(--shadow-lg);
  pointer-events: none;
  white-space: nowrap;
  display: none;
  z-index: 4;
}
#portfolio-section .pf-tip-d { color: var(--text-muted); }
#portfolio-section .pf-tip-v {
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
#portfolio-section .pf-tip-m { margin-top: 2px; color: var(--text-muted); }

/* Crosshair: two dashed rules and a marker, drawn outside the svg so a mouse
   move never rebuilds the chart. The vertical rule follows the cursor; the
   horizontal one tracks the settled total under the cursor, not the cursor's
   own y, so it lines up with the value axis on the right. */
#portfolio-section .pf-cx-v,
#portfolio-section .pf-cx-h,
#portfolio-section .pf-cx-d {
  position: absolute;
  display: none;
  pointer-events: none;
  z-index: 3;
}
#portfolio-section .pf-cx-v {
  top: 14px;                 /* PADT */
  bottom: 12px;              /* PADB */
  width: 0;
  border-left: 1px dashed rgba(255, 255, 255, 0.28);
}
#portfolio-section .pf-cx-h {
  left: 6px;                 /* PADL */
  right: 58px;               /* PADR */
  height: 0;
  border-top: 1px dashed rgba(255, 255, 255, 0.28);
}
#portfolio-section .pf-cx-d {
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50% !important;
  border: 1.5px solid var(--card-bg);
}
#portfolio-section .pf-xax {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  padding-right: 56px;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

/* ---------- calendar ----------
   53 columns x 7 rows, inside the chart card. `drawCalendar` computes the
   cell size and gap from the column width; do not hardcode either here or
   the two disagree and the grid overflows the card. */
#portfolio-section .pf-cal {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding-top: 14px;
}
#portfolio-section .pf-cal[hidden] { display: none; }
#portfolio-section .pf-cal-months {
  display: flex;
  margin-left: 34px;
  height: 14px;
  color: var(--text-muted);
}
#portfolio-section .pf-cal-months > span {
  width: calc(var(--pf-cal-cell, 16px) + var(--pf-cal-gap, 3px));
  flex: 0 0 calc(var(--pf-cal-cell, 16px) + var(--pf-cal-gap, 3px));
  white-space: nowrap;
  overflow: visible;
}
#portfolio-section .pf-cal-body { display: flex; gap: 6px; margin-top: 4px; width: 100%; }
#portfolio-section .pf-cal-dow {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 28px;
  padding: 1px 0 20px;
  color: var(--text-muted);
}
#portfolio-section .pf-cal-grid { display: flex; gap: var(--pf-cal-gap, 3px); }
#portfolio-section .pf-cal-col { display: flex; flex-direction: column; gap: var(--pf-cal-gap, 3px); }
#portfolio-section .pf-cal-c {
  width: var(--pf-cal-cell, 16px);
  height: var(--pf-cal-cell, 16px);
  border-radius: var(--r-xs) !important;
  background: rgba(255, 255, 255, 0.04);
  display: block;
}
/* A day that settled at exactly zero is measured; an empty cell is
   unmeasured. The two must not share one colour. */
#portfolio-section .pf-cal-flat { background: var(--border-light); }
#portfolio-section .pf-cal-void { background: transparent; }
#portfolio-section .pf-cal-w1 { background: var(--positive); opacity: 0.25; }
#portfolio-section .pf-cal-w2 { background: var(--positive); opacity: 0.45; }
#portfolio-section .pf-cal-w3 { background: var(--positive); opacity: 0.7; }
#portfolio-section .pf-cal-w4 { background: var(--positive); opacity: 1; }
#portfolio-section .pf-cal-l1 { background: var(--negative); opacity: 0.25; }
#portfolio-section .pf-cal-l2 { background: var(--negative); opacity: 0.45; }
#portfolio-section .pf-cal-l3 { background: var(--negative); opacity: 0.7; }
#portfolio-section .pf-cal-l4 { background: var(--negative); opacity: 1; }
#portfolio-section .pf-cal-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 12px;
  color: var(--text-muted);
}
#portfolio-section .pf-cal-key { display: flex; align-items: center; gap: 3px; }
#portfolio-section .pf-cal-key .pf-cal-c { width: 11px; height: 11px; }
#portfolio-section .pf-cal-key .pf-cal-c:first-of-type { margin-left: 6px; }
#portfolio-section .pf-cal-key .pf-cal-c:last-of-type { margin-right: 6px; }

/* States that a filter is on and reaches further than the table, between the
   band and the tabs. */
#portfolio-section .pf-filtered {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding: 9px 14px;
  border: 1px solid var(--border-color);
  border-radius: var(--r-input) !important;
  background: var(--panel-sunken);
  color: var(--text-muted);
}
#portfolio-section .pf-filtered[hidden] { display: none; }
#portfolio-section .pf-filtered b {
  color: var(--text-primary);
}
#portfolio-section .pf-filtered-n { color: var(--text-muted); }

/* A refetch is running. The page keeps its last good render and dims it — it
   must not swap in the empty state, which reads as a page refresh flash. */
/* The 400ms DELAY is the point. Portfolio.show() runs sync() before it kicks
   refreshPositions()/loadTradeHistory(), so entering the page always produces
   a short refetch a moment after the content is already on screen — and the
   dim made that flash every single time you opened the page. A refetch that
   resolves inside 400ms now never becomes visible; only one slow enough to be
   worth reporting does. Recovery is NOT delayed (see the rule below), so the
   page brightens the instant the data lands. */
/* Everything below is DESKTOP-ONLY. portfolio.css hides #portfolio-section
   below 992px, but mobile.css re-shows it with
   `#portfolio-section[style*="display: block"] { display: block !important }`
   and mobile-ui.js calls Portfolio.show() on phones — so sync() toggles
   pf-busy / pf-first-load on the section at every width. Un-scoped, the
   dim, the skeleton and the band mask would all reach the mobile
   portfolio, which is a different surface. Mobile parity is a hard
   constraint (CLAUDE.md), so the whole block is gated. */
@media (min-width: 992px) {
  #portfolio-section.pf-busy:not(.pf-first-load) .pf-band,
  #portfolio-section.pf-busy:not(.pf-first-load) .pf-pane {
    opacity: 0.55;
    transition: opacity 0.18s ease 0.4s;
  }

  /* ---------- first load: a skeleton, not a dimmed void -------------------
     The dim above is right for a REFETCH — it preserves the last good render.
     On the first load there is nothing to preserve, so dimming showed an empty
     frame at 55% while the reader waited. pf-first-load (portfolio.js sync())
     marks that case; the panes paint shimmer rows instead (V2P.skel).       */
  #portfolio-section.pf-first-load .pf-band,
  #portfolio-section.pf-first-load .pf-pane { opacity: 1; }

  #portfolio-section .pf-skel-row {
    display: grid;
    align-items: center;
    height: 32px;
    padding: 0 12px;
    gap: 8px;
    border-bottom: 1px solid var(--v2-hair, rgba(255, 255, 255, .06));
  }
  #portfolio-section .pf-skel-row:last-of-type { border-bottom: 0; }

  #portfolio-section .pf-skel-row > i {
    height: 10px;
    border-radius: 3px;
    background: linear-gradient(90deg,
      var(--v2-chip, #232C42) 25%, var(--v2-chip-hover, #2C3752) 50%, var(--v2-chip, #232C42) 75%);
    background-size: 200% 100%;
    animation: pf-shimmer 1.4s linear infinite;
  }

  /* The band ships hardcoded "$0.00" in app.html, so removing the dim would
     print a crisp zero balance before the real figure lands — a value that is
     legal in its own range standing in for one nobody has measured yet. Mask
     the figure itself while first-loading; the LABEL stays, so the reader is
     told what is coming rather than what it is worth. */
  #portfolio-section.pf-first-load .pf-metric-v,
  #portfolio-section.pf-first-load .pf-ops-v,
  #portfolio-section.pf-first-load #pf-chart-value,
  /* The signed-value rules later in this file are `.pf-metric .v2-band-v.is-pos`
     at (1,3,0) !important, which OUTWEIGHS a plain (1,2,0) mask — so a P&L
     carrying a sign class would have stayed green or red on top of the skeleton,
     printing an unmeasured number in the exact colour that says "this is your
     result". Today that is unreachable (the sign class is only written from a
     parsed non-zero value, and the markup ships $0.00, so it cannot be on before
     the first paint) — but the mask must not depend on that ordering holding.
     These two carry (1,5,0) and win outright. Found by an adversarial CSS review;
     reproduced in Chrome before fixing. */
  #portfolio-section.pf-first-load .pf-metric .pf-metric-v.v2-band-v.is-pos,
  #portfolio-section.pf-first-load .pf-metric .pf-metric-v.v2-band-v.is-neg {
    color: transparent !important;
    border-radius: 3px;
    background: linear-gradient(90deg,
      var(--v2-chip, #232C42) 25%, var(--v2-chip-hover, #2C3752) 50%, var(--v2-chip, #232C42) 75%);
    background-size: 200% 100%;
    animation: pf-shimmer 1.4s linear infinite;
  }
  #portfolio-section.pf-first-load .v2-band-sub,
  #portfolio-section.pf-first-load #pf-chart-sub { visibility: hidden; }

  /* Own keyframe rather than revamp.css's v2-shimmer: that one is declared
     inside a @media (min-width: 992px) block in another file, and a cross-file
     dependency on a name nested in a media query is a silent break waiting to
     happen. Four lines is cheaper than the coupling. */
  @keyframes pf-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
  }

@media (prefers-reduced-motion: reduce) {
    #portfolio-section .pf-skel-row > i,
    #portfolio-section.pf-first-load .pf-metric-v,
    #portfolio-section.pf-first-load .pf-ops-v,
    #portfolio-section.pf-first-load #pf-chart-value {
      animation: none;
      background: var(--v2-chip, #232C42);
    }
  }
}

/* The visually-hidden status line clips at EVERY width. paintBand() appends
   #pf-band-sr into the band, which mobile renders too; the ODETTE_V2 gate
   keeps it empty below 992px, but an unstyled span that ever did get text
   would print it. This rule lived inside the 992 block while its comment
   claimed otherwise — a comment asserting a defence the braces did not
   deliver, which is the P-09 shape in .claude/rules/review-lessons.md.
   Moved out, so it now is what it says. */
#portfolio-section .pf-skel-sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

#portfolio-section .pf-band,
#portfolio-section .pf-pane { transition: opacity 0.18s ease; }

/* ---------- empty state: the band is replaced, never greyed out ---------- */
#portfolio-section .pf-blank {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 20px;
  border: 1px solid var(--border-color);
  border-radius: var(--r-card) !important;
  background: var(--card-bg);
}
#portfolio-section .pf-blank-t {
  color: var(--text-primary);
}
#portfolio-section .pf-blank-s {
  margin-top: 5px;
  color: var(--text-muted);
}

/* ---------- tabs + pane: one card, the tabs are its head ---------- */
#portfolio-section .pf-tabs {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 14px;
  padding: 0 14px;
  border: 1px solid var(--border-color);
  border-bottom: 0;
  border-radius: var(--r-card) var(--r-card) 0 0 !important;
  background: var(--card-bg);
}
#portfolio-section .pf-tabstrip { display: flex; }
/* Same register as the trade page's strip tabs (app.css:16194): uppercase,
   0.8125rem, 0.03em. Active underline is --primary, not --accent — --accent
   is the top strip's gold, reserved for the prize and for the action button
   above. */
#portfolio-section .pf-tab {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 13px 14px 11px;
  margin-bottom: -1px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}
#portfolio-section .pf-tab:hover { color: rgba(255, 255, 255, 0.8); }
#portfolio-section .pf-tab.active {
  color: #fff;
  border-bottom-color: var(--primary);
}
/* The count beside a tab label. Must be a `<span>`, not `<b>` or `<strong>`:
   their UA `bolder` weight resolves to 900 against the label's 600, off the
   weight ladder. `.t-num` sets family and numerals only, not weight. */
#portfolio-section .pf-tab .pf-tab-n {
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
/* Marks the context switch from the user's own money to a market-wide tab. */
#portfolio-section .pf-tab-split {
  align-self: center;
  width: 1px;
  height: 16px;
  margin: 0 10px;
  background: var(--border-color);
  display: block;
}
#portfolio-section .pf-tools { display: flex; gap: 6px; }
#portfolio-section .pf-tool {
  padding: 6px 10px;
  border: 1px solid var(--border-color);
  border-radius: var(--r-input) !important;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
#portfolio-section .pf-tool:hover { border-color: var(--border-light); color: var(--text-secondary); }
#portfolio-section .pf-tool.active {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-primary);
  border-color: var(--border-light);
}
#portfolio-section .pf-tool-sep {
  align-self: center;
  width: 1px;
  height: 16px;
  margin: 0 4px;
  background: var(--border-color);
  display: block;
}
/* The three history filters, same size as .pf-tool, so the row reads as one
   set of controls. */
#portfolio-section .pf-filter { position: relative; }
/* Outlined pill matched to `.pf-btn` beside it: same padding, radius, border,
   so the filters and actions read as one row of controls. Bootstrap's `.btn`
   still supplies the click target and `data-bs-toggle` still opens the menu;
   only the paint is ours. */
#portfolio-section .pf-filter-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  /* Right padding keeps the caret's 1rem well (app.css:5243). */
  padding: 8px 32px 8px 12px !important;
  border: 1px solid var(--border-color) !important;
  border-radius: var(--r-input) !important;
  /* `!important` on background and colour is required, not decorative.
     `.form-select-dropdown` (app.css:5225) declares every property
     `!important`, so a plain rule here always loses. With both important,
     specificity decides: `#portfolio-section .pf-filter-btn` (1,1,0) beats
     `.form-select-dropdown` (0,1,0). Without this the three filters render
     filled, mismatched against the transparent action buttons beside them. */
  background: transparent !important;
  color: var(--text-secondary) !important;
  white-space: nowrap;
}
#portfolio-section .pf-filter-btn:hover,
#portfolio-section .pf-filter-btn:focus {
  border-color: var(--border-light) !important;
  color: var(--text-primary) !important;
  background: transparent !important;
  box-shadow: none;
}
#portfolio-section .pf-filter-btn::after {
  content: '';
  width: 0;
  height: 0;
  border-left: 3.5px solid transparent;
  border-right: 3.5px solid transparent;
  border-top: 4px solid currentColor;
  opacity: 0.7;
}
/* Marks a filter that is not on "all", so a short result list is explained
   on screen. Same reason for `!important` as above. */
#portfolio-section .pf-filter-btn.pf-filter-on {
  border-color: var(--border-light) !important;
  background: rgba(255, 255, 255, 0.07) !important;
  color: var(--text-primary) !important;
}
#portfolio-section .pf-filter .dropdown-menu {
  min-width: 150px;
  padding: 4px;
  border: 1px solid var(--border-light);
  border-radius: var(--r-input) !important;
  background: var(--panel-sunken);
  box-shadow: var(--shadow-lg);
}
#portfolio-section .pf-filter .dropdown-item {
  padding: 6px 10px;
  border-radius: var(--r-xs) !important;
  color: var(--text-secondary);
}
#portfolio-section .pf-filter .dropdown-item:hover,
#portfolio-section .pf-filter .dropdown-item:focus {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text-primary);
}
#portfolio-section .pf-filter .dropdown-item.active {
  background: rgba(255, 255, 255, 0.1);
  color: var(--text-primary);
}

/* ---------- panes ---------- */
#portfolio-section .pf-pane {
  border: 1px solid var(--border-color);
  border-radius: 0 0 var(--r-card) var(--r-card) !important;
  background: var(--card-bg);
  overflow-x: auto;
}
#portfolio-section .pf-pane[hidden] { display: none; }

/* the market feed keeps its nine stats INSIDE its own pane, never in the band */
#portfolio-section .pf-ops {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-color);
  background: var(--panel-sunken);
}
/* EVEN TRACKS, full width. The row used to be a flex run with a note pinned
   right; the note is gone, and a flex run left the nine figures bunched at
   the left with a hole after them. Equal `1fr` columns give each figure the
   same room, so the labels below them line up as a rank of headers instead
   of drifting by word length. */
#portfolio-section .pf-ops-row {
  display: grid;
  grid-template-columns: repeat(9, minmax(0, 1fr));
  gap: 12px;
}
#portfolio-section .pf-ops-row > div { min-width: 0; }
#portfolio-section .pf-ops-v {
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
/* Not inline: copyStat() copies the source's inline colour, which is empty,
   so an inline value here is deleted on the first sync. */
/* Type tokens, not P&L tokens: a count of calls is not a profit. */
#portfolio-section #pf-ops-calls { color: var(--call-green); }
#portfolio-section #pf-ops-puts { color: var(--put-red); }
#portfolio-section #pf-ops-rangers { color: var(--ranger-purple); }

#portfolio-section .pf-ops-l {
  margin-top: 3px;
  color: var(--text-muted);
}
/* No "live" badge: `loadOpenPositionsData` (score.js) does not poll, it runs
   on nav, manual refresh, and load. The pane is a snapshot; add a live mark
   only if something starts polling. Ownership is carried by the tab labels
   ("My…" / "All Odette Positions") instead. */

/* ============================================================================
   TABLES
   The rows are the same HTML the trade-page strip renders. Every rule below
   is a re-scoped copy of one at app.css:16222-16399. Keep every selector
   under `#portfolio-section`.
   ========================================================================= */
#portfolio-section .pf-pane table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  background: transparent;
  --bs-table-bg: transparent;
  --bs-table-striped-bg: transparent;
  --bs-table-accent-bg: transparent;
  --bs-table-color: var(--text-primary);
  --bs-table-striped-color: var(--text-primary);
}
/* 11px header / 12px cell, the trade strip's scale (app.css:16285, :16348).
   Both surfaces show the same rows and must print them at one size. */
#portfolio-section .pf-pane thead th {
  padding: 0.85rem 16px;
  border: 0;
  border-bottom: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-muted);
  white-space: nowrap;
}
/* `.table` is required, as at app.css:16285: Bootstrap paints odd rows
   through `.table` at (0,2,2), so a lighter selector loses on odd rows. */
/* A ROW IS DATA, AND DATA IS PRINTED IN --text-primary.
   --text-secondary was reading as grey against the re-based dark card
   (#131A28) — measurably legible at 11.7:1, but a figure a trader compares
   down a column should not be dimmer than the page's plain text. Only the
   LABELS stay muted: the column header names the figure, it is not the
   figure. */
#portfolio-section .pf-pane .table > tbody > tr > td {
  padding: 0.7rem 16px;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  background: transparent;
  color: var(--text-primary);
  vertical-align: middle;
}
#portfolio-section .pf-pane tbody tr:last-child td { border-bottom: 0; }
#portfolio-section .pf-pane tbody tr:hover td { background: rgba(255, 255, 255, 0.025); }
#portfolio-section .pf-pane tbody tr.no-positions-message td,
#portfolio-section .pf-pane tbody tr.no-positions-message p {
  color: var(--text-muted);
  text-align: center;
}

/* --- 1 · The extra cell (app.css:16234) -----------------------------------
   `createPositionCard` emits 12 cells. `.col-date` and `.col-payout` are
   already hidden (app.css:7898, :7909), leaving `.col-belief` as an extra
   cell against the My Positions headers. Hidden here, not removed — the
   phone card and Positions page still read it. The ALL pane uses
   `.col-belief` as its Position column with its own header, so this hide is
   scoped to #pf-pane-mine only. */
#portfolio-section #pf-pane-mine tbody > tr > td.col-belief {
  display: none;
}

/* --- 2 · The asset sub-line repeats three other columns (app.css:16277) --- */
#portfolio-section .pf-pane tbody > tr > td.col-asset .position-cost-label {
  display: none;
}

/* --- 3 · Numerals line up (app.css:16251) --------------------------------
   Right-aligned and tabular: these figures are compared down a column.
   Token split stated at app.css:42. */
#portfolio-section .pf-pane th.col-strike,
#portfolio-section .pf-pane th.col-settlement,
#portfolio-section .pf-pane th.col-size,
#portfolio-section .pf-pane th.col-cost,
#portfolio-section .pf-pane th.col-current-price,
#portfolio-section .pf-pane th.col-premium,
#portfolio-section .pf-pane th.col-premium-usd,
#portfolio-section .pf-pane th.col-pnl,
#portfolio-section .pf-pane th.col-pnl-usd,
#portfolio-section .pf-pane th.col-time-left,
#portfolio-section .pf-pane td.col-strike,
#portfolio-section .pf-pane td.col-settlement,
#portfolio-section .pf-pane td.col-size,
#portfolio-section .pf-pane td.col-cost,
#portfolio-section .pf-pane td.col-current-price,
#portfolio-section .pf-pane td.col-premium,
#portfolio-section .pf-pane td.col-premium-usd,
#portfolio-section .pf-pane td.col-pnl,
#portfolio-section .pf-pane td.col-pnl-usd,
#portfolio-section .pf-pane td.col-time-left {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
#portfolio-section .pf-pane .col-size,
#portfolio-section .pf-pane .col-cost,
#portfolio-section .pf-pane .col-premium,
#portfolio-section .pf-pane .col-premium-usd,
#portfolio-section .pf-pane .col-current-price,
#portfolio-section .pf-pane .col-settlement,
#portfolio-section .pf-pane .col-strike,
#portfolio-section .pf-pane .col-pnl,
#portfolio-section .pf-pane .col-pnl-usd,
#portfolio-section .pf-pane .col-time-left {
  /* Inter, like every other cell. Inter with `tabular-nums` gives all ten
     digits one width, so a mono face is not needed and would split one
     table across two typefaces. */
  font-family: var(--sans);
}

/* --- 3a1 · One register for every header -----------------------------------
   `.user-positions-table thead th` and `.history-table thead th` in `app.css`
   set `var(--font-size-base)` at 700, at (0,2,1), beating `.t-col` at
   (0,1,0). Reset at id specificity, reading the same tokens `.t-col` reads. */
#portfolio-section .pf-pane thead th {
  font-size: var(--fs-micro);
  font-weight: 600;
}

/* --- 3a2 · One size for every cell -----------------------------------------
   `app.css` emphasises the current price at `calc(var(--font-size-base) + 5px)`
   on the Positions page, reaching these panes via `nth-child(7)` at (0,3,1),
   beating `.t-table` at (0,1,3). An nth-child rule breaks if a column is
   added or reordered. Reset by class here, at id specificity, reading the
   same token `.t-table` reads. */
#portfolio-section .pf-pane .table > tbody > tr > td.col-current-price,
#portfolio-section .pf-pane .table > tbody > tr > td.col-cost,
#portfolio-section .pf-pane .table > tbody > tr > td:nth-child(7) {
  font-size: var(--fs-data);
}

/* --- 3b · The USD columns ---------------------------------
   `.col-premium-usd` and `.col-pnl-usd` stay hidden (app.css:5999) on every
   `.history-table`, this page included. The rail and chart above already
   show P&L in dollars; showing it again here would be two columns for one
   number, on a book whose collateral is already a dollar stablecoin. */

/* --- 4 · Two levels of emphasis (app.css:16293) --------------------------- */
#portfolio-section .pf-pane .table > tbody > tr > td.col-asset strong {
  font-weight: 600;
  color: var(--text-primary);
}
#portfolio-section .pf-pane .table > tbody > tr > td.col-pnl {
  font-weight: 600;
}
/* Rows arrive with Bootstrap's .text-danger / .text-success (#dc3545 /
   #198754), colours that appear nowhere else in this theme. Same override
   as the trade strip (app.css:16305), at the one site its selector does not
   reach. `!important` is required because Bootstrap's utilities use it. */
#portfolio-section .pf-pane .table > tbody > tr > td.col-pnl.text-danger,
#portfolio-section .pf-pane .table > tbody > tr > td.col-pnl-usd.text-danger {
  color: var(--negative) !important;
}
#portfolio-section .pf-pane .table > tbody > tr > td.col-pnl.text-success,
#portfolio-section .pf-pane .table > tbody > tr > td.col-pnl-usd.text-success {
  color: var(--positive) !important;
}
#portfolio-section .pf-pane .table > tbody > tr > td.col-pnl.text-muted {
  color: var(--text-muted) !important;
}
/* Separates the value and percentage spans, which otherwise render as one
   run of glyphs (app.css:16321). */
#portfolio-section .pf-pane tbody > tr > td.col-pnl .pnl-pct {
  margin-left: 0.4em;
  font-weight: 400;
  opacity: 0.75;
}

/* --- 5 · Type band (app.css:16331) ---------------------------------------- */
#portfolio-section .pf-pane tbody > tr { border-left: 3px solid transparent; }
#portfolio-section .pf-pane tbody > tr[data-option-type="call"] { border-left-color: var(--positive); }
#portfolio-section .pf-pane tbody > tr[data-option-type="put"] { border-left-color: var(--negative); }
#portfolio-section .pf-pane tbody > tr[data-option-type="ranger"] { border-left-color: var(--ranger-purple); }

/* --- 6 · No glow on the countdown (app.css:16356) --------------------------
   `.countdown` is declared twice (app.css:3679, :3693). The second overrides
   everything except `text-shadow` and `animation: pulse-glow`. Killed here
   too, scoped to this surface so the Positions page and phone keep theirs.
   The ALL pane's Position sentence uses the same countdown, so both
   selectors are named. */
#portfolio-section .pf-pane tbody > tr > td.col-time-left .countdown,
#portfolio-section .pf-pane tbody > tr > td.col-belief .countdown {
  text-shadow: none;
  animation: none;
  font-size: var(--fs-data);
  font-weight: 600;
  letter-spacing: 0;
}
#portfolio-section .pf-pane tbody > tr > td.col-belief .countdown {
  color: var(--text-primary);
}

/* --- 7 · "View Option" is a link out (app.css:16371) -----------------------
   Two icons ship in the markup; each context shows one. The label stays in
   the DOM and is hidden only visually — an icon-only control needs an
   accessible name. */
#portfolio-section .pf-pane .view-option-btn .view-option-icon-doc {
  display: none;
}
#portfolio-section .pf-pane .view-option-btn .view-option-icon-ext {
  display: inline-block;
}
#portfolio-section .pf-pane .view-option-btn {
  border: none;
  background: none;
  padding: 0.25rem;
  color: var(--text-muted);
}
#portfolio-section .pf-pane .view-option-btn:hover {
  color: var(--primary);
  background: none;
}
#portfolio-section .pf-pane .view-option-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- 8 · A badge marks the exception, not the rule (app.css:16420) --------
   `settled` is the ordinary end state: it reads as quiet text. The other
   three statuses keep the pill. */
#portfolio-section .pf-pane .col-actions { text-align: right; white-space: nowrap; }
#portfolio-section .pf-pane .position-asset-logo {
  width: 18px;
  height: 18px;
  border-radius: 50% !important;
  margin-right: 8px;
  vertical-align: middle;
}
/* Generated markup, shared with the History page, the trade strip and the
   phone card. Id-scoped, not a `.t-col` class, so this rule cannot leak onto
   those surfaces; it reads the same tokens `.t-col` reads. Weight is stated
   for both states: `.status-badge` inherits 500 from app.css:7390, which is
   off the weight ladder and must be overridden on both selectors. */
#portfolio-section .pf-pane .status-badge {
  display: inline-block;
  padding: 2px 7px;
  border: 1px solid var(--border-color);
  border-radius: var(--r-xs) !important;
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: var(--tr-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  background: transparent;
}
#portfolio-section .pf-pane .status-badge.status-settled {
  background: none;
  border: 0;
  padding: 0;
  color: var(--text-muted);
  font-weight: 400;
}
#portfolio-section .pf-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 16px;
  border-top: 1px solid var(--border-color);
  color: var(--text-muted);
}

/* Below 992px the phone keeps mobile-ui.js and its own pages. This surface
   is desktop-only, same as the trade page redesign. */
@media (max-width: 991px) {
  #portfolio-section { display: none !important; }
}

@media (max-width: 1200px) {
  #portfolio-section .pf-band { grid-template-columns: 260px minmax(0, 1fr); }
}

/* ---- Trollbox safe area — REMOVED 2026-09-08 --------------------------
   This section used to reserve `padding-bottom: 440px` under
   `body:has(.trollbox-widget:not(.minimized):not(.hidden))`, so table rows
   could scroll clear of a chat widget that floated over the bottom-right
   corner at `position: fixed; bottom: 20px; right: 20px`.

   v2 moved the widget into the right rail: revamp.css sets
   `position: static !important; inset: auto !important` on
   `body.v2 #v2-chat > .trollbox-widget` at >=992px, and `body.v2` is
   hardcoded in app.html, so at every desktop width the widget covers
   nothing. Worse, V2Chat.init strips `.minimized`/`.hidden` and re-strips
   them from a MutationObserver, so the `:has()` guard could never go false
   — the reservation never released. On the portfolio page the widget has no
   layout box at all (its `#trade-section` is display:none), yet the tail was
   still reserved: 440px of dead space, and `documentElement.scrollHeight`
   904 against a 705 viewport, which also failed test-v2-contract's
   `doc-no-scroll` assertion.

   Below 992px mobile.css floats the widget again, but `#portfolio-section`
   is `display: none !important` there, so nothing needs reserving. */

/* ---- Focus visibility ---------------------------------------------------
   The `.pf-filter-btn:hover, :focus` rule earlier in this file sets
   `box-shadow: none` to keep the filters flush with the action buttons beside
   them. That removed the
   only sign of keyboard focus on this page, and nothing replaced it: a user
   who navigates by Tab could not tell which control was selected.

   Restore it with :focus-visible, which the browser sets for keyboard focus
   and not for a mouse press — so the buttons stay flush when clicked and show
   a ring when tabbed to. Every interactive control on this page is listed:
   a ring on the filters alone would just move the blind spot. */
#portfolio-section .pf-filter-btn:focus-visible,
#portfolio-section .pf-tab:focus-visible,
#portfolio-section .pf-btn:focus-visible,
#portfolio-section .pf-chip:focus-visible,
#portfolio-section .pf-view:focus-visible,
#portfolio-section .dropdown-item:focus-visible {
  /* --primary, not --accent. Gold means money that will be paid and nothing
     else, and a focus ring is not money; the Scoreboard already rings in
     --primary, so the two pages ringed differently for the same event.
     The radius is gone: it carried no !important, so the >=992px square
     sweep at app.css zeroed it — a declaration that could never take
     effect. */
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* ---- Positions retirement ------------------------------------------------
   Portfolio replaces the old Positions page on desktop. Hide the nav item;
   do not remove it. `showSection` still calls
   `$("#nav-positions").addClass("active")` on the paths that reach the old
   section, and the Scoreboard still lives inside it, so the element has to
   stay in the DOM and stay harmless when written to.

   Remove the body class (config.js RETIRE_POSITIONS) to put the item back. */
body.retire-positions .navbar-nav .nav-item:has(> #nav-positions) {
  display: none;
}


/* ==========================================================================
   v2 · OPEN POSITIONS AS TICKETS (>=992px). Cards built by renderCards()
   from the cloned rows; the table stays as the data source and the phone
   face. Type colours ride the shared tokens.
   ========================================================================== */
.pf-cards {
  display: none;
}

@media (min-width: 992px) {
  /* The serif page title — the v2 house headline face. */
  .pf-title {
    font-family: var(--v2-display, 'Geist', sans-serif);
    font-size: 26px;
    font-weight: 600;
    letter-spacing: -0.02em;
  }

  /* round 10: filled controls, no borders; selected = solid sky; tabs = chip-active */
  #portfolio-section .pf-btn {
    border: 0;
    background: var(--v2-chip, #232C42);
    box-shadow: var(--v2-chip-lift);
    color: var(--text-secondary);
  }
  #portfolio-section .pf-btn:hover { background: var(--v2-chip-hover, #2C3752); color: var(--text-primary); }
  #portfolio-section .pf-chips,
  #portfolio-section .pf-views { border: 0; background: var(--panel-sunken); }
  #portfolio-section .pf-view.active,
  #portfolio-section .pf-chip.active { background: var(--v2-sky, #7DD3FC); color: var(--v2-on-sky, #07131C); }
  #portfolio-section .pf-tool {
    border: 0;
    background: var(--v2-chip, #232C42);
    box-shadow: var(--v2-chip-lift);
    color: var(--text-secondary);
  }
  #portfolio-section .pf-tool:hover { background: var(--v2-chip-hover, #2C3752); color: var(--text-primary); }
  #portfolio-section .pf-tool.active { background: var(--v2-sky, #7DD3FC); box-shadow: none; color: var(--v2-on-sky, #07131C); }
  #portfolio-section .pf-filter-btn {
    border: 0 !important;
    background: var(--v2-chip, #232C42) !important;
    box-shadow: var(--v2-chip-lift);
    color: var(--text-secondary) !important;
  }
  #portfolio-section .pf-filter-btn:hover,
  #portfolio-section .pf-filter-btn:focus { background: var(--v2-chip-hover, #2C3752) !important; color: var(--text-primary) !important; }
  #portfolio-section .pf-tab {
    padding: 7px 12px;
    margin-bottom: 0;
    border-bottom: 0;
    border-radius: var(--v2-r-ctl, 8px) var(--v2-r-ctl, 8px) 0 0 !important;
    color: var(--text-muted);
    font-weight: 500;
  }
  #portfolio-section .pf-tab.active {
    color: var(--text-primary);
    background: var(--v2-chip, #232C42);
    box-shadow: var(--v2-chip-lift);
    border-bottom-color: transparent;
    font-weight: 600;
  }

}


/* ==========================================================================
   v2 · THE BAND, FULL-WIDTH (>=992px — the Portfolio board). The 316px rail
   grid folds into one stacked band: hero numeral + inline sub, the cluster
   (Win rate / Best return / Avg ticket) as hairline-divided columns, the
   outcome CHIPS, and the sparkline running the whole width beneath. The
   retired tiles and the wl-bar stay in the DOM as the mobile face.
   ========================================================================== */
@media (min-width: 992px) {
  #portfolio-section .pf-band {
    display: block;
    gap: 0;
  }

  #portfolio-section .pf-rail {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    gap: 26px;
    border: 0;
    background: transparent;
    padding: 0 0 10px;
    width: 100%;
    max-width: none;
  }

  #portfolio-section .pf-rail-hero {
    border: 0;
    background: transparent;
    padding: 0;
  }

  #portfolio-section .pf-hero {
    font-family: var(--v2-display, 'Geist', sans-serif);
    font-size: 46px;
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
  }

  #portfolio-section .pf-hero-sub { margin-top: 5px; color: var(--text-muted); }
  #portfolio-section .pf-hero-sub[hidden] { display: none; }

  /* the bar + key yield to the chips on desktop */
  #portfolio-section .pf-wl, #portfolio-section .pf-wlk { display: none; }

  #portfolio-section .pf-wl-chips { display: flex; gap: 5px; margin-top: 10px; }
  #portfolio-section .pf-wl-chips[hidden] { display: none; }

  #portfolio-section .pf-wlc {
    background: var(--panel-hover, rgba(255, 255, 255, 0.05));
    color: var(--text-muted);
    font-size: 0.65625rem;
    padding: 4px 10px;
    border-radius: 7px;
  }

  #portfolio-section .pf-wlc.is-open {
    background: rgba(255, 255, 255, 0.09);
    color: var(--text-primary);
    font-weight: 600;
  }

  /* the cluster: three columns, hairline-divided, pushed right */
  #portfolio-section .pf-metrics {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    margin-left: auto;
    gap: 0;
    align-items: flex-end;
    border: 0;
    background: transparent;
    padding: 0;
    width: auto;
  }

  #portfolio-section .pf-metrics .pf-metric {
    display: block;
    justify-content: normal;
    width: auto;
    background: transparent;
  }

  #portfolio-section .pf-metrics .pf-metric-v {
    font-size: 1rem;
    font-weight: 700;
    text-align: left;
  }

  #portfolio-section .pf-metrics .pf-metric.pf-metric-retired { display: none; }

  #portfolio-section .pf-metrics .pf-metric {
    border-left: 1px solid rgba(255, 255, 255, 0.06);
    padding: 0 22px;
  }

  #portfolio-section .pf-metrics .pf-metric-l {
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 4px;
    text-align: left;
    white-space: nowrap;
  }

  /* the chart runs full-bleed under the band */
  #portfolio-section .pf-chart {
    border: 0;
    background: transparent;
    padding: 0;
  }

  #portfolio-section .pf-chart-title { display: none; }

  /* white primaries — the v2 house rule */
  #portfolio-section .pf-btn-pri {
    background: #FDFDFD;
    border-color: #FDFDFD;
    color: #0F1520;
  }

  #portfolio-section .pf-btn-pri:hover {
    background: #FFFFFF;
    box-shadow: none;
  }

  /* rangers are sky, not purple, in the v2 palette */
  #portfolio-section #pf-ops-rangers { color: #7DD3FC; }

}


/* ==========================================================================
   v2 · ROUND 10 — the page system on the Portfolio (>=992px). The band is
   `.v2-band` (page-system.css), the ledgers are the positions strip, the
   blank face is `.v2-blank` beside the Everyone's-open strip.
   ========================================================================== */
@media (min-width: 992px) {
  /* the band rides the hero's baseline and takes the rest of the row */
  #portfolio-section .pf-metrics.v2-band {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: 26px;
    align-self: stretch;
    align-items: stretch;
    border-radius: 8px !important; /* the radius sweep in app.css is !important too; round 13: the panel radius */
  }

  #portfolio-section .pf-rail { padding-bottom: 14px; }

  #portfolio-section .pf-rail-hero { flex: 0 0 auto; }

  /* the hero's sub retires — its facts moved into the band */
  #portfolio-section #pf-hero-sub { display: none; }

  /* the sparkline: no chrome, no micro-copy */
  #portfolio-section #pf-chart-note { display: none; }

  /* section label above the open cards */
  #portfolio-section #pf-open-section { margin: 12px 0 0; }
  #portfolio-section #pf-open-section[hidden] { display: none; }

  /* cards: kind wash + the P&L split */

  /* the strips: the trade page's positions strip, inside the pane card */
  #portfolio-section .v2-pf-strip { padding: 0 4px; }
  #portfolio-section .v2-pf-strip .v2-pos-who {
    color: var(--text-primary);
    font-weight: 600;
  }
  #portfolio-section .v2-pf-strip .v2-pos-status { text-align: left; }

  /* tab row: the right-hand fact */
  #portfolio-section #pf-tabs-r {
    margin-left: auto;
    align-self: center;
    white-space: nowrap;
    font-size: 0.65625rem;
    color: var(--text-muted);
  }
  #portfolio-section #pf-tabs-r[hidden] { display: none; }

  /* the blank face: card left, Everyone's open right */
  #portfolio-section .pf-wrap.pf-is-blank {
    display: grid;
    grid-template-columns: 420px minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    column-gap: 24px;
    align-items: start;
  }
  #portfolio-section .pf-is-blank > .pf-head { grid-column: 1 / -1; grid-row: 1; }
  #portfolio-section .pf-is-blank > .pf-blank { grid-column: 1; grid-row: 2 / span 2; margin-top: 14px; }
  #portfolio-section .pf-is-blank > .pf-tabs { grid-column: 2; grid-row: 2; }
  #portfolio-section .pf-is-blank > .pf-pane { grid-column: 2; grid-row: 3; }
  #portfolio-section .pf-is-blank > .pf-band,
  #portfolio-section .pf-is-blank > .pf-filtered { grid-column: 1 / -1; }
  #portfolio-section .pf-is-blank #pf-tab-mine,
  #portfolio-section .pf-is-blank #pf-tab-hist,
  #portfolio-section .pf-is-blank .pf-tab-split { display: none; }
  #portfolio-section .pf-blank.v2-blank #pf-blank-trade { margin-top: 6px; }
}

/* the desktop-only band cell and blank glyph never show on the phone face */
@media (max-width: 991.98px) {
  #portfolio-section .pf-metric-desk,
  #portfolio-section .v2-blank-glyph,
  #portfolio-section #pf-blank-quick { display: none !important; }
}

/* ==========================================================================
   ROUND 11 — square tables, no pane card, everyone's-open stats as cards,
   one card radius.
   ========================================================================== */
@media (min-width: 992px) {
  #portfolio-section .pf-tabs {
    border: 0;
    background: transparent;
    padding: 0 0 8px;
    margin-top: 14px;
    border-radius: 0 !important;
  }
  #portfolio-section .pf-pane {
    border: 0;
    background: transparent;
    border-radius: 0 !important;
    overflow: visible;
  }
  #portfolio-section .pf-tab,
  #portfolio-section .pf-tab.active { border-radius: 0 !important; }
  #portfolio-section .pf-tools { padding-right: 0; }

  #portfolio-section .pf-blank { border-radius: var(--v2-r-card-sm, 12px) !important; }

  /* the market stats above everyone's open: the same small cards as the band */
  #portfolio-section .pf-ops { padding: 0; border: 0; background: transparent; margin: 0 0 14px; }
  #portfolio-section .pf-ops-row {
    display: flex !important;
    gap: 10px;
  }
  #portfolio-section .pf-ops-row > div {
    flex: 1 1 0;
    min-width: 0;
    background: var(--card-bg, #0E1322);
    border: 1px solid var(--v2-hair-strong, rgba(255, 255, 255, .13));
    border-radius: var(--v2-r-card-sm, 12px) !important;
    padding: 10px 12px;
  }
  #portfolio-section .pf-ops-v {
    font-size: 0.9375rem;
    font-weight: 700;
    line-height: 1.1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #portfolio-section .pf-ops-l {
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-top: 3px;
    white-space: nowrap;
  }
}


/* ==========================================================================
   ROUND 13 — the quiet system on the Portfolio (>=992px). Big tabs (Overview ·
   History · Everyone's open) under the header; the band is the stat panel
   (Total P&L · Win rate · Premium spent · At work now, each with a sub);
   the chart is a panel with the range switcher in its head; every pane is a
   panel whose rows are the trade strip's rows (V2P.mine / hist / all). The
   cards are gone; the hero rail is gone.
   ========================================================================== */
@media (min-width: 992px) {
  #portfolio-section .pf-wrap { display: block; }

  /* header: the status filter leaves the desktop row (mobile proxy keeps it) */
  #portfolio-section .pf-filters { display: inline-flex; gap: 8px; }
  #portfolio-section .pf-filter:has(#pf-history-status) { display: none; }
  #portfolio-section .pf-filter-btn { min-width: 0; }
  #portfolio-section .pf-filter-btn::after { margin-left: 6px; }

  /* big tabs */
  #portfolio-section .pf-tabs {
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
  }
  #portfolio-section .pf-tabstrip.v2-bigtabs { display: flex !important; }
  #portfolio-section .pf-tab-split { display: none !important; }
  #portfolio-section #pf-tab-mine .pf-tab-n { display: none; }

  /* the band: one block, the stat panel above the chart panel */
  #portfolio-section .pf-band { display: block; gap: 0; }
  #portfolio-section .pf-band[hidden] { display: none; }
  #portfolio-section .pf-rail { display: block; margin: 0; padding: 0; border: 0; background: transparent; }
  #portfolio-section .pf-rail-hero { display: none !important; }
  #portfolio-section .pf-metrics.v2-band { margin: 0 0 12px !important; flex: none; }
  #portfolio-section .pf-metric .pf-metric-v { color: var(--text-primary); }
  #portfolio-section .pf-metric .v2-band-v.is-pos { color: var(--positive) !important; }
  #portfolio-section .pf-metric .v2-band-v.is-neg { color: var(--negative) !important; }
  #portfolio-section #pf-total-pnl { font-family: var(--sans) !important; font-size: 22px !important; font-weight: 600 !important; letter-spacing: -0.01em !important; line-height: 1.1 !important; }

  /* the chart panel */
  #portfolio-section .pf-chart.v2-panel { padding: 0; border: 0; background: var(--card-bg, #0E1322); margin: 0 0 12px; }
  #portfolio-section .pf-chart-top.v2-panel-head { margin: 0; padding: 0 16px !important; }
  #portfolio-section .pf-chart-title { display: inline !important; font-family: var(--sans); font-size: 12px; font-weight: 600; color: var(--text-primary); }
  #portfolio-section #pf-chart-note { display: none; }
  #portfolio-section .pf-chart-ctl { display: inline-flex; align-items: center; gap: 8px; }
  #portfolio-section .pf-chart-read { display: none !important; }
  #portfolio-section #pf-view-line { padding: 16px 16px 10px; }
  /* the chart is a block panel, not a flex column: the plot is exactly the
     SVG's 200px floor (drawChart), no stretch */
  #portfolio-section .pf-chart.v2-panel { display: block !important; min-height: 0 !important; height: auto !important; flex: none; overflow: visible; }
  #portfolio-section .pf-plot, #portfolio-section .pf-plot svg { overflow: visible; }
  #portfolio-section .pf-plot { height: 200px !important; min-height: 0 !important; max-height: none; flex: none !important; }
  #portfolio-section #pf-view-line { min-height: 0; flex: none; }
  #portfolio-section .pf-xax { margin-top: 6px; font-size: 11px; color: var(--text-muted); }
  #portfolio-section .pf-cal { padding: 16px; }
  #portfolio-section .pf-plot-note { border: 0; background: transparent; }
  #portfolio-section .pf-plot-note-t { font-family: var(--sans); font-size: 12px; font-weight: 500; color: var(--text-secondary); }
  #portfolio-section .pf-plot-note-s { font-size: 12px; color: var(--text-muted); }

  /* the filtered banner: a muted line */
  #portfolio-section .pf-filtered { border: 0; background: transparent; padding: 0 0 10px; font-size: 12px; color: var(--text-muted); }

  /* the panes: panels */
  #portfolio-section .pf-pane.v2-panel { padding: 0 !important; margin: 0 !important; border: 0; background: var(--card-bg, #0E1322); }
  #portfolio-section .pf-pane[hidden] { display: none !important; }
  #portfolio-section .pf-pane .v2-panel-head .pf-tools { display: inline-flex; gap: 2px; margin: 0 !important; padding: 0 !important; }
  #portfolio-section .pf-pane .v2-panel-head .pf-tools[hidden] { display: none; }
  #portfolio-section .pf-pane .v2-pf-strip { padding: 0 !important; }
  #portfolio-section .pf-pane .pgr { margin: 0; padding: 8px 16px; border-top: 1px solid var(--v2-hair, rgba(255, 255, 255, .06)); justify-content: flex-end; }
  #portfolio-section .pf-pane .pgr:empty { display: none; }
  #portfolio-section .pgr-sel { height: 24px; padding: 0 9px; border: 0; border-radius: 5px; background: var(--v2-chip, #232C42); font-size: 11px; }
  #portfolio-section .pgr-lbl, #portfolio-section .pgr-of { font-size: 11px; }
  #portfolio-section .pgr-btn { border: 0; background: var(--v2-chip, #232C42); border-radius: 5px; width: 24px; height: 24px; color: var(--text-secondary); }
  #portfolio-section .pgr-btn:disabled { opacity: .4; }
  #portfolio-section .pf-cards { display: none !important; }
  #portfolio-section #pf-open-section { display: none !important; }
  #portfolio-section #pf-tabs-r { display: none !important; }
  #portfolio-section .pf-ops { display: none !important; }

  /* the sort tools inside the Everyone's-open head are the switcher */
  #portfolio-section .pf-pane .v2-panel-head .pf-tools {
    padding: 2px !important;
    background: var(--panel-sunken, #070A11);
    border-radius: 7px;
  }
  #portfolio-section .pf-pane .v2-panel-head .pf-tool {
    height: 24px !important;
    padding: 0 10px !important;
    border-radius: 5px !important;
    background: transparent !important;
    color: var(--text-muted) !important;
    font-size: 12px !important;
    font-weight: 500 !important;
  }
  #portfolio-section .pf-pane .v2-panel-head .pf-tool:hover { color: var(--text-secondary) !important; }
  #portfolio-section .pf-pane .v2-panel-head .pf-tool.active { background: var(--v2-chip, #232C42) !important; color: var(--text-primary) !important; }

  /* the blank face: a panel beside Everyone's open */
  #portfolio-section .pf-wrap.pf-is-blank {
    display: grid;
    grid-template-columns: 420px minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    column-gap: 12px;
    align-items: start;
  }
  #portfolio-section .pf-is-blank > .pf-head { grid-column: 1 / -1; grid-row: 1; }
  #portfolio-section .pf-is-blank > .pf-tabs { grid-column: 1 / -1; grid-row: 2; }
  #portfolio-section .pf-is-blank > .pf-blank { grid-column: 1; grid-row: 3; margin: 0; }
  #portfolio-section .pf-is-blank > .pf-pane { grid-column: 2; grid-row: 3; }
  #portfolio-section .pf-is-blank > .pf-band,
  #portfolio-section .pf-is-blank > .pf-filtered { grid-column: 1 / -1; }
  #portfolio-section .pf-blank.v2-blank #pf-blank-trade { margin-top: 0; }
  /* the blank page shows one big tab: no divider stub before it */
  #portfolio-section .pf-is-blank #pf-tab-all { border-left: 0 !important; margin-left: 0 !important; padding-left: 0 !important; }
}

/* the panel radius, stated with the section's own specificity now that app.css's
   square sweep no longer reaches body.v2 (it had been masking a 10px chart, a 12px
   blank and a squared pane) */
@media (min-width: 992px) {
  #portfolio-section .pf-wrap .pf-chart.v2-panel,
  #portfolio-section .pf-wrap .pf-pane.v2-panel,
  #portfolio-section .pf-wrap .pf-blank.v2-blank,
  #portfolio-section .pf-wrap .pf-metrics.v2-band { border-radius: 8px !important; }
}

/* round 14 (2026-09-29): the blank face is one full-width line — what is
   missing and the one action — with Everyone's open full width beneath it.
   The sentence moves to the panel's tooltip (portfolio.js setBlankCopy). */
@media (min-width: 992px) {
  #portfolio-section .pf-wrap.pf-is-blank { grid-template-columns: minmax(0, 1fr); }
  #portfolio-section .pf-is-blank > .pf-blank {
    grid-column: 1; grid-row: 3;
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: 12px;
    min-height: 0 !important;
    padding: 12px 16px !important;
    margin: 0 0 12px !important;
    text-align: left !important;
  }
  #portfolio-section .pf-is-blank > .pf-blank[hidden] { display: none !important; }
  #portfolio-section .pf-is-blank > .pf-blank .pf-blank-t { margin-right: auto !important; color: var(--text-primary) !important; }
  #portfolio-section .pf-is-blank > .pf-blank .pf-blank-s {
    position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  #portfolio-section .pf-is-blank > .pf-blank .v2-blank-acts { margin: 0 !important; }
  #portfolio-section .pf-is-blank > .pf-pane { grid-column: 1; grid-row: 4; }
}
