/* =========================================================
   Apes Alpha — Seasonality (Simple) page
   ========================================================= */

:root {
  --bg:       #1a1a1a;
  --panel:    #232323;
  --panel-2:  #2b2b2b;
  --panel-3:  #313131;
  --border:   #383838;
  --text:     #ececec;
  --muted:    #9b9b9b;
  --accent:   #1f9be0;
  --accent-d: #1580bd;
  --green:    #35c26a;
  --danger:   #e0576a;
  --radius:   12px;
  --shadow:   0 6px 20px rgba(0, 0, 0, .35);
}

* { box-sizing: border-box; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  line-height: 1.6;
  margin: 0;
  padding: 0;
}

h1, h2, h3, h4, h5 { color: var(--text); margin-top: 0; text-align: left; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- Page shell ---------- */
.season-page {
  max-width: 1360px;
  margin: 0 auto;
  padding: 24px 20px 64px;
}

.season-head { text-align: center; margin-bottom: 4px; }
.season-head h3 {
  display: flex;
  gap: 12px;
  justify-content: center;
  align-items: baseline;
  flex-wrap: wrap;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: .2px;
  text-align: center;
}
.season-head .adv-link {
  font-size: .8rem;
  font-weight: 600;
  padding: 3px 11px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--muted);
}
.season-head .adv-link:hover {
  color: var(--text);
  border-color: var(--accent);
  text-decoration: none;
}

/* ---------- Alerts ---------- */
.season-alert {
  max-width: 720px;
  margin: 12px auto 4px;
  text-align: center;
  font-size: .95rem;
}
.season-alert.error { color: var(--danger); font-weight: 700; }
.season-alert.info {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 16px;
  color: var(--muted);
}
.season-alert.info a { font-weight: 700; white-space: nowrap; }

/* ---------- Layout ---------- */
.season-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  grid-template-areas: "main aside";
  gap: 24px;
  align-items: start;
  margin-top: 18px;
}
.season-main  { grid-area: main; min-width: 0; }
.season-aside { grid-area: aside; min-width: 0; }

/* simple-seasonality: give the month grid more room, slim the watchlist rail */
@media (min-width: 993px) {
  .season-layout.sl-tight { grid-template-columns: minmax(0, 1fr) 176px; gap: 16px; }
}
.sl-tight .wl-card { padding: 10px; }
.sl-tight .wl-head h5 { font-size: .82rem; }
.sl-tight .wl-hint { font-size: .62rem; }
.sl-tight #watchlist { gap: 2px; }
.sl-tight .wl-item { padding: 5px 6px; font-size: .78rem; gap: 6px; }
.sl-tight .wl-item .wl-tkr { font-size: .78rem; }
.sl-tight .wl-add input { padding: 6px 8px; font-size: .78rem; }
.sl-tight .wl-add button { padding: 6px 8px; font-size: .74rem; }

/* ---------- Toolbar ---------- */
.toolbar-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
  margin-bottom: 20px;
}

.search-wrap {
  position: relative;
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
}
#search-input {
  width: 100%;
  padding: 11px 14px;
  font-size: .98rem;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 9px;
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
#search-input::placeholder { color: #7d7d7d; }
#search-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(31, 155, 224, .18);
}

#search-results {
  display: none;
  list-style: none;
  position: absolute;
  left: 0;
  right: 0;
  z-index: 1000;
  margin: 6px 0 0;
  padding: 4px;
  background: #fff;
  color: #1a1a1a;
  border: 1px solid #cfcfcf;
  border-radius: 9px;
  max-height: 320px;
  overflow-y: auto;
  box-shadow: 0 14px 34px rgba(0, 0, 0, .45);
}
#search-results li {
  padding: 8px 10px;
  border-radius: 6px;
  font-size: .9rem;
  cursor: pointer;
}
#search-results li:hover,
#search-results li.highlight { background: var(--accent); color: #fff; }

/* advanced-mode field grid */
.adv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px 12px;
}
.adv-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--muted);
}
.adv-field--event  span { color: #e08a7d; }
.adv-field--custom span { color: #7fc8a0; }
.adv-input {
  width: 100%;
  padding: 8px 10px;
  font-size: .9rem;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  outline: none;
}
select.adv-input {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%239b9b9b' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
}
select.adv-input option { background: #232323; color: var(--text); }

/* screener control bar */
.screener-form {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px 14px;
}
.screener-form .adv-field { flex: 0 0 auto; }
.screener-form .adv-field:first-child .adv-input { min-width: 170px; }
.screener-form .adv-field .adv-input { width: auto; min-width: 120px; }
.screener-form .range-group { margin-left: auto; align-self: flex-end; }
.adv-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(31,155,224,.18); }

/* range segmented control */
.range-group {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
}
a.range-btn { text-decoration: none; display: inline-block; }
a.range-btn:hover { text-decoration: none; }

.event-head {
  padding: 12px 14px 0;
  font-weight: 700;
  color: var(--text);
}
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 12px 14px;
}
.pager-info { font-size: .82rem; color: var(--muted); margin: 0 6px; }
.event-table th:first-child,
.event-table td:first-child { color: var(--muted); }
.range-btn {
  appearance: none;
  -webkit-appearance: none;
  padding: 7px 15px;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .3px;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  transition: all .14s ease;
}
.range-btn:hover { color: var(--text); border-color: #565656; background: var(--panel-3); }
.range-btn.is-active {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 2px 10px rgba(31, 155, 224, .3);
}

/* primary action button (Submit / Search / Save) */
.range-btn.range-btn--go {
  color: #fff;
  background: linear-gradient(180deg, #29a6e6 0%, #1f8fce 100%);
  border-color: #1f8fce;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .12) inset, 0 2px 8px rgba(31, 143, 206, .3);
}
.range-btn.range-btn--go:hover {
  color: #fff;
  background: linear-gradient(180deg, #33b0f0 0%, #248fd0 100%);
  border-color: #248fd0;
}

/* ghost button (Reset) */
.range-btn.range-btn--reset {
  color: var(--muted);
  background: transparent;
  border-color: transparent;
}
.range-btn.range-btn--reset:hover { color: var(--text); background: var(--panel-2); border-color: var(--border); }

/* directional action buttons (gap up / gap down) */
.range-btn.range-btn--up {
  color: #fff;
  background: linear-gradient(180deg, #3ccb78 0%, #2fae67 100%);
  border-color: #2fae67;
  box-shadow: 0 1px 0 rgba(255,255,255,.12) inset, 0 2px 8px rgba(47,174,103,.28);
}
.range-btn.range-btn--up:hover { background: linear-gradient(180deg, #46d884 0%, #34b972 100%); border-color: #34b972; color:#fff; }
.range-btn.range-btn--down {
  color: #fff;
  background: linear-gradient(180deg, #e5687a 0%, #d5566a 100%);
  border-color: #d5566a;
  box-shadow: 0 1px 0 rgba(255,255,255,.12) inset, 0 2px 8px rgba(213,86,106,.28);
}
.range-btn.range-btn--down:hover { background: linear-gradient(180deg, #ec7484 0%, #dc5e72 100%); border-color: #dc5e72; color:#fff; }

/* gap page: keep the 3 controls on one row, actions below */
.gaps-grid { grid-template-columns: minmax(120px,1fr) minmax(120px,1fr) minmax(190px,1.4fr); }
.gaps-actions { justify-content: flex-start; margin-top: 12px; }
.gaps-actions .range-btn { padding: 9px 22px; font-size: .9rem; }
@media (max-width: 560px) { .gaps-grid { grid-template-columns: 1fr; } }

/* ---------- Charts ---------- */
.charts {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.chart-card {
  margin: 0;
  padding: 10px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.season-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
}

/* client-side (Plotly) charts */
.charts { min-width: 0; }
.chart-card { min-width: 0; max-width: 100%; }
.plotly-chart { width: 100%; height: 260px; min-width: 0; max-width: 100%; overflow: hidden; }
.plotly-chart.tall { height: 400px; }

/* ---------- monthly-return grid (month x year heat table) ---------- */
.sg-card { padding: 12px 12px 10px; }
.sg-title { font-size: .8rem; font-weight: 700; color: var(--text); margin: 0 0 8px; }
.sg-title span { color: var(--muted); font-weight: 400; }
.sg-foot { font-size: .68rem; color: #7a7a7a; margin: 7px 0 0; }
.sg-grid { border-collapse: separate; border-spacing: 0; width: 100%;
  font-variant-numeric: tabular-nums; font-size: .78rem; }
.sg-grid thead th { position: sticky; top: 0; z-index: 2; background: var(--panel);
  font-size: .66rem; font-weight: 800; letter-spacing: .03em;
  color: #7a7f88; padding: 5px 7px 7px; text-align: center; white-space: nowrap; }
.sg-grid thead th:first-child { text-align: left; }
.sg-grid tbody th { text-align: left; color: var(--text); font-weight: 700; font-size: .74rem;
  padding: 5px 12px 5px 4px; position: sticky; left: 0; background: var(--panel); z-index: 1; white-space: nowrap; }
.sg-grid td { padding: 5px 7px; text-align: center; color: #ededed;
  border-right: 1px solid rgba(0,0,0,.28); border-bottom: 1px solid rgba(0,0,0,.28); }
.sg-grid .sg-p { background: rgba(53, 194, 106, var(--a, .3)); }
.sg-grid .sg-n { background: rgba(224, 87, 106, var(--a, .3)); }
.sg-grid .sg-na { background: transparent; color: transparent; }
.sg-grid tbody tr:hover td { outline: 1px solid rgba(255,255,255,.25); outline-offset: -1px; }
/* full-year summary row */
.sg-grid tr.sg-total th, .sg-grid tr.sg-total td { border-top: 2px solid var(--border);
  font-weight: 800; padding-top: 6px; padding-bottom: 6px; }
/* Avg / Median / Hit-rate summary columns (over the years shown) */
.sg-grid th.sg-sh { color: #9aa0a6; }
.sg-grid th.sg-sh:first-of-type, .sg-grid td.sg-s0 { border-left: 3px solid #cfd2d8; }
.sg-grid tr.sg-total td.sg-s0 { border-left: 3px solid #cfd2d8; }
.sg-grid td.sg-s { font-weight: 800; color: #f0f0f0; }
/* the month we are in -- one row, so it reads as "you are here" rather than
   as a band of months that all matter equally */
.sg-grid tbody tr:not(.sg-hl) td, .sg-grid tbody tr:not(.sg-hl) th { opacity: .78; }
.sg-grid tr.sg-hl th { color: #fff; font-weight: 900; background: var(--accent); }
.sg-grid tr.sg-hl td { box-shadow: inset 0 0 0 999px rgba(31, 155, 224, .1);
  color: #fff; font-weight: 700; border-top: 2px solid var(--accent); border-bottom: 2px solid var(--accent); }
.sg-grid tr.sg-hl td:last-child { border-right: 2px solid var(--accent); }

/* macro screener: two compact horizontal-bar charts, side by side when wide */
.macro-head {
  font-size: 1.05rem; font-weight: 700; color: var(--text);
  margin: 4px 0 10px; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
.macro-head .macro-sub { font-size: .8rem; font-weight: 400; color: var(--muted); }
.macro-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 16px; }
.macro-grid .chart-card { margin: 0; }
.macro-bars { width: 100%; }
@media (max-width: 720px) { .macro-grid { grid-template-columns: 1fr; } }

/* stat tiles (COT snapshot etc.) */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}
.stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 9px;
}
.stat-label {
  font-size: .68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--muted);
}
.stat-value { font-size: 1.15rem; font-weight: 700; color: var(--text); }
.stat-value.pos { color: var(--green); }
.stat-value.neg { color: var(--danger); }
.stat-sub { font-size: .7rem; color: #6f6f6f; }

.cross-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 8px;
}
.cross-head h4 { margin: 0; font-size: 1rem; font-weight: 700; }
.metric-group { display: flex; flex-wrap: wrap; gap: 6px; }
.cross-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  margin-bottom: 6px;
}
.cross-label { font-size: 1rem; font-weight: 700; color: var(--text); }
.cross-controls .range-btn { padding: 6px 11px; }
.cross-controls .adv-input { padding: 6px 8px; font-size: .88rem; }
.cross-note { margin: 8px 0 0; font-size: .78rem; color: var(--muted); }
.hdr-date { font-size: .8rem; font-weight: 400; color: var(--muted); }

/* ---- COT: primer ---- */
.primer {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 16px;
  overflow: hidden;
}
.primer summary {
  cursor: pointer;
  padding: 12px 16px;
  font-weight: 700;
  font-size: .9rem;
  list-style: none;
  color: var(--text);
}
.primer summary::-webkit-details-marker { display: none; }
.primer[open] summary { border-bottom: 1px solid var(--border); }
.primer-body { padding: 14px 18px; font-size: .88rem; color: var(--muted); }
.primer-body p { margin: 0 0 10px; }
.primer-body ul { margin: 0 0 10px; padding-left: 18px; }
.primer-body li { margin-bottom: 5px; }
.primer-body strong { color: var(--text); }

/* ---- COT: hero ---- */
.tone-hot  { color: #d8a45f; }   /* crowded long  */
.tone-warm { color: #cabb92; }
.tone-flat { color: var(--text); }
.tone-cool { color: #aeb7bf; }
.tone-cold { color: #6fae99; }   /* crowded short */

.hero-headline {
  margin: 14px 0 4px;
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1.3;
}
@media (max-width: 560px) { .hero-headline { font-size: 1.2rem; } }

.mood-scale { position: relative; margin: 24px 0 6px; padding-top: 52px; }
.mood-scale-title {
  position: absolute;
  top: 0;
  left: 0;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: var(--muted);
}
.mood-track {
  height: 12px;
  border-radius: 7px;
  background: linear-gradient(90deg,
    #c17b6f 0%, #c17b6f 14%, #5f5f5f 42%, #5f5f5f 58%, #5b9e8a 86%, #5b9e8a 100%);
}
.mood-now {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  text-align: center;
  font-size: .8rem;
  font-weight: 800;
  color: var(--text);
  line-height: 1.05;
  white-space: nowrap;
}
.mood-labels {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  font-size: .72rem;
  line-height: 1.35;
  color: var(--muted);
}

.hero-meaning {
  margin: 20px 0 0;
  padding: 14px 16px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.hero-kicker {
  font-size: .68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: var(--muted);
  margin-bottom: 6px;
}
.hero-meaning p { margin: 0; font-size: .98rem; line-height: 1.6; color: var(--text); }

.hero-takeaway {
  display: flex;
  gap: 10px;
  margin: 16px 0 0;
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.55;
}
.hero-takeaway span { font-weight: 800; flex-shrink: 0; }

.hero-strip {
  margin: 18px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: .82rem;
  color: var(--muted);
}
.hero-strip b { color: var(--text); font-weight: 700; }

/* ---- COT: chart captions ---- */
.chart-caption {
  margin: 8px 4px 2px;
  font-size: .8rem;
  line-height: 1.5;
  color: var(--muted);
}
.chart-caption em { color: var(--text); font-style: normal; font-weight: 600; }

.sea-range {
  display: flex; gap: 4px; flex-wrap: wrap; margin: 4px 0 2px;
  justify-content: flex-end;
}
.sea-range button {
  font-size: .72rem; font-weight: 700; color: var(--muted, #9b9b9b);
  background: var(--panel-2, #232323); border: 1px solid var(--border, #383838);
  border-radius: 6px; padding: 3px 9px; cursor: pointer; line-height: 1.4;
}
.sea-range button:hover { color: var(--text, #ececec); border-color: #5a5a5a; }
.sea-range button.on {
  color: #fff; background: var(--accent, #1f9be0); border-color: var(--accent, #1f9be0);
}

.season-divnote {
  margin: -8px 0 16px;
  padding: 7px 12px;
  border-radius: 8px;
  background: var(--panel-2, #232323);
  border: 1px solid var(--border, #383838);
  font-size: .82rem;
  color: var(--text, #ececec);
}

/* ---- Congressional trades ---- */
.pel-intro {
  max-width: 780px;
  margin: 6px 0 16px;
  font-size: .92rem;
  line-height: 1.6;
  color: var(--muted);
}
.pel-topfilers {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 12px 0 0;
  font-size: .8rem;
}
.pel-topfilers > span { color: var(--muted); margin-right: 4px; }
.pel-chip {
  display: inline-block;
  padding: 4px 10px;
  font-size: .78rem;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
  text-decoration: none;
  transition: border-color .13s;
}
.pel-chip:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.pel-chip b { color: var(--muted); font-weight: 700; margin-left: 3px; }

.pel-alerts { display: flex; flex-direction: column; gap: 10px; }
.pel-chk {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: .9rem;
  color: var(--text);
  cursor: pointer;
}
.pel-chk input { margin-top: 3px; accent-color: var(--green); width: 15px; height: 15px; }
.pel-chk b { font-weight: 700; }
.pel-alerts button { align-self: flex-start; margin-top: 4px; }

.pel-controls { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pel-controls .adv-input { max-width: 220px; }
.pel-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: .82rem;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
}
.pel-toggle input { accent-color: var(--accent); }

.table-scroll.pel-table-wrap { border-radius: 8px; }
.pel-table { font-size: .85rem; }
.pel-table th, .pel-table td { text-align: left; }
.pel-table td:first-child, .pel-table th:first-child { text-align: right; }
.pel-idx { color: #6f6f6f; font-variant-numeric: tabular-nums; }
.pel-row.is-recent td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.pel-name { font-weight: 600; }
.pel-name.is-notable { color: #d8a45f; }
.pel-new {
  margin-left: 6px;
  padding: 1px 6px;
  font-size: .62rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: #101010;
  background: var(--accent);
  border-radius: 4px;
  vertical-align: middle;
}
.pel-ago { margin-left: 8px; font-size: .74rem; color: #6f6f6f; }

/* crowding score pill */
.crowd-pill {
  display: inline-block;
  min-width: 34px;
  padding: 2px 8px;
  border-radius: 6px;
  font-weight: 800;
  font-size: .82rem;
  text-align: center;
  color: #fff;
}
.crowd-extreme  { background: #b5544f; }
.crowd-high     { background: #c17b6f; }
.crowd-elevated { background: #c9a24b; color: #1a1a1a; }
.crowd-moderate { background: #5f6b6a; }
.crowd-low      { background: #3a3a3a; color: var(--muted); }
.crowd-n\/a     { background: #3a3a3a; color: var(--muted); }

/* slim bar above a data table */
.table-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 4px 2px 6px;
  font-size: .76rem;
  color: var(--muted);
}
.mini-select {
  appearance: none;
  -webkit-appearance: none;
  padding: 4px 24px 4px 8px;
  font-size: .78rem;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%239b9b9b' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
}
.mini-select option { background: #232323; }

/* click-to-sort table headers */
.season-table th.th-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.season-table th.th-sortable:hover { color: var(--text); }
.season-table th.sorted-asc::after  { content: " \25B2"; font-size: .7em; color: var(--accent); }
.season-table th.sorted-desc::after { content: " \25BC"; font-size: .7em; color: var(--accent); }
.pel-link { font-weight: 600; white-space: nowrap; }
.pel-empty { padding: 24px; text-align: center; color: var(--muted); }

@media (max-width: 560px) {
  .pel-ago { display: block; margin: 2px 0 0; }
}

/* monthly returns table */
.table-card { padding: 0; }
/* no inner scroll on desktop -> table headers can pin to the viewport;
   horizontal scroll only kicks in on narrow screens for the wide grids */
.table-scroll { width: 100%; overflow-x: visible; }
@media (max-width: 820px) { .table-scroll { overflow-x: auto; } }
.season-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .82rem;
  color: var(--text);
}
.season-table th,
.season-table td {
  padding: 6px 10px;
  text-align: center;
  white-space: nowrap;
  border-bottom: 1px solid var(--border);
}
.season-table thead th {
  color: var(--muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .4px;
  font-size: .72rem;
  background: var(--panel-2);
  position: sticky;
  top: 0;
  z-index: 3;
  box-shadow: inset 0 -1px 0 var(--border);   /* keep a divider when the row scrolls under */
}
.season-table tbody th {
  text-align: left;
  color: var(--muted);
  font-weight: 700;
  position: sticky;
  left: 0;
  background: var(--panel);
}
.season-table tbody tr:last-child td,
.season-table tbody tr:last-child th { border-bottom: none; }
.season-table td.pos { color: var(--green); }
.season-table td.neg { color: var(--danger); }

.season-note {
  max-width: 760px;
  margin: 22px auto 0;
  padding: 12px 16px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  color: var(--muted);
  font-size: .88rem;
}

/* ---------- Watchlist ---------- */
.wl-card {
  position: sticky;
  top: 16px;
  padding: 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.wl-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 10px;
}
.wl-head h5 { margin: 0; font-size: 1rem; font-weight: 700; }
.wl-hint {
  font-size: .66rem;
  text-transform: uppercase;
  letter-spacing: .6px;
  color: #6f6f6f;
}

#watchlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.wl-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 9px 10px;
  background: var(--panel-2);
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  transition: background .13s ease, border-color .13s ease;
}
.wl-item:hover { background: var(--panel-3); border-color: var(--accent); }
.wl-tkr { font-weight: 700; font-size: .9rem; letter-spacing: .4px; }
.remove-ticker {
  appearance: none;
  border: none;
  background: transparent;
  color: #6f6f6f;
  font-size: 1.15rem;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
  transition: color .12s;
}
.wl-item:hover .remove-ticker { color: var(--muted); }
.remove-ticker:hover { color: var(--danger) !important; }

.wl-add {
  display: flex;
  gap: 6px;
  margin-top: 12px;
}
.wl-add #new-ticker {
  flex: 1;
  min-width: 0;
  padding: 8px 10px;
  font-size: .85rem;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  outline: none;
}
.wl-add #new-ticker:focus { border-color: var(--accent); }
.wl-add #add-ticker {
  padding: 8px 14px;
  font-size: .82rem;
  font-weight: 700;
  color: #fff;
  background: var(--green);
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: filter .12s;
}
.wl-add #add-ticker:hover { filter: brightness(1.08); }

/* ---------- Login modal ---------- */
#loginModal,
#gateModal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: rgba(0, 0, 0, .62);
}
#loginModal .modal-content,
#gateModal .modal-content {
  margin: 14vh auto 0;
  max-width: 340px;
  width: calc(100% - 40px);
  padding: 26px 28px;
  text-align: center;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .55);
}
#loginModal h5,
#gateModal h5 { margin-bottom: 8px; font-size: 1.05rem; text-align: center; }
#loginModal p,
#gateModal p { margin-bottom: 18px; color: var(--muted); font-size: .88rem; }
.btn_modal {
  display: block;
  width: 100%;
  margin-bottom: 8px;
  padding: 11px 16px;
  font-weight: 700;
  color: #fff;
  background: var(--accent);
  border-radius: 9px;
  text-align: center;
}
.btn_modal:hover { background: var(--accent-d); color: #fff; text-decoration: none; }
/* the modal's headline carries the whole message, so it needs the breathing
   room the (now removed) sub-paragraph used to provide */
#gateModal h5 { margin-bottom: 18px; }
#gateModal .gate-alt { margin: 10px 0 14px; font-size: .82rem; }
#gateModal .gate-alt a { color: var(--accent); font-weight: 600; }

#closeModal,
.modal-dismiss {
  width: 100%;
  padding: 9px 16px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 9px;
  cursor: pointer;
}
#closeModal:hover,
.modal-dismiss:hover { color: var(--text); }

/* ---------- Responsive ---------- */
@media (max-width: 992px) {
  .season-layout {
    grid-template-columns: 1fr;
    grid-template-areas: "aside" "main";
    gap: 16px;
  }
  .wl-card { position: static; }
  .wl-head { margin-bottom: 8px; }
  #watchlist {
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 4px;
  }
  .wl-item { flex: 0 0 auto; }
}

@media (max-width: 560px) {
  .season-page { padding: 16px 12px 44px; }
  .season-head h3 { font-size: 1.25rem; }
  .toolbar-card { padding: 12px; }
  .range-btn { padding: 6px 12px; }
}

/* compact "jump to another ticker" box (per-ticker pages) */
.pg-jump { display: inline-flex; max-width: 300px; margin: 0 0 18px; }
.pg-jump input {
  flex: 1; background: var(--panel-3); border: 1px solid var(--border); color: var(--text);
  font-size: .86rem; padding: 8px 12px; border-radius: 8px 0 0 8px; outline: none;
}
.pg-jump input:focus { border-color: var(--accent); }
.pg-jump button {
  background: var(--accent); color: #fff; border: none; font-weight: 800; font-size: .78rem;
  padding: 0 14px; border-radius: 0 8px 8px 0; cursor: pointer;
}
.pg-jump button:hover { background: var(--accent-d); }


/* ---- "trending" idea cards: /pelosi and the homepage share these ---- */
.ideas-wrap { margin: 14px 0 20px; }
.ideas-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin: 0 0 4px; }
.ideas-head h4 { margin: 0; font-size: 1.12rem; font-weight: 800; }
.ideas-head .sub { font-size: .76rem; color: var(--muted); }
/* the lag / method fine print, tucked into the top-right corner of the section */
.ideas-fine { margin-left: auto; text-align: right; white-space: nowrap;
  font-size: .62rem; line-height: 1.45; color: #6f7480; }
@media (max-width: 900px) { .ideas-fine { margin-left: 0; text-align: left; white-space: normal; } }
/* one row, always -- they share the width when they fit and scroll sideways
   when they don't, rather than wrapping into a ragged second row */
.ideas-grid { display: flex; gap: 10px; margin-top: 10px; overflow-x: auto;
  padding: 2px 2px 6px; scroll-snap-type: x proximity; }
.idea { flex: 1 0 0; min-width: 258px; scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 7px; text-decoration: none; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 12px; padding: 12px 13px 11px;
  transition: border-color .12s, transform .12s; }
.idea:hover { border-color: #5a5a5a; transform: translateY(-2px); }
.idea.buy { box-shadow: inset 3px 0 0 #46d884; }
.idea.sell { box-shadow: inset 3px 0 0 #ec7484; }
.idea-top { display: flex; align-items: center; gap: 8px; }
.idea-id { min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
.idea-tk { font-weight: 800; font-size: .96rem; letter-spacing: .2px; }
.idea-nm { font-size: .68rem; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.idea-act { margin-left: auto; font-size: .6rem; font-weight: 900; letter-spacing: .8px;
  padding: 3px 7px; border-radius: 5px; flex-shrink: 0; }
.idea-act.buy { color: #46d884; background: rgba(70,216,132,.14); }
.idea-act.sell { color: #ec7484; background: rgba(236,116,132,.14); }
.idea-do { font-size: .92rem; line-height: 1.3; }
.idea-do b { font-weight: 800; }
.idea-opt { font-size: .58rem; font-weight: 800; letter-spacing: .5px; text-transform: uppercase;
  color: #cabb92; background: rgba(202,187,146,.14); border-radius: 4px; padding: 1px 5px; vertical-align: 1px; }
.idea-sub2 { font-size: .68rem; color: #8a8a8a; margin-top: -3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.idea-rrow { display: flex; align-items: center; gap: 7px; }
.idea-opp { font-size: .62rem; color: #8a8a8a; }
.idea-reason { font-size: .62rem; font-weight: 800; letter-spacing: .3px;
  padding: 2px 8px; border-radius: 999px; border: 1px solid transparent; white-space: nowrap; }
.idea-reason.r-new     { color: #7ab8ff; background: rgba(122,184,255,.13); }
.idea-reason.r-cluster { color: #c79bff; background: rgba(199,155,255,.13); }
.idea-reason.r-big     { color: #ffd27a; background: rgba(255,210,122,.13); }
.idea-reason.r-opt     { color: #cabb92; background: rgba(202,187,146,.14); }
.idea-reason.r-fresh   { color: #6fe0c2; background: rgba(111,224,194,.13); }
.idea-reason.r-notable { color: #9aa4b2; background: rgba(154,164,178,.13); }
.idea-reason.r-mixed   { color: #9aa4b2; background: rgba(154,164,178,.1); border-color: rgba(154,164,178,.25); }
.idea-spark { width: 100%; height: 46px; display: block; }
.idea-nospark { display: flex; align-items: center; justify-content: center; font-size: .64rem;
  color: #6a6a6a; border: 1px dashed var(--border); border-radius: 6px; }
.idea-px { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.idea-price { font-weight: 800; font-size: .9rem; font-variant-numeric: tabular-nums; }
.idea-chg { font-size: .72rem; font-variant-numeric: tabular-nums; }
.idea-since { font-size: .72rem; font-weight: 700; margin-left: auto; }
.up { color: #46d884; } .down { color: #ec7484; }
.idea-entry { display: flex; align-items: baseline; gap: 7px; font-size: .7rem; color: #8a8a8a;
  margin-top: -2px; }
.idea-entry > span:first-child { flex: none; color: #b6b6b6; font-weight: 600; }
.idea-timing { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.idea-timing.t-good { color: #46d884; }
.idea-timing.t-late { color: #e6b866; }
.idea-timing.t-flat { color: #8a8a8a; }
.idea-mem { display: flex; align-items: center; gap: 5px; font-size: .72rem; color: var(--muted);
  border-top: 1px solid var(--border); padding-top: 7px; }
.idea-mem .stack { display: flex; }
.idea-mem .stack .sy-photo { margin-left: -6px; border: 1.5px solid var(--panel-2); }
.idea-mem .stack .sy-photo:first-child { margin-left: 0; }
.idea-fresh { color: #7a7a7a; }

/* Month-summary table: same heat cells as the grid, but months run across and
   the three statistics are the rows. The current month gets a column outline,
   matching the row highlight on the grid and the bar charts below. */
.sg-months tbody th { text-align: left; white-space: nowrap; color: var(--text);
  font-weight: 700; }
.sg-months td { text-align: center; font-variant-numeric: tabular-nums; }
.sg-months td.sg-hc, .sg-months th.sg-hc { box-shadow: inset 1px 0 0 var(--accent),
  inset -1px 0 0 var(--accent); }
.sg-months thead th.sg-hc { color: #fff; background: var(--accent); }
.sg-months tbody tr:last-child td.sg-hc { box-shadow: inset 1px 0 0 var(--accent),
  inset -1px 0 0 var(--accent), inset 0 -1px 0 var(--accent); }

/* ===================================================================
   Seasonality: chart, table and the three bar charts on one screen.
   The four Plotly charts already share l=55 / r=20 margins, so their
   plot areas coincide; the table is sized to that same band and the
   line chart ticks mid-month, which puts every month in one column
   down the whole page.
   =================================================================== */
@media (min-width: 900px) {
  /* One flex column with a fixed budget, so the charts divide whatever is
     left rather than adding up to more than the screen. Plotly reads the
     height off the div and season_charts.js already re-fits on resize. */
  /* The column owns the screen and the charts take whatever the search bar and
     the notes above them leave, rather than a constant guessed from today's
     header -- a longer company name wrapping to a second line would otherwise
     push the last bar chart off the bottom. */
  .season-fit .season-main { display: flex; flex-direction: column; }
  .season-fit .charts { flex: 1 1 auto; min-height: 0; gap: 5px; }
  .season-fit .charts > figure { margin: 0; min-height: 0; }
  .season-fit .chart-card { padding: 3px 8px 2px; position: relative; }
  .season-fit .fig-table { flex: 0 0 auto; }
  /* min-height here, not just on the #chart-seasonal div inside it: this
     figure is the actual flex item, and it clips its child (overflow:
     hidden) -- a min-height on the child alone does not push a flex-basis-0
     parent taller, it just gets invisibly clipped to whatever little space
     the parent already has. That was the real reason the earlier fix (see
     .plotly-chart below) did not stop the flash: measured with a headless
     browser, this figure sat at 7px for a full second before Plotly loaded,
     with the table right below it, then jumped to ~660px once Plotly drew.
     A min-height directly on the flex item is what actually reserves the
     space up front. */
  .season-fit .fig-seasonal { flex: 1 1 0; }
  /* `.season-fit .charts > figure { min-height: 0 }` above is MORE specific
     than a plain `.fig-seasonal` class rule would be (it adds the `figure`
     type selector), so a min-height set there loses regardless of source
     order -- confirmed by measuring the actual computed style in a headless
     browser, which still showed min-height: 0px after a first attempt at
     this fix. Matching its selector shape here is what actually wins. */
  .season-fit .charts > figure.fig-seasonal { min-height: 260px; }
  /* one panel holding the three bar charts, which share it evenly */
  .season-fit .fig-bars {
    flex: 1 1 0; display: flex; flex-direction: column; gap: 0;
    padding: 3px 8px 2px;
  }
  /* min-height was 0 on both of these: on first paint, before Plotly (a
     separate, blocking script tag) has loaded and season_charts.js has drawn
     into them, these divs are genuinely empty, so `height: 100%` of a flex
     column with nothing yet forcing its own height collapses them to zero.
     Everything below -- the month-by-month table under the curve chart --
     briefly renders right under the toolbar instead, then jumps down once
     the chart claims its real height a moment later. A floor here is purely
     a fallback for that gap: once the chart draws, its real height is larger
     than this floor every time, so this changes nothing about the final,
     steady-state layout -- it only stops the pre-JS collapse. */
  .season-fit .fig-bars .plotly-chart { flex: 1 1 0; height: auto; min-height: 220px; }
  .season-fit .plotly-chart,
  .season-fit .plotly-chart.tall { height: 100%; min-height: 260px; }

  /* The year buttons move into the chart's own top margin instead of taking
     a 24px row each -- four rows of them was 96px of the budget. */
  .season-fit .sea-range {
    position: absolute; top: 3px; right: 9px; z-index: 3;
    margin: 0; flex-wrap: nowrap;
  }
  .season-fit .sea-range button { padding: 1px 7px; font-size: .68rem; }

  /* Month columns land on the charts' plot area: the label column is Plotly's
     left margin, the wrapper reserves its right margin. */
  .season-fit .sg-months-wrap { padding-right: 20px; overflow: visible; }
  .season-fit .sg-months { table-layout: fixed; width: 100%; }
  .season-fit .sg-months th:first-child,
  .season-fit .sg-months td:first-child { width: 74px; padding-left: 0; }
  .season-fit .fig-table .sg-title { margin: 0 0 3px; font-size: .74rem; }
  .season-fit .fig-table .sg-foot { margin: 3px 0 0; font-size: .63rem; }
  .season-fit .sg-months thead th { padding: 0 4px 2px; }
  .season-fit .sg-months tbody td,
  .season-fit .sg-months tbody th { padding: 2px 4px; font-size: .73rem; line-height: 1.5; }
  /* never let a row label spill over the first month's number */
  .season-fit .sg-months tbody th { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  /* The search box and the year buttons were sized for a page with room to
     spare; on a one-screen layout every row they cost comes off the charts. */
  .season-fit #search-input { padding: 6px 11px; font-size: .84rem; border-radius: 7px; }
  .season-fit .range-btn { padding: 4px 11px; font-size: .74rem; border-radius: 7px; }

  /* the page furniture above the charts sets the budget above */
  .season-fit .toolbar-card {
    flex-direction: row; align-items: center; gap: 10px;
    padding: 6px 11px; margin-bottom: 6px;
  }
  /* The year buttons were wrapping onto a second row, which is what made the
     toolbar 78px tall rather than the 48 its tallest child needs. Narrowing the
     search box gives them the width for one row. */
  .season-fit .toolbar-card .search-wrap { flex: 0 1 196px; margin: 0; }
  .season-fit .toolbar-card .range-group { flex: 0 0 auto; flex-wrap: nowrap; margin-left: auto; }
  /* the title sits at the right end of the toolbar row rather than owning a
     band of its own above it */
  /* title, link and the total-return note all on the toolbar's own line */
  .season-fit .toolbar-card .season-head {
    margin: 0; min-width: 0;
    display: flex; align-items: baseline; gap: 10px; white-space: nowrap;
  }
  /* the h3 was being shrunk to 250px and wrapping its own three parts onto
     three lines while there was room to spare beside it */
  .season-fit .toolbar-card .season-head h3 {
    margin: 0; font-size: .95rem; white-space: nowrap;
    flex: 0 0 auto; flex-wrap: nowrap;
  }
  /* space-between spread the logo, the ticker and the remove button across the
     rail once it widened to match the left column; the ticker belongs next to
     its logo, and only the x should be pushed away */
  .season-fit .wl-item { justify-content: flex-start; }
  .season-fit .wl-item .remove-ticker { margin-left: auto; }

  /* short enough to always fit, so it neither clips nor disappears */
  .season-fit .toolbar-card .season-head .season-divnote { flex: 0 0 auto; cursor: help; }
  .season-fit .toolbar-card .season-head { overflow: hidden; }
  .season-fit .season-divnote {
    margin: 0; padding: 0; background: none; border: 0;
    font-size: .68rem; line-height: 1.3; color: #8b8b8b; white-space: nowrap;
  }
  .season-fit .season-divnote b { color: #b9b9b9; font-weight: 700; }
  .season-fit .season-layout { margin-top: 0; }
}

/* a little of the page back: the navbar carried 8px under the brand and the
   seasonality page opened with a 24px gap above its toolbar */
.season-fit { padding-top: 5px !important; }

/* =====================================================================
   Seasonality: three columns -- the five-year grid, the charts, and the
   watchlist hard against the right edge.
   ===================================================================== */
@media (min-width: 1200px) {
  .season-fit .season-layout.sl-tight {
    /* Both flanks the same width so the charts sit dead centre. The grid gets
       there by dropping a couple of points of type rather than by taking the
       width from the middle. */
    grid-template-columns: 250px minmax(0, 1fr) 250px;
    grid-template-areas: "side main aside";
    gap: 10px;
  }
  .season-fit .season-side { grid-area: side; min-width: 0; }
  /* Three columns need the whole window: the page is capped at 1360px and
     centred, which left the rail floating 280px from the edge on a 1920 screen.
     The cap comes off here and the rail runs to the edge. */
  /* equal gutters, or "centre" is off by the difference */
  .season-fit { max-width: none; margin: 0; padding: 5px 8px 0 !important; }
  /* The grid sizes to its own thirteen rows and stops. Stretching it to the
     height of the charts gave each row 59px for one number, which is a lot of
     empty panel to look at. */
  .season-fit .season-layout.sl-tight { align-items: start; }

  /* the grid is tall and thin: twelve months down, five years across */
  .season-fit .side-grid { padding: 4px 5px 5px; }
  .season-fit .side-grid .sg-title { margin: 0 0 3px; font-size: .72rem; }
  .season-fit .sg-years { table-layout: fixed; width: 100%; font-size: .64rem; }
  .season-fit .sg-years thead th { padding: 0 1px 2px; font-size: .55rem; }
  .season-fit .sg-years th:first-child { width: 26px; text-align: left; }
  .season-fit .sg-years tbody td,
  .season-fit .sg-years tbody th { padding: 5px 1px; font-size: .65rem; text-align: center; }
  .season-fit .sg-years tbody th { text-align: left; color: var(--muted); font-weight: 700; }
  .season-fit .sg-years .sg-total th,
  .season-fit .sg-years .sg-total td { border-top: 1px solid var(--border); font-weight: 800; }
  .season-fit .sg-years tr.sg-hl th { color: #fff; background: var(--accent); }

  .season-fit .side-grid { margin: 0; }
}

/* view switcher + demean, in the toolbar row */
.season-switches { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.season-switches .seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.season-switches .seg button {
  border: 0; background: transparent; color: var(--muted); font: inherit;
  font-size: .74rem; font-weight: 700; padding: 4px 12px; cursor: pointer;
}
.season-switches .seg button + button { border-left: 1px solid var(--border); }
.season-switches .seg button.on { background: var(--accent); color: #fff; }
/* a switch rather than a button: it is a state you leave on, not an action */
.season-switches .tgl {
  display: inline-flex; align-items: center; gap: 7px;
  border: 0; background: none; padding: 2px 2px; cursor: pointer;
  font: inherit; font-size: .74rem; font-weight: 700; color: var(--muted);
}
.season-switches .tgl:hover { color: var(--text); }
.season-switches .tgl-sw {
  position: relative; flex: none; width: 30px; height: 17px; border-radius: 999px;
  background: var(--panel-3, #2f2f2f); border: 1px solid var(--border);
  transition: background .15s ease, border-color .15s ease;
}
.season-switches .tgl-sw i {
  position: absolute; top: 1px; left: 1px; width: 13px; height: 13px;
  border-radius: 50%; background: #8b8b8b; transition: transform .15s ease, background .15s ease;
}
.season-switches .tgl.on { color: var(--text); }
.season-switches .tgl.on .tgl-sw { background: var(--accent); border-color: var(--accent); }
.season-switches .tgl.on .tgl-sw i { transform: translateX(13px); background: #fff; }

/* Between 900 and 1199px there is no room for a third column, so the grid
   falls below the charts. Left to itself it stretched to the full width of the
   page, which is a strange shape for five columns of numbers. */
@media (min-width: 900px) and (max-width: 1199px) {
  .season-fit .season-side { max-width: 380px; margin-top: 8px; }
}

/* ---------- Portfolio watchlist (detail pages) ---------- */
/* Built like a stock watchlist, because that is what it is: a dense quote
   board you scan down, not a stack of cards. Rows are contiguous and 24px, the
   identifier is left and everything numeric is right-aligned and tabular, the
   headline number carries the colour (green when the book beats its benchmark,
   red when it does not) and the rules run the full height of the table so the
   eye can travel a column. Shared by both detail templates via
   _portfolio_side.html.

   Sticky, never scrolling: an `overflow-y` box here would not overflow with a
   handful of books, so it showed no scrollbar of its own and merely swallowed
   the wheel. */
.pl-side { display: block; padding: 14px 12px 16px;
  /* the four numeric column widths, dragged by the header grips and shared by
     the header and every row so they cannot drift apart */
  --c1: 48px; --c2: 38px; --c3: 40px; --c4: 34px;
  position: sticky; top: 14px; }

.pl-cap { display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: .6rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 8px; }

.pl-card, .pl-hdr { display: grid; align-items: center; gap: 0;
  grid-template-columns: minmax(0,1fr) var(--c1) var(--c2) var(--c3) var(--c4); }
.pl-card > *, .pl-hdr > * { padding: 0 5px; }
.pl-card > *:first-child, .pl-hdr > *:first-child { padding-left: 3px; }

.pl-hdr { padding-bottom: 4px; border-bottom: 1px solid #3a4048;
  font-size: .52rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; color: #6f6f6f; }
.pl-hdr span + span { text-align: right; }
.pl-h { position: relative; cursor: pointer; user-select: none; }
.pl-h:hover { color: var(--text); }
.pl-h.asc::after { content: '\25B2'; margin-left: 2px; color: var(--accent); }
.pl-h.desc::after { content: '\25BC'; margin-left: 2px; color: var(--accent); }
/* the header tooltips: the abbreviations are only fair if the words are one
   hover away. Drawn on the header cell itself, above it, and anchored to the
   right so a wide label cannot run off the edge of the column. */
.pl-h[data-tip]:hover::after {
  content: attr(data-tip) ' · click to sort';
  position: absolute; bottom: calc(100% + 8px); right: -6px; z-index: 40;
  white-space: nowrap; text-transform: none; letter-spacing: .01em;
  background: #12151a; border: 1px solid #454c55; border-radius: 7px;
  padding: 5px 9px; font-size: .68rem; font-weight: 600; color: #e8eaed;
  box-shadow: 0 10px 24px rgba(0,0,0,.6); pointer-events: none; }
.pl-h[data-tip]:hover::before {
  content: ''; position: absolute; bottom: calc(100% + 3px); right: 6px; z-index: 41;
  border: 5px solid transparent; border-top-color: #454c55; pointer-events: none; }
.pl-h[data-k="name"][data-tip]:hover::after { right: auto; left: -3px; }
.pl-h[data-k="name"][data-tip]:hover::before { right: auto; left: 6px; }

/* a real target: 16px wide and taller than the 12px header text, or the grip
   is a pixel hunt. touch-action keeps a drag from scrolling the page instead. */
.pl-grip { position: absolute; top: -7px; bottom: -6px; right: -9px; width: 16px;
  cursor: col-resize; touch-action: none; z-index: 5; }
.pl-grip::before { content: ''; position: absolute; top: 4px; bottom: 4px; left: 7px;
  border-left: 1px solid transparent; }
.pl-hdr:hover .pl-grip::before { border-left-color: #4a5058; }
.pl-grip:hover::before { border-left-color: var(--accent); }

/* the board: 24px rows, one hairline between, nothing floating */
.pl-items { display: block; }
.pl-card { height: 24px; color: var(--text); text-decoration: none;
  border-bottom: 1px solid rgba(255,255,255,.05); transition: background .1s ease; }
.pl-card:last-child { border-bottom: 0; }
.pl-card:hover { background: rgba(255,255,255,.045); text-decoration: none; }
.pl-card.on { background: rgba(224,179,58,.10); box-shadow: inset 2px 0 0 var(--accent); }
.pl-card:focus { outline: none; background: rgba(224,179,58,.14);
  box-shadow: inset 2px 0 0 var(--accent); }

.pl-nm { font-size: .74rem; font-weight: 600; line-height: 24px; letter-spacing: .01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-card.on .pl-nm { font-weight: 800; }
.pl-n { font-size: .71rem; font-weight: 600; text-align: right; line-height: 24px;
  font-variant-numeric: tabular-nums; color: #98a1aa; }
/* the rules travel the whole table -- that is what makes it read as columns */
.pl-n, .pl-h[data-col] { border-left: 1px solid rgba(255,255,255,.07); }
/* the headline number, like the last price on a quote board */
.pl-card .pl-n:first-of-type { font-weight: 800; color: var(--text); }
.pl-card .pl-n.pos { color: var(--green); }
.pl-card .pl-n.neg { color: var(--danger); }

.pl-all { display: block; text-align: center; margin-top: 12px; padding: 7px 12px;
  background: var(--accent); border: 1px solid var(--accent); border-radius: 7px;
  color: #fff; font-weight: 700; font-size: .8rem; text-decoration: none; }
.pl-all:hover { filter: brightness(1.08); text-decoration: none; color: #fff; }

@media (max-width: 1080px) { .pl-side { position: static; } }

/* ---------- Follow a strategy ---------- */
/* Deliberately small and quiet: it sits beside a name, in a table row and in a
   page heading, so it has to look like part of the furniture rather than a
   call to action shouting over the numbers. */
.follow-btn { display: inline-block; padding: 4px 11px; border-radius: 7px;
  border: 1px solid #4c9be8; background: #4c9be8; color: #fff;
  font: inherit; font-size: .74rem; font-weight: 800; line-height: 1.4;
  cursor: pointer; text-decoration: none; white-space: nowrap; }
.follow-btn:hover { filter: brightness(1.08); text-decoration: none; color: #fff; }
.follow-btn.on { background: transparent; color: var(--green);
  border-color: rgba(53,194,106,.6); }
.follow-btn.on:hover { background: rgba(53,194,106,.1); color: var(--green); }
