@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

/* Dark is the default. The light palette below only overrides the tokens -
   every rule in this file reads from them, so nothing else has to change.
   Applied to <html> before first paint by theme_bootstrap() so there is no
   flash of the wrong theme on navigation. */
:root{
  --bg-void:#0b0e11;
  --bg-panel:#12161c;
  --bg-card:#171c24;
  --bg-card-hover:#1c222c;
  --border-subtle:#232933;
  --border-soft:#2a313d;
  --text-primary:#e6e9ef;
  --text-muted:#8b93a1;
  --text-faint:#5c6472;
  --up:#00d68f;
  --up-dim:rgba(0,214,143,.12);
  --down:#ff5c72;
  --down-dim:rgba(255,92,114,.12);
  --brand:#4c8dff;
  --brand-dim:rgba(76,141,255,.15);
  --radius:10px;
  --shadow-strong:rgba(0,0,0,.55);
  --shadow-drag:rgba(0,0,0,.5);
  --overlay-scrim:rgba(6,8,10,.82);
  --install-glow:#182230;
  --chart-baseline:rgba(139,147,161,.5);
  --pill-text:#0b0e11;
}

:root[data-theme="light"]{
  --bg-void:#f5f6f8;
  --bg-panel:#ffffff;
  --bg-card:#ffffff;
  --bg-card-hover:#f0f2f5;
  --border-subtle:#e6e8ec;
  --border-soft:#d2d7de;
  --text-primary:#12161c;
  --text-muted:#5c6572;
  --text-faint:#8a929e;
  /* Saturated enough to read as green/red on white without glowing. */
  --up:#0a8f5f;
  --up-dim:rgba(10,143,95,.12);
  --down:#d3304a;
  --down-dim:rgba(211,48,74,.10);
  --brand:#2563eb;
  --brand-dim:rgba(37,99,235,.14);
  --shadow-strong:rgba(20,26,36,.18);
  --shadow-drag:rgba(20,26,36,.16);
  --overlay-scrim:rgba(28,32,38,.55);
  --install-glow:#dfe6f2;
  --chart-baseline:rgba(120,130,145,.55);
  --pill-text:#ffffff;
}

:root[data-theme="light"] body{
  background:var(--bg-void);
}

*{box-sizing:border-box;}
html,body{height:100%;}
body{
  background:var(--bg-void);
  color:var(--text-primary);
  font-family:'Inter',system-ui,sans-serif;
  min-height:100vh;
}
.mono{font-family:'IBM Plex Mono',ui-monospace,monospace;}

/* ---------- top bar ---------- */
.topbar{
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 22px; border-bottom:1px solid var(--border-subtle);
  background:linear-gradient(180deg,var(--bg-panel),var(--bg-void));
  position:sticky; top:0; z-index:20; flex-wrap:wrap; gap:10px;
}
.topbar .brand{
  font-weight:700; letter-spacing:.02em; font-size:1.05rem; color:var(--text-primary);
  display:flex; align-items:center; gap:10px;
}
.brand .dot{width:9px;height:9px;border-radius:50%;background:var(--up);box-shadow:0 0 8px var(--up);animation:pulse 2s ease-in-out infinite;}
@keyframes pulse{0%,100%{opacity:1;}50%{opacity:.35;}}
.topbar .nav{display:flex;align-items:center;flex-wrap:wrap;}
.topbar .nav a{
  color:var(--text-muted); text-decoration:none; font-size:.9rem; margin-left:18px;
  transition:color .15s;
}
.topbar .nav a:hover, .topbar .nav a.active{color:var(--text-primary);}

.net-activity{
  display:inline-flex; align-items:center; gap:6px; margin-left:14px;
  padding:3px 10px; border-radius:999px; background:var(--bg-panel);
  border:1px solid var(--border-subtle); font-size:.72rem; color:var(--text-muted);
}
.net-activity .net-dot{width:6px;height:6px;border-radius:50%;background:var(--brand);opacity:.4;}
.net-activity .net-dot.net-pulse{animation:net-flash .6s ease-out;}
@keyframes net-flash{0%{opacity:1;box-shadow:0 0 6px var(--brand);}100%{opacity:.4;box-shadow:none;}}

.pf-badge{
  display:inline-flex; align-items:center; gap:14px; margin-right:18px;
  padding:3px 12px; border-radius:999px; background:var(--bg-panel);
  border:1px solid var(--border-subtle); font-size:.74rem; line-height:1.3;
}
.pf-badge .pf-item{display:inline-flex; align-items:baseline; gap:5px;}
.pf-badge .pf-label{color:var(--text-faint); font-size:.62rem; text-transform:uppercase; letter-spacing:.04em;}
.pf-badge .pf-value{font-family:'IBM Plex Mono',monospace; font-weight:600; color:var(--text-muted);}
.pf-badge .pf-value.up{color:var(--up);}
.pf-badge .pf-value.down{color:var(--down);}

/* ---------- dashboard grid ---------- */
.dash-wrap{padding:22px;}
.dash-toolbar{display:flex; gap:10px; margin-bottom:16px;}
.dash-toolbar #dashSearch{max-width:360px;}
#dashboard-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(340px,1fr));
  align-items:start;
  gap:14px;
}
.ticker-card.kbd-focused{outline:2px solid var(--brand); outline-offset:1px;}
.ticker-card{
  background:var(--bg-card);
  border:1px solid var(--border-subtle);
  border-radius:var(--radius);
  padding:14px 16px;
  cursor:grab;
  position:relative;
  overflow:hidden;
  user-select:none;
  touch-action:pan-y;
  transition:background .5s ease, border-color .2s, transform .12s;
}
.ticker-card:hover{border-color:var(--border-soft); background:var(--bg-card-hover);}
.ticker-card.sortable-ghost{opacity:.3;}
.ticker-card.sortable-drag{cursor:grabbing; box-shadow:0 8px 24px var(--shadow-drag);}
.ticker-card.flash-up{background:var(--up-dim);}
.ticker-card.flash-down{background:var(--down-dim);}

.tc-head{display:flex; justify-content:space-between; align-items:flex-start; gap:10px; margin-bottom:4px;}
.tc-head-left{min-width:0; flex:1 1 auto;}
.tc-head-right{flex:0 0 auto; text-align:right;}
.tc-symbol{font-weight:700;font-size:.98rem;letter-spacing:.02em; display:block;}
.tc-name{font-size:.72rem;color:var(--text-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.tc-price{font-size:1.35rem;font-weight:600;line-height:1.2;}
.tc-change{font-size:.78rem;font-weight:500; text-align:right;}
.tc-change.up{color:var(--up);}
.tc-change.down{color:var(--down);}
.tc-change.flat{color:var(--text-muted);}
.tc-spark{width:100%;height:60px;margin-top:6px;display:block;}
.tc-null{color:var(--text-faint);font-size:.85rem;}

/* P/L row - only rendered when the card's symbol is a portfolio holding */
.tc-pl{
  display:flex; justify-content:space-between; margin-top:8px; padding-top:8px;
  border-top:1px dashed var(--border-subtle);
}
.tc-pl .pl-item{display:flex; flex-direction:column; gap:1px;}
.tc-pl .pl-label{font-size:.58rem; text-transform:uppercase; letter-spacing:.05em; color:var(--text-faint);}
.tc-pl .pl-value{font-size:.78rem; font-weight:600; font-family:'IBM Plex Mono',monospace;}
.tc-pl .pl-value.up{color:var(--up);}
.tc-pl .pl-value.down{color:var(--down);}
.tc-pl .pl-value.flat{color:var(--text-muted);}


/* timeframe switch strip */
.tf-strip{
  display:flex; flex-wrap:wrap; gap:4px 4px; margin-top:10px;
}
.tf-btn{
  flex:0 0 auto; background:none; border:1px solid var(--border-subtle); color:var(--text-muted);
  font-size:.6rem; padding:2px 6px; border-radius:999px; line-height:1.5; cursor:pointer;
}
.tf-btn:hover{border-color:var(--border-soft); color:var(--text-primary);}
.tf-btn.active{background:var(--brand-dim); border-color:var(--brand); color:var(--text-primary);}

.tc-lowhigh{display:flex; justify-content:space-between; font-size:.66rem; color:var(--text-faint); margin-top:8px;}
.tc-lowhigh span b{color:var(--text-muted); font-weight:600; font-family:'IBM Plex Mono',monospace;}

.tc-updated{display:flex; align-items:center; gap:5px; font-size:.6rem; color:var(--text-faint); margin-top:8px;}
.tc-updated .live-dot{width:6px;height:6px;border-radius:50%;background:var(--up);box-shadow:0 0 5px var(--up);animation:pulse 2s ease-in-out infinite;}
.tc-updated.stale .live-dot{background:var(--text-faint); box-shadow:none; animation:none;}

/* ---------- context menu ---------- */
.ctx-menu{
  position:fixed; z-index:2000; min-width:210px; max-width:260px;
  background:var(--bg-panel); border:1px solid var(--border-soft); border-radius:8px;
  box-shadow:0 12px 32px var(--shadow-strong); padding:6px; display:none;
}
.ctx-menu button{
  display:block; width:100%; text-align:left; background:none; border:0;
  color:var(--text-primary); font-size:.86rem; padding:8px 10px; border-radius:6px;
}
.ctx-menu button:hover{background:var(--bg-card-hover);}
.ctx-menu button:disabled{color:var(--text-faint); cursor:default;}
.ctx-menu button:disabled:hover{background:none;}
.ctx-menu .ctx-sep{height:1px;background:var(--border-subtle);margin:6px 2px;}

/* ---------- big chart overlay ---------- */
.chart-overlay{
  position:fixed; inset:0; background:var(--overlay-scrim); backdrop-filter:blur(3px);
  display:none; align-items:center; justify-content:center; z-index:1500;
}
.chart-overlay.show{display:flex;}
.chart-panel{
  width:min(1000px,92vw); height:min(640px,84vh);
  background:var(--bg-panel); border:1px solid var(--border-soft); border-radius:12px;
  display:flex; flex-direction:column; overflow:hidden;
}
.chart-panel-head{
  display:flex; justify-content:space-between; align-items:center;
  padding:14px 18px; border-bottom:1px solid var(--border-subtle);
}
.chart-panel-body{flex:1; position:relative;}
#tv_chart_container{position:absolute; inset:0;}

/* ---------- settings ---------- */
.settings-wrap{padding:26px; max-width:980px; margin:0 auto;}
.settings-card{
  background:var(--bg-card); border:1px solid var(--border-subtle); border-radius:var(--radius);
  padding:20px 22px; margin-bottom:18px;
}
.settings-card h2{font-size:1rem; font-weight:700; margin-bottom:14px;}

.group-pill{
  display:inline-flex; align-items:center; gap:8px; background:var(--bg-panel);
  border:1px solid var(--border-subtle); border-radius:999px; padding:5px 8px 5px 14px; margin:0 8px 8px 0;
}
.group-pill input[type=text]{background:none;border:0;color:var(--text-primary);width:auto;font-size:.85rem;}
.group-pill input[type=text]:focus{outline:none;}
.group-pill .pill-switch{transform:scale(.8); margin:0;}
.group-pill .pill-del{
  border:0; background:var(--bg-card-hover); color:var(--text-muted); width:22px;height:22px;
  border-radius:50%; font-size:.75rem; line-height:1; flex:0 0 auto;
}

/* ticker row - stacks cleanly on narrow / mobile widths */
.ticker-row{
  display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap;
  gap:10px; padding:10px 0; border-bottom:1px solid var(--border-subtle);
}
.ticker-row:last-child{border-bottom:0;}
.ticker-row .tr-main{display:flex; flex-direction:column; min-width:0; flex:1 1 140px;}
.ticker-row .tr-main .sym{font-family:'IBM Plex Mono',monospace; font-weight:600; font-size:.88rem;}
.ticker-row .tr-main .nm{color:var(--text-muted); font-size:.74rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.ticker-row .tr-actions{display:flex; gap:8px; align-items:center; flex:0 0 auto;}
.ticker-row .tr-actions select{min-width:130px;}

@media (max-width:480px){
  .ticker-row{flex-direction:column; align-items:stretch;}
  .ticker-row .tr-actions{justify-content:space-between; width:100%;}
  .ticker-row .tr-actions select{flex:1;}
}

.search-result{
  padding:8px 12px; cursor:pointer; border-radius:6px; font-size:.86rem;
}
.search-result:hover{background:var(--bg-card-hover);}

.form-control, .form-select{
  background:var(--bg-panel); border:1px solid var(--border-soft); color:var(--text-primary);
}
.form-control:focus, .form-select:focus{
  background:var(--bg-panel); border-color:var(--brand); color:var(--text-primary);
  box-shadow:0 0 0 .18rem var(--brand-dim);
}
.form-label{color:var(--text-muted); font-size:.8rem;}
.btn-primary{background:var(--brand); border-color:var(--brand);}
.btn-outline-light{border-color:var(--border-soft); color:var(--text-primary);}
.btn-outline-danger{--bs-btn-color:var(--down);--bs-btn-border-color:var(--down);}

/* Bootstrap ships its own fixed colours for these; point them at our tokens
   so they follow whichever theme is active. */
.text-muted{color:var(--text-muted) !important;}
.form-check-label{color:var(--text-muted);}
.form-select{color:var(--text-primary);}
.form-select option{background:var(--bg-panel); color:var(--text-primary);}
.alert-success{background:var(--up-dim); border-color:var(--up); color:var(--up);}
.alert-danger{background:var(--down-dim); border-color:var(--down); color:var(--down);}

.install-body{background:radial-gradient(1200px 600px at 50% -10%, var(--install-glow), var(--bg-void));}
.install-card{background:var(--bg-card); border:1px solid var(--border-subtle); color:var(--text-primary);}
.install-card .form-control{background:var(--bg-panel);}

.empty-state{
  border:1px dashed var(--border-soft); border-radius:var(--radius); padding:40px;
  text-align:center; color:var(--text-muted);
}

/* ---------- portfolio ---------- */
.portfolio-wrap{padding:26px; max-width:1180px; margin:0 auto;}
.portfolio-summary{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:14px; margin-bottom:20px;
}
.summary-card{
  background:var(--bg-card); border:1px solid var(--border-subtle); border-radius:var(--radius); padding:16px;
}
.summary-card .label{font-size:.68rem; text-transform:uppercase; letter-spacing:.05em; color:var(--text-faint); margin-bottom:6px;}
.summary-card .value{font-size:1.35rem; font-weight:700; font-family:'IBM Plex Mono',monospace;}
.summary-card .value.up{color:var(--up);}
.summary-card .value.down{color:var(--down);}
.summary-card .sub{font-size:.74rem; color:var(--text-muted); margin-top:3px;}

.portfolio-layout{display:grid; grid-template-columns:1fr 320px; gap:20px; align-items:start;}
@media (max-width:900px){.portfolio-layout{grid-template-columns:1fr;}}

.holdings-card{
  background:var(--bg-card); border:1px solid var(--border-subtle); border-radius:var(--radius);
  padding:18px 20px;
}
.holdings-table{width:100%; table-layout:fixed; border-collapse:collapse; font-size:.83rem;}
.holdings-table th{
  text-align:left; color:var(--text-faint); font-size:.64rem; text-transform:uppercase;
  letter-spacing:.04em; padding:6px 8px; border-bottom:1px solid var(--border-soft);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.holdings-table td{padding:8px; border-bottom:1px solid var(--border-subtle); vertical-align:middle;}
.holdings-table tr:last-child td{border-bottom:0;}
.holdings-table .sym{font-family:'IBM Plex Mono',monospace; font-weight:600; white-space:nowrap;}
.holdings-table .nm{
  color:var(--text-muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%;
}
.holdings-table .num{font-family:'IBM Plex Mono',monospace; text-align:right; white-space:nowrap;}
.holdings-table .pl-main{display:block; font-weight:600;}
.holdings-table .pl-sub{display:block; font-size:.72rem; color:var(--text-muted); font-weight:400;}
.holdings-table .pl.up .pl-main{color:var(--up);}
.holdings-table .pl.down .pl-main{color:var(--down);}
.holdings-table input.inline-edit{
  width:100%; max-width:76px; background:var(--bg-panel); border:1px solid var(--border-soft); color:var(--text-primary);
  border-radius:6px; padding:3px 5px; font-family:'IBM Plex Mono',monospace; font-size:.78rem;
}

/* mobile / narrow fallback - the table can't reflow itself sensibly, so
   below 700px we swap it for a stacked card per holding instead. */
.holding-cards{display:none;}
@media (max-width:700px){
  .holdings-table{display:none;}
  .holding-cards{display:block;}
  .holding-card{
    background:var(--bg-panel); border:1px solid var(--border-subtle); border-radius:8px;
    padding:12px 14px; margin-bottom:10px;
  }
  .holding-card:last-child{margin-bottom:0;}
  .holding-card .hc-head{display:flex; justify-content:space-between; align-items:baseline; margin-bottom:2px;}
  .holding-card .hc-sym{font-family:'IBM Plex Mono',monospace; font-weight:700;}
  .holding-card .hc-name{color:var(--text-muted); font-size:.76rem; margin-bottom:10px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}
  .holding-card .hc-grid{display:grid; grid-template-columns:1fr 1fr; gap:10px 14px; font-size:.82rem;}
  .holding-card .hc-field label{display:block; font-size:.62rem; text-transform:uppercase; letter-spacing:.04em; color:var(--text-faint); margin-bottom:3px;}
  .holding-card .hc-field input{width:100%;}
  .holding-card .hc-value{font-family:'IBM Plex Mono',monospace;}
  .holding-card .hc-value.up{color:var(--up);}
  .holding-card .hc-value.down{color:var(--down);}
  .holding-card .hc-actions{margin-top:12px; display:flex; justify-content:flex-end;}
}

.pie-wrap{
  background:var(--bg-card); border:1px solid var(--border-subtle); border-radius:var(--radius);
  padding:18px; text-align:center;
}
.pie-legend{display:flex; flex-direction:column; gap:7px; margin-top:14px; text-align:left; font-size:.78rem;}
.pie-legend .legend-row{display:flex; align-items:center; gap:8px;}
.pie-legend .swatch{width:10px; height:10px; border-radius:2px; flex:0 0 auto;}
.pie-legend .legend-name{font-family:'IBM Plex Mono',monospace; font-weight:600;}
.pie-legend .legend-pct{margin-left:auto; color:var(--text-muted);}

@media (prefers-reduced-motion: reduce){
  .brand .dot, .tc-updated .live-dot{animation:none;}
  .ticker-card{transition:none;}
}

/* ---------- toolbar: chart mode, view mode, theme ---------- */
.dash-toolbar{flex-wrap:wrap; align-items:center;}
.dash-toolbar .toolbar-spacer{flex:1 1 auto;}

.mode-strip{
  display:inline-flex; background:var(--bg-panel); border:1px solid var(--border-subtle);
  border-radius:999px; padding:2px; gap:2px;
}
.mode-btn{
  background:none; border:0; color:var(--text-muted); font-size:.72rem; font-weight:500;
  padding:4px 11px; border-radius:999px; line-height:1.5; cursor:pointer; white-space:nowrap;
}
.mode-btn:hover{color:var(--text-primary);}
.mode-btn.active{background:var(--brand-dim); color:var(--text-primary);}

.theme-toggle{
  background:var(--bg-panel); border:1px solid var(--border-subtle); color:var(--text-muted);
  width:30px; height:30px; border-radius:50%; line-height:1; font-size:.9rem; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
}
.theme-toggle:hover{color:var(--text-primary); border-color:var(--border-soft);}
.topbar .theme-toggle{margin-left:18px;}

/* ---------- two-line quote (pre-market / after-hours) ---------- */
.tc-quote-line{display:flex; align-items:baseline; justify-content:flex-end; gap:7px;}
.tc-quote-ext{margin-top:1px;}
.tc-ext-tag{
  font-size:.54rem; font-weight:700; letter-spacing:.06em; color:var(--text-faint);
  border:1px solid var(--border-soft); border-radius:3px; padding:0 3px; line-height:1.4;
}
.tc-price-ext{font-size:1rem; font-weight:600; line-height:1.2;}
.tc-change-ext{font-size:.7rem; font-weight:500;}
.tc-change-ext.up{color:var(--up);}
.tc-change-ext.down{color:var(--down);}
.tc-change-ext.flat{color:var(--text-muted);}

/* The percentage pill is the list view's headline; hidden in card view,
   where the full "+1.23 (+0.45%)" line is shown instead. */
.tc-pct-pill{
  display:none; font-family:'IBM Plex Mono',ui-monospace,monospace; font-weight:600;
  font-size:.78rem; padding:2px 8px; border-radius:6px; line-height:1.45; white-space:nowrap;
}
.tc-pct-pill.up{background:var(--up); color:var(--pill-text);}
.tc-pct-pill.down{background:var(--down); color:var(--pill-text);}
.tc-pct-pill.flat{background:var(--bg-card-hover); color:var(--text-muted);}

/* ---------- list view ----------
   A compact reading layout for phones, close to the Yahoo Finance app: one
   row per symbol, name under the ticker, a small chart, and the price with
   the percentage as a coloured pill. The per-card timeframe strip, day range
   and P/L row belong to the card view, which has room for them - a card
   keeps whichever timeframe it was on when you switch back. */
#dashboard-grid.view-list{
  display:block;
  background:var(--bg-card);
  border:1px solid var(--border-subtle);
  border-radius:var(--radius);
  overflow:hidden;
}
.view-list .ticker-card{
  display:grid;
  grid-template-columns:minmax(0,1fr) 104px auto;
  align-items:center;
  gap:12px;
  border:0;
  border-bottom:1px solid var(--border-subtle);
  border-radius:0;
  padding:11px 15px;
}
.view-list .ticker-card:last-child{border-bottom:0;}
.view-list .ticker-card:hover{background:var(--bg-card-hover);}
.view-list .tc-head{display:contents;}
.view-list .tc-head-left{grid-column:1; margin:0;}
.view-list .tc-symbol{font-size:1rem;}
.view-list .tc-name{font-size:.78rem;}
.view-list .tc-spark{grid-column:2; width:104px; height:42px; margin:0;}
.view-list .tc-head-right{grid-column:3;}
.view-list .tc-quote-line{flex-direction:column; align-items:flex-end; gap:3px;}
.view-list .tc-price{font-size:1.12rem;}
.view-list .tc-change{display:none;}
.view-list .tc-pct-pill{display:inline-block;}
.view-list .tc-quote-ext{flex-direction:row; align-items:baseline; gap:5px; margin-top:4px;}
.view-list .tc-price-ext{font-size:.82rem;}
.view-list .tc-change-ext{font-size:.66rem;}
/* Hidden outright rather than kept invisible: rows sit in a flow layout, so
   an unused row can collapse without leaving a hole beside its neighbours. */
.view-list .tc-pl,
.view-list .tc-lowhigh,
.view-list .tf-strip,
.view-list .tc-updated{display:none;}

@media (max-width:520px){
  .view-list .ticker-card{grid-template-columns:minmax(0,1fr) 74px auto; gap:9px; padding:10px 12px;}
  .view-list .tc-spark{width:74px; height:38px;}
  .view-list .tc-price{font-size:1rem;}
  .dash-toolbar #dashSearch{max-width:none; flex:1 1 100%;}
}

/* ---------- card view: sparkline sizing ---------- */
.view-cards .tc-spark{height:60px;}

/* Shown in the day-range row when a timeframe has no bars at all, or when
   its series stops before the present - otherwise a stale range reads as a
   low/high the live price sits outside of, with nothing to explain it. */
.tc-range-note{
  color:var(--down); font-size:.62rem; font-weight:500; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; cursor:help;
}
/* Informational variant of the range note - the data is fine, it was just
   rebuilt from a finer interval than the one asked for. */
.tc-range-note.is-info{color:var(--text-faint); font-weight:400;}

/* The value-over-time canvas had no CSS width, so it rendered at the 300px
   canvas default inside a full-width card. */
#historyChart{width:100%; display:block;}
.hist-controls{display:flex; align-items:center; gap:8px; flex-wrap:wrap;}
.hist-controls .form-select{width:auto; background:var(--bg-panel); color:var(--text-primary);
  border-color:var(--border-soft); font-size:.75rem; padding:2px 24px 2px 8px;}
