:root{
  --bg:#0e1116; --panel:#151a21; --panel2:#1b222b; --line:#242c37;
  --text:#e6edf3; --dim:#8b98a9; --faint:#5d6875;
  --accent:#4d8ef7; --bad:#f2545b; --warn:#e8a33d; --good:#3fb950;
  --row:#121820; --rowalt:#141b24;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
  background:var(--bg); color:var(--text);
  font:13px/1.45 "Inter","Segoe UI",system-ui,-apple-system,sans-serif;
  display:flex; flex-direction:column;
}

/* ---------------------------------------------------------------- top bar */
.topbar{
  display:flex; align-items:center; justify-content:space-between; gap:20px;
  padding:12px 18px; background:var(--panel); border-bottom:1px solid var(--line);
  flex-wrap:wrap; position:sticky; top:0; z-index:30;
}
.brand{display:flex;align-items:center;gap:10px}
.brand h1{font-size:15px;font-weight:650;margin:0;letter-spacing:.2px}
.dot{width:9px;height:9px;border-radius:50%;background:var(--bad);box-shadow:0 0 10px var(--bad)}
.range{color:var(--faint);font-size:12px;font-variant-numeric:tabular-nums}
.controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.filterbtn{display:none}          /* phone only -- see the mobile block */

.ctlabel{color:var(--faint);font-size:11px;text-transform:uppercase;letter-spacing:.6px}
.segmented{display:flex;background:var(--panel2);border:1px solid var(--line);border-radius:7px;overflow:hidden}
.segmented button{
  background:none;border:0;color:var(--dim);padding:6px 13px;font-size:12.5px;
  cursor:pointer;font-family:inherit;white-space:nowrap;
}
.segmented button:hover{color:var(--text)}
.segmented button.on{background:var(--accent);color:#fff;font-weight:600}

input[type=search]{
  background:var(--panel2);border:1px solid var(--line);color:var(--text);
  padding:6px 10px;border-radius:7px;width:190px;font-family:inherit;font-size:12.5px;
}
input[type=search]:focus{outline:none;border-color:var(--accent)}
.chk{display:flex;align-items:center;gap:5px;color:var(--dim);font-size:12.5px;cursor:pointer;user-select:none}
.chk input{accent-color:var(--accent);cursor:pointer;margin:0}
button#refresh{
  background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  padding:6px 12px;border-radius:7px;cursor:pointer;font-family:inherit;font-size:12.5px;
}
button#refresh:hover{color:var(--text);border-color:var(--accent)}
button#refresh.busy{opacity:.5;pointer-events:none}

/* ------------------------------------------------------------------ table */
.tablewrap{flex:1;overflow:auto;padding:10px 18px 30px}
table{border-collapse:separate;border-spacing:0;width:100%;min-width:1180px}
thead th{
  position:sticky;top:0;z-index:20;background:var(--panel);
  border-bottom:1px solid var(--line);color:var(--dim);font-weight:600;
  font-size:11px;text-transform:uppercase;letter-spacing:.5px;
  padding:9px 10px;text-align:right;white-space:nowrap;cursor:pointer;user-select:none;
}
thead th:first-child{text-align:left}
thead th:hover{color:var(--text)}
thead th .arrow{color:var(--accent);font-size:9px;margin-left:3px}

tbody td{
  padding:7px 10px;text-align:right;border-bottom:1px solid var(--line);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}
tbody td:first-child{text-align:left;max-width:420px}
tr.combo{background:var(--row)}
tr.combo:nth-child(even){background:var(--rowalt)}
tr.combo:hover{background:#1a2230}
tr.combo.flagged td:first-child{box-shadow:inset 3px 0 0 var(--bad)}


.name{display:flex;align-items:center;gap:7px}
.caret{
  display:inline-flex;align-items:center;justify-content:center;
  width:14px;height:14px;flex:0 0 14px;color:var(--faint);
  transition:transform .16s ease,color .16s ease;
}
.caret svg{width:13px;height:13px;fill:none;stroke:currentColor;
  stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
tr:hover > td .caret{color:var(--dim)}
.caret.open{transform:rotate(90deg);color:var(--accent)}
tr:hover > td .caret.open{color:var(--accent)}
.label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pill{
  font-size:10px;padding:1px 6px;border-radius:9px;font-weight:650;flex:0 0 auto;
  background:rgba(242,84,91,.15);color:var(--bad);border:1px solid rgba(242,84,91,.3);
}

.val{display:inline-flex;align-items:baseline;gap:5px;justify-content:flex-end}
.delta{font-size:10.5px;font-variant-numeric:tabular-nums}
.delta.bad{color:var(--bad)} .delta.good{color:var(--good)}
.delta.warn{color:var(--warn)} .delta.flat{color:var(--faint)}
/* Volume variance: deliberately uncoloured, but --faint is too dim to read a
   leading +/- at a glance and the sign is the whole point of the number. */
.delta.vol{color:var(--dim)}
td.hot{background:rgba(242,84,91,.09);box-shadow:inset 2px 0 0 var(--bad)}
td.mild{background:rgba(232,163,61,.07)}
.null{color:var(--faint)}
.thin{color:var(--faint);font-size:10.5px;margin-left:4px}

/* ------------------------------------------------------------- misc / foot */
.state{padding:26px;text-align:center;color:var(--dim)}
.state.err{color:var(--bad);white-space:pre-wrap;text-align:left;font-family:ui-monospace,Consolas,monospace;font-size:12px}
.spin{display:inline-block;width:13px;height:13px;border:2px solid var(--line);
  border-top-color:var(--accent);border-radius:50%;animation:s .7s linear infinite;vertical-align:-2px;margin-right:7px}
@keyframes s{to{transform:rotate(360deg)}}

.foot{padding:10px 18px 22px;border-top:1px solid var(--line);background:var(--panel)}
.linkbtn{background:none;border:0;color:var(--dim);cursor:pointer;font-family:inherit;font-size:12px;padding:0}
.linkbtn:hover{color:var(--accent)}
.build{color:var(--faint);font-size:10.5px;margin-left:12px;font-variant-numeric:tabular-nums}
.defs{display:grid;grid-template-columns:repeat(auto-fill,minmax(255px,1fr));gap:7px;margin-top:11px}
/* a class with display:grid outranks the UA [hidden] rule, so say it explicitly */
.defs[hidden]{display:none}
.defs div{background:var(--panel2);border:1px solid var(--line);border-radius:7px;padding:8px 11px}
.defs b{color:var(--text);font-weight:620} .defs span{color:var(--dim)}
.defs .note{grid-column:1/-1;background:rgba(77,142,247,.07);border-color:rgba(77,142,247,.25);color:var(--dim);line-height:1.6}
.defs code{background:#0d1218;padding:1px 5px;border-radius:4px;color:#9fc4ff;font-size:11.5px}

/* ---------------------------------------------------------------- tooltip */
.tip{
  position:fixed;z-index:100;pointer-events:none;
  background:#0b0f14;border:1px solid var(--line);border-radius:9px;
  padding:10px 12px;min-width:225px;max-width:330px;
  box-shadow:0 10px 34px rgba(0,0,0,.6);
}
.tip-h{font-weight:650;font-size:12.5px;color:var(--text)}
.tip-f{color:var(--faint);font-size:11px;margin:1px 0 8px}
.tip-grid{display:grid;grid-template-columns:1fr auto;gap:3px 14px;align-items:baseline}
.tip-l{color:var(--dim);font-size:11.5px;display:flex;flex-direction:column}
.tip-sub{color:var(--faint);font-size:10px;font-variant-numeric:tabular-nums}
.tip-v{text-align:right;font-variant-numeric:tabular-nums;font-size:12.5px;font-weight:600;color:var(--text)}
.tip-v.bad{color:var(--bad)} .tip-v.good{color:var(--good)} .tip-v.flat{color:var(--dim)}
.tip-parts{margin-top:9px;padding-top:8px;border-top:1px solid var(--line)}
.tip-parts-h{color:var(--faint);font-size:10px;text-transform:uppercase;letter-spacing:.6px;margin-bottom:4px}
.tip-parts .tip-v{font-weight:500;color:var(--dim);font-size:11.5px}
.tip-note{color:var(--faint);font-size:10px;margin-top:5px;text-align:right}
.tip-warn{margin-top:8px;padding-top:7px;border-top:1px solid var(--line);color:var(--warn);font-size:11px;line-height:1.4}

/* ------------------------------------------------------- drawer + view swap */
.burger{
  background:none;border:0;cursor:pointer;padding:5px 6px;display:flex;
  flex-direction:column;gap:3.5px;border-radius:6px;
}
.burger:hover{background:var(--panel2)}
.burger span{display:block;width:16px;height:2px;background:var(--dim);border-radius:2px}
.burger:hover span{background:var(--text)}

.drawer{
  position:fixed;top:0;left:0;bottom:0;width:255px;z-index:60;
  background:var(--panel);border-right:1px solid var(--line);
  transform:translateX(-100%);transition:transform .16s ease;
  padding:14px 12px;display:flex;flex-direction:column;gap:6px;
}
.drawer.open{transform:none}
.drawer-h{
  color:var(--faint);font-size:10.5px;text-transform:uppercase;letter-spacing:.7px;
  padding:2px 8px 8px;
}
.navitem{
  background:none;border:1px solid transparent;border-radius:8px;cursor:pointer;
  text-align:left;padding:9px 11px;font-family:inherit;display:flex;
  flex-direction:column;gap:2px;color:var(--dim);
}
.navitem:hover{background:var(--panel2);color:var(--text)}
.navitem.on{background:var(--panel2);border-color:var(--accent);color:var(--text)}
.navitem-t{font-size:13px;font-weight:620}
.navitem-d{font-size:11px;color:var(--faint);line-height:1.35}
.scrim{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:55}

/* only the active view's controls are shown */
body[data-view="sources"] .v-offers,
body[data-view="sources"] .v-splits,
body[data-view="sources"] .v-wtd,
body[data-view="wtd"]     .v-splits,
body[data-view="splits"]  .v-sources,
body[data-view="splits"]  .v-wtd,
body[data-view="wtd"]     .v-sources{display:none !important}
/* "Issues only" is meaningful in Sources (flagged rows) and WTD (off target),
   but Offer Splits carries no flags at all. */
body[data-view="splits"]  .issuesctl{display:none !important}

/* -------------------------------------------------------------- date range */
.daterange{display:flex;align-items:center;gap:5px}
.daterange input[type=date]{
  background:var(--panel2);border:1px solid var(--line);color:var(--text);
  padding:5px 7px;border-radius:7px;font-family:inherit;font-size:12px;
  color-scheme:dark;
}
.daterange input[type=date]:focus{outline:none;border-color:var(--accent)}
.daterange .dash{color:var(--faint);font-size:11px}
.daterange button{
  background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  padding:5px 10px;border-radius:7px;cursor:pointer;font-family:inherit;font-size:12px;
}
.daterange button:hover{color:var(--text);border-color:var(--accent)}

.stepper{display:flex;align-items:center;gap:0;
  border:1px solid var(--line);border-radius:7px;overflow:hidden;background:var(--panel2)}
.stepper button{
  background:none;border:0;color:var(--dim);cursor:pointer;font-size:15px;
  padding:3px 9px;font-family:inherit;line-height:1.5;
}
.stepper button:hover{color:var(--accent);background:var(--panel)}
.stepper select{
  background:var(--panel2);border:0;border-left:1px solid var(--line);
  border-right:1px solid var(--line);color:var(--text);
  padding:6px 8px;font-family:inherit;font-size:12.5px;max-width:185px;cursor:pointer;
}
.stepper select:focus{outline:none}

/* ------------------------------------------------------- offers view rows */
tr.grouphead{background:#1a2432}
tr.grouphead td{
  border-top:1px solid var(--accent);border-bottom:1px solid var(--line);
  font-weight:640;padding-top:9px;padding-bottom:9px;
}
tr.grouphead .glabel{font-size:13px;font-weight:680;color:var(--text)}
tr.grouphead .val{color:var(--text)}
tr.offerrow td:first-child{padding-left:26px}
tr.offerrow{background:var(--row)}
tr.offerrow:hover{background:#1a2230}

/* ------------------------------------------------------------ day breakdown */
tr.expandable{cursor:pointer}
tr.dayrow{background:#0b0f14;color:var(--dim);font-size:12.5px}
tr.dayrow:hover{background:#101720}
tr.dayrow td:first-child{padding-left:52px}
tr.dayrow .daylabel{color:var(--faint);font-variant-numeric:tabular-nums}
tr.dayrow td{border-bottom:1px solid #182029}

/* ------------------------------------------------------------------ targets */
td.targetcell{text-align:left;white-space:nowrap}
.tgtbox{display:flex;align-items:center;gap:7px}
.tgtval{color:var(--dim);font-variant-numeric:tabular-nums;font-size:12px}
.tgtpill{
  font-size:10px;padding:1.5px 7px;border-radius:9px;font-weight:650;
  letter-spacing:.2px;border:1px solid transparent;
}
.tgtpill.tgt-on{background:rgba(63,185,80,.14);color:var(--good);border-color:rgba(63,185,80,.32)}
.tgtpill.tgt-close{background:rgba(232,163,61,.14);color:var(--warn);border-color:rgba(232,163,61,.32)}
.tgtpill.tgt-off{background:rgba(242,84,91,.15);color:var(--bad);border-color:rgba(242,84,91,.32)}
.tgtpill.tgt-nodata{background:var(--panel2);color:var(--faint);border-color:var(--line)}

.delta.tgt-on{color:var(--good)}
.delta.tgt-close{color:var(--warn)}
.delta.tgt-off{color:var(--bad)}
td.tgt-on{background:rgba(63,185,80,.08);box-shadow:inset 2px 0 0 var(--good)}
td.tgt-close{background:rgba(232,163,61,.08);box-shadow:inset 2px 0 0 var(--warn)}
td.tgt-off{background:rgba(242,84,91,.10);box-shadow:inset 2px 0 0 var(--bad)}

/* ------------------------------------------------------------- telegram send */
.tgbtn{
  display:inline-flex;align-items:center;gap:6px;
  background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  padding:6px 12px;border-radius:7px;cursor:pointer;font-family:inherit;font-size:12.5px;
}
.tgbtn:hover{color:var(--text);border-color:var(--accent)}
.tgbtn .tgicon{font-size:12px;color:var(--accent)}
.tgbtn.pending{opacity:.6;pointer-events:none}

.toast{
  position:fixed;bottom:22px;left:50%;transform:translateX(-50%) translateY(8px);
  background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--accent);
  color:var(--text);padding:11px 16px;border-radius:9px;font-size:12.5px;
  box-shadow:0 12px 34px rgba(0,0,0,.55);z-index:120;max-width:min(560px,92vw);
  opacity:0;transition:opacity .16s ease,transform .16s ease;pointer-events:none;
}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.toast b{color:var(--accent);font-weight:640}
.toast .sub{color:var(--dim);display:block;margin-top:3px;line-height:1.5}

/* -------------------------------------------------------------- header fix */
thead th.leftcol{text-align:left}

/* ------------------------------------------------------------------- chart */
tr.chartrow td{background:#0b0f14;padding:0;border-bottom:1px solid var(--line)}
/* The table is wider than the viewport and scrolls sideways; sticking the chart
   to the left edge keeps the whole plot on screen instead of running off with
   the columns. */
.chartbox{position:sticky;left:0;padding:16px 20px 12px;
  width:calc(100vw - 76px);box-sizing:border-box}
/* The box spans the viewport so the plot never scrolls off with the columns;
   the svg is capped and auto-margined so it sits centred inside it. */
.chart{width:100%;max-width:1120px;margin:0 auto;height:auto;display:block;overflow:visible}
.c-empty{color:var(--faint);padding:14px 2px;font-size:12.5px}

/* Blue / amber is the safest pair to tell apart, including for colour-blind
   readers -- and each y-axis is tinted to its own series so nobody has to guess
   which scale a mark belongs to. */
.c-spend{color:#5b9cf8}
.c-cpa{color:#f0a742}

.c-grid{stroke:#1b2430;stroke-width:1}
.c-axis{stroke:#2b3644;stroke-width:1}
.c-tick{font-size:10.5px;font-variant-numeric:tabular-nums;text-anchor:end}
.c-tick-spend{fill:#5b9cf8;opacity:.75}
.c-tick-cpa{fill:#f0a742;opacity:.75}
.c-xlab{fill:var(--faint);font-size:10.5px;font-variant-numeric:tabular-nums}

.c-bar{fill:#5b9cf8;opacity:.42}
.c-line{fill:none;stroke:#f0a742;stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round}
.c-dot{fill:#f0a742;stroke:#0b0f14;stroke-width:2}
.c-dot.over{fill:var(--bad)}
.c-target{stroke:var(--bad);stroke-width:1.5;stroke-dasharray:5 4;opacity:.7;fill:none}

.c-legtext{fill:var(--dim);font-size:11.5px}
.c-cross{stroke:#3a4757;stroke-width:1;stroke-dasharray:3 3;pointer-events:none}
.c-hit{fill:transparent;cursor:crosshair}

.tip-swatch{width:9px;height:9px;border-radius:2px;display:inline-block;margin-right:6px}
.tip-swatch.c-key-spend{background:#5b9cf8;opacity:.7}
.tip-swatch.c-key-cpa{background:#f0a742}
.tip-l{align-items:baseline}
.tip-note2{margin-top:7px;padding-top:6px;border-top:1px solid var(--line);
  color:var(--faint);font-size:10.5px}

/* --------------------------------------------------------------- scale call */
.c-rectext{font-size:12.5px;font-weight:680}
.c-recsub{font-size:10px;fill:var(--faint)}
.c-rec.rec-up .c-rectext{fill:var(--good)}
.c-rec.rec-hold .c-rectext{fill:var(--warn)}
.c-rec.rec-down .c-rectext{fill:var(--bad)}

/* ------------------------------------------------------------------ split % */
td.splitcell{font-variant-numeric:tabular-nums}
tr.grouphead td.splitcell{color:var(--dim)}
tr.dayrow td.splitcell{color:var(--faint)}
/* Split health is flagged with a pill on the offer name, not by tinting the
   number -- a coloured cell says "something", a tag says what. */
tr.grouphead.flagged td:first-child{box-shadow:inset 3px 0 0 var(--bad)}

/* ------------------------------------------------- flagged split day rows */
tr.dayrow.daybad td:first-child{box-shadow:inset 3px 0 0 var(--bad)}
tr.dayrow.daybad .daylabel{color:var(--bad)}
/* The split cells use the same treatment as the KPI cells (td.hot / td.won):
   matching tint alpha, matching inset, number left in normal ink. All four
   highlighted cells have to look alike or the eye keeps ranking them. */
td.splitcell.splitheld{background:rgba(242,84,91,.09);box-shadow:inset 2px 0 0 var(--bad);
  color:var(--text)}
td.splitcell.splitwon{background:rgba(63,185,80,.09);box-shadow:inset 2px 0 0 var(--good);
  color:var(--text)}

/* ------------------------------------------------- Offer Splits, by date */
tr.datehead{background:#141c26;cursor:pointer}
tr.datehead:hover{background:#18222e}
tr.datehead td{border-bottom:1px solid var(--line);padding-top:7px;padding-bottom:7px}
tr.datehead td:first-child{padding-left:24px}
tr.datehead .datelabel{font-weight:640;font-variant-numeric:tabular-nums;color:var(--text)}
tr.datevariant td:first-child{padding-left:52px}
tr.datevariant{background:var(--row)}
tr.datevariant:hover{background:#1a2230}
tr.datevariant.daybad td:first-child{box-shadow:inset 3px 0 0 var(--bad)}

/* Winner of the day in the By-date view. Everything between the winner and a
   flagged loser stays plain on purpose -- if the middle were coloured too, the
   two colours that mean something would stop standing out. */
tr.datevariant.daywin td:first-child{box-shadow:inset 3px 0 0 var(--good)}
/* Deliberately the mirror image of td.hot -- same tint alpha, same inset width,
   and the number left in normal ink. The first version recoloured and bolded the
   text as well, so green shouted while red only whispered and the two were hard to
   scan side by side. */
td.won{background:rgba(63,185,80,.09);box-shadow:inset 2px 0 0 var(--good)}

/* ------------------------------------------------- Actual $ Lost/Gained */
td.dollarscell{font-variant-numeric:tabular-nums;white-space:nowrap}
td.dollarscell .gain{color:var(--good);font-weight:620}
td.dollarscell .loss{color:var(--bad);font-weight:620}

/* --------------------------------------------------- Offer Sources trend bar */
.trendbar{display:flex;align-items:center;justify-content:space-between;gap:14px;
  margin-bottom:10px;flex-wrap:wrap}
.trendname{color:var(--dim);font-size:12px;font-weight:600}
.trendctl{display:flex;align-items:center;gap:8px}
.trendsel{
  background:var(--panel2);border:1px solid var(--line);color:var(--text);
  padding:5px 8px;border-radius:7px;font-family:inherit;font-size:12px;cursor:pointer;
}
.trendsel:focus{outline:none;border-color:var(--accent)}
.trendbar .segmented button{padding:4px 10px;font-size:11.5px}

/* ------------------------------------------------------------- chart titles */
.charttitle{margin-bottom:10px}
.ct-main{color:var(--text);font-size:13px;font-weight:650;letter-spacing:.1px}
.ct-sub{color:var(--faint);font-size:11px;margin-top:2px}
.trendbar .charttitle{margin-bottom:0}

/* trendlines: thin, dashed, subordinate to the series they summarise */
.c-fit{stroke:#f0a742;stroke-width:1.5;stroke-dasharray:6 4;opacity:.85;fill:none}

.togglebtn{
  background:var(--panel2);border:1px solid var(--line);color:var(--dim);
  padding:4px 11px;border-radius:7px;cursor:pointer;font-family:inherit;font-size:11.5px;
}
.togglebtn:hover{color:var(--text);border-color:var(--faint)}
.togglebtn.on{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}

/* ------------------------------------------------------- narrow: pin labels */
/* The table needs about 1220px to lay out without scrolling. Below that it
   scrolls sideways, and the moment it does, the row label has to stay put --
   otherwise you scroll to a wall of numbers with no idea whose they are. This
   tier is deliberately separate from the phone tier below: a tablet in portrait
   needs the pinned column but has plenty of room for everything else. */
@media (max-width: 1220px) {
  /* Backgrounds are inherited rather than hardcoded so the zebra striping, the
     hover state and every row type (group, day, variant) come through
     unchanged -- each of those sets its own background on the tr. Chart rows are
     excluded: their single full-width cell is already sticky. */
  thead th:first-child,
  tbody tr:not(.chartrow) > td:first-child{
    position:sticky; left:0; z-index:22;
    background-color:inherit;
    /* A border, not a box-shadow: the flagged-row marker is an inset shadow on
       this same cell and the two would overwrite each other. */
    border-right:1px solid var(--line);
  }
  thead th:first-child{z-index:26;background:var(--panel)}
}

/* ------------------------------------------------------------------ mobile */
/* The dash is a wide numeric table, and the comparison ACROSS columns is the
   product -- Pur CPA next to its own purchase count next to Pur CR. Reflowing
   each row into a stacked card would destroy exactly that. So the table stays a
   table and scrolls sideways under a pinned label, and what changes here is
   everything around it: the chrome shrinks to leave the data the screen. */
@media (max-width: 760px) {
  /* -- top bar ------------------------------------------------------------ */
  .topbar{padding:9px 12px;gap:8px}
  .brand{gap:9px;flex:1 1 100%;min-width:0}
  .brand h1{font-size:14px;white-space:nowrap}
  .range{flex:1 1 100%;order:3;font-size:11px;line-height:1.4}
  .ctlabel{display:none}                 /* "COMPARE VS" -- the pills say it */

  /* Collapsed by default. On the Offers view the full bar is 289px of an 812px
     screen -- more than a third of the phone gone to controls that are set once
     and then left alone. The range line stays visible above, so the window in
     force is readable without opening it. */
  .filterbtn{
    display:inline-block;margin-left:auto;flex:0 0 auto;
    background:var(--panel2);border:1px solid var(--line);color:var(--dim);
    padding:6px 12px;border-radius:7px;font-family:inherit;font-size:12px;
    cursor:pointer;
  }
  body.filters-open .filterbtn{border-color:var(--accent);color:var(--text)}
  .controls{display:none;gap:7px;flex:1 1 100%}
  body.filters-open .controls{display:flex}
  #search{flex:1 1 100%;min-width:0}
  .stepper{flex:1 1 100%}
  .stepper select{flex:1;max-width:none;min-width:0}
  .daterange{flex-wrap:wrap}
  .daterange input[type=date]{flex:1;min-width:0}

  /* Comfortable thumb targets without making the bar taller than the data. */
  .segmented button{padding:8px 12px;font-size:12.5px}
  .daterange button, .tgbtn, .controls > button{padding:8px 12px}

  /* -- the table ---------------------------------------------------------- */
  .tablewrap{padding:8px 0 24px;overscroll-behavior-x:contain}
  table{min-width:0}                     /* let it size to content, not 1180px */
  thead th{padding:9px 8px}
  tbody td{padding:8px 8px}

  /* A fixed band, not just a cap: the grid below has a small min-content width,
     so without a floor the table would collapse the name to a few characters. */
  tbody tr:not(.chartrow) > td:first-child,
  thead th:first-child{min-width:44vw;max-width:44vw}
  tbody tr:not(.chartrow) > td:first-child{white-space:normal}

  /* Wrap to three lines rather than truncating. Offer source names are
     front-loaded with the vendor -- "Hero - Skin - TPS (EF) - CPA ($96)" -- so a
     trailing ellipsis cuts off the only part that distinguishes TPS from TFC.
     Grid, not flex: the caret holds its own column so the wrapped name never
     pushes it onto a line of its own, and the badges stack under the name
     instead of stealing width from it. */
  .name{display:grid;grid-template-columns:14px 1fr;gap:2px 7px;align-items:start}
  .name .caret{margin-top:2px}
  .name > .label, .name > .pill, .name > .thin{grid-column:2}
  .name > .pill, .name > .thin{justify-self:start;margin-left:0}
  .label{
    min-width:0;white-space:normal;overflow:hidden;
    display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  }

  /* A tap on a row is "expand", never "select this word". On a touch screen the
     browser resolves the ambiguity as a text selection and the row never opens.
     Scoped to rows that are actually clickable so numbers stay copyable. */
  tr.expandable, tr.datehead, tr.grouphead{-webkit-user-select:none;user-select:none}
  tr.expandable td, tr.datehead td{-webkit-tap-highlight-color:transparent}

  /* Indents that read as hierarchy on a wide screen just eat the label here. */
  tr.offerrow td:first-child{padding-left:14px}
  tr.datehead td:first-child{padding-left:14px}
  tr.dayrow td:first-child,
  tr.datevariant td:first-child{padding-left:22px}

  /* -- charts, drawer, footer --------------------------------------------- */
  /* Charts are drawn on a fixed 980px canvas, so fitting one to a 350px screen
     renders the axis labels at under 4px -- on screen but unreadable, which is
     worse than absent because it still looks like information. The plot keeps a
     legible size and its box scrolls instead. */
  .chartbox{width:calc(100vw - 8px);padding:12px 10px 10px;
    overflow-x:auto;overscroll-behavior-x:contain}
  .chart{width:900px;max-width:none;margin:0}
  /* The controls above it are a second flex row that does not wrap on its own,
     so the Trendline toggle falls off the right edge. */
  .trendctl{flex-wrap:wrap;gap:7px}
  .trendsel{flex:1 1 150px;min-width:0}

  .drawer{width:min(280px,84vw)}
  .foot{padding:10px 12px 20px}
  .defs{grid-template-columns:1fr}
  .toast{left:12px;right:12px;transform:none;max-width:none}
  .toast.show{transform:none}
}
