/* ---------------------------------------------------------------
   Pokémon 30th Tracker - single-screen dashboard
   Everything fits one viewport; only the listing table scrolls,
   inside its own panel.

   Restrained theming: the identity is a drawn Poke Ball, the logo
   blue as the accent, one gold highlight for a bargain, and a type
   dot per product. Washes and borders across the chrome were tried
   and removed -- they competed with the numbers, which are the whole
   point of the page.
   --------------------------------------------------------------- */

:root {
  color-scheme: light;

  /* Pokémon's own colours, kept as constants so the roles below can be
     re-pointed without losing the reference. */
  --poke-blue:   #3b4cca;   /* logo blue   */
  --poke-gold:   #ffcb05;   /* logo yellow */
  --poke-red:    #ee1515;   /* Poké Ball   */

  --bg:        #eef0f4;
  --panel:     #ffffff;
  --panel-2:   #f6f7f9;
  --ink:       #141720;
  --ink-2:     #464d5e;
  --muted:     #7a8293;
  --line:      #e1e5ec;
  --line-soft: #eef1f5;

  --accent:    #2c3bb5;
  --accent-in: #ffffff;
  --good:      #1a9c52;
  --good-bg:   #e6f6ec;
  --bad:       #cf2a20;
  --warn:      #a86a00;
  --warn-bg:   #fdf4e0;

  --median:    #2c3bb5;

  --shadow: 0 1px 2px rgba(20, 22, 29, .05), 0 1px 3px rgba(20, 22, 29, .07);
  --radius: 12px;

}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    /* Night: deep navy rather than neutral grey, so the gold reads warm
       against it the way foil does on a dark card. */
    --bg:        #0b0d12;
    --panel:     #13161d;
    --panel-2:   #181c25;
    --ink:       #e9ecf2;
    --ink-2:     #b0b7c5;
    --muted:     #79808f;
    --line:      #232834;
    --line-soft: #1b1f28;

    --accent:    #8195ff;
    --accent-in: #0a0c14;
    --good:      #35d07f;
    --good-bg:   #0e2a1c;
    --bad:       #ff6b60;
    --warn:      #ffc043;
    --warn-bg:   #2b2007;

    --median:    #8195ff;

    --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 2px 10px rgba(0, 0, 0, .25);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
    /* Night: deep navy rather than neutral grey, so the gold reads warm
       against it the way foil does on a dark card. */
    --bg:        #0b0d12;
    --panel:     #13161d;
    --panel-2:   #181c25;
    --ink:       #e9ecf2;
    --ink-2:     #b0b7c5;
    --muted:     #79808f;
    --line:      #232834;
    --line-soft: #1b1f28;

    --accent:    #8195ff;
    --accent-in: #0a0c14;
    --good:      #35d07f;
    --good-bg:   #0e2a1c;
    --bad:       #ff6b60;
    --warn:      #ffc043;
    --warn-bg:   #2b2007;

    --median:    #8195ff;

    --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 2px 10px rgba(0, 0, 0, .25);
}

* { box-sizing: border-box; }

/* The hidden attribute is only a browser default, so any display rule on an
   element (a pill is inline-flex) silently overrides it. The "view only" pill
   showed on your own dashboard that way. Make hidden mean hidden. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;                 /* the page itself never scrolls */
}

body {
  background: var(--bg);
  color: var(--ink);
  font: 13px/1.5 -apple-system, "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.num, .right { font-variant-numeric: tabular-nums; }

/* ---------------- app shell ---------------- */

.app {
  height: 100vh;
  /* Flex, not grid rows. The problem strip is hidden most of the time, and a
     hidden child occupies no grid row -- so the panels landed on the auto row
     and sized to their content while the 1fr row sat empty. That only looked
     right while the table happened to be tall enough to fill the window. */
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 12px 12px;
  /* A reading width, centred. Stretched across a wide monitor the table put
     a listing's price, bid and close time a whole screen away from its title,
     and the eye lost the row in between. Narrower screens are unaffected. */
  max-width: 1440px;
  margin: 0 auto;
}

.topbar, .alert-strip { flex: none; }
.grid { flex: 1 1 auto; }

/* ---------------- top bar ---------------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px 20px;
  flex-wrap: wrap;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 10px 16px;
}

.brand { display: flex; align-items: center; gap: 11px; min-width: 0; flex: 1 1 auto; flex-wrap: wrap; }

/* A Poke Ball, drawn rather than dropped in as an image: red top, white
   bottom, a dark equator and a button in the middle, with a soft highlight
   so it reads as a sphere. */
.mark {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  position: relative; overflow: hidden;
  background:
    linear-gradient(to bottom, var(--poke-red) 0 47%, #1b1d22 47% 53%, #fdfdfd 53% 100%);
  box-shadow:
    inset 0 0 0 1.5px #1b1d22,
    inset -3px -4px 7px rgba(0, 0, 0, .25),
    inset 3px 3px 6px rgba(255, 255, 255, .35),
    0 1px 3px rgba(0, 0, 0, .28);
}
.mark::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px;
  border-radius: 50%; background: #fdfdfd;
  box-shadow: inset 0 0 0 1.5px #1b1d22, 0 0 0 1.5px #1b1d22;
}
.mark::after {
  content: ""; position: absolute; left: 4px; top: 3px;
  width: 9px; height: 6px; border-radius: 50%;
  background: rgba(255, 255, 255, .5); filter: blur(1px);
}

.brand-text { min-width: 0; }
h1 { font-size: 14px; font-weight: 640; margin: 0; letter-spacing: -.01em; white-space: nowrap; }
.brand-text .sub { white-space: nowrap; }
h2 { font-size: 12px; font-weight: 620; margin: 0; letter-spacing: .005em; }
.sub { font-size: 11px; color: var(--muted); }

.pill {
  font-size: 10.5px; font-weight: 600; padding: 2.5px 9px; border-radius: 999px;
  border: 1px solid transparent; white-space: nowrap; letter-spacing: .015em;
}
.pill.ok   { color: var(--good); background: var(--good-bg); border-color: color-mix(in srgb, var(--good) 28%, transparent); }
.pill.warn { color: var(--warn); background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 32%, transparent); }
.pill.pill-view { color: var(--muted); background: var(--panel-2); border-color: var(--line); }
.pill.bad  { color: var(--bad);  background: color-mix(in srgb, var(--bad) 12%, transparent); border-color: color-mix(in srgb, var(--bad) 34%, transparent); }

/* ---------------- KPIs ---------------- */

/* The headline numbers get a row of their own under the brand and product
   tabs. Sharing the tabs' row pushed them to the far edge of the screen, where
   they read as detached from the product they describe. */
.kpis {
  display: flex; align-items: stretch; gap: 0; flex-wrap: wrap;
  flex-basis: 100%;
  padding-top: 10px; border-top: 1px solid var(--line-soft);
}

.kpi { padding: 0 18px; border-left: 1px solid var(--line-soft); }
.kpi:first-child { border-left: 0; padding-left: 2px; }
.kpi .lab {
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); font-weight: 600; white-space: nowrap;
}
.kpi .val {
  font-size: 21px; font-weight: 660; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; line-height: 1.24;
}
.kpi .val small { font-size: 12px; font-weight: 550; color: var(--muted); margin-left: 1px; }
.kpi.is-good .val { color: var(--good); }

/* Price trend: a sparkline, not a number, so it sits on the same baseline as
   the values beside it rather than claiming a figure of its own. */
.kpi-trend .trend-row { display: flex; align-items: center; gap: 10px; height: 26px; margin-top: 1px; }
.kpi-trend .spark { position: relative; line-height: 0; }
.kpi-trend .spark svg { display: block; overflow: visible; cursor: crosshair; }
.spark-line {
  fill: none; stroke: var(--muted); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.spark-end   { fill: var(--accent); stroke: var(--panel); stroke-width: 2; }
.spark-hover { fill: var(--ink); stroke: var(--panel); stroke-width: 2; }
.kpi-trend .trend-change {
  font-size: 12px; font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.kpi-trend .trend-flat { color: var(--muted); }
.kpi-trend .trend-head { display: flex; align-items: center; gap: 8px; }

/* The range toggle sits in the label line, so it has to be label-sized. */
.seg.seg-mini { padding: 1px; gap: 1px; border-radius: 6px; }
.seg.seg-mini button {
  font-size: 9.5px; font-weight: 620; letter-spacing: .03em;
  padding: 0 6px; line-height: 15px; border-radius: 5px;
}
.kpi-trend .trend-wait { font-size: 11px; color: var(--muted); line-height: 26px; white-space: nowrap; }
.spark-tip { top: 40px; transform: translateX(-50%); line-height: normal; white-space: nowrap; }

/* ---------------- problem strip ---------------- */

.alert-strip {
  padding: 8px 14px; border-radius: 10px; font-size: 12px; font-weight: 520;
  background: color-mix(in srgb, var(--bad) 10%, var(--panel));
  border: 1px solid color-mix(in srgb, var(--bad) 36%, transparent);
  color: var(--bad);
}
.alert-strip.is-warn {
  background: var(--warn-bg);
  border-color: color-mix(in srgb, var(--warn) 34%, transparent);
  color: var(--warn);
}

/* ---------------- layout grid ---------------- */

.grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  /* An explicit stretching row. Without it the single implicit row is
     content-sized, so a product with only a few listings left the panel
     204px tall in a 900px window. */
  grid-template-rows: minmax(0, 1fr);
  min-height: 0;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--panel);
  flex: none;
}

.panel-body { flex: 1; min-height: 0; }
.scroll { overflow: auto; scrollbar-width: thin; }
.scroll::-webkit-scrollbar { width: 9px; height: 9px; }
.scroll::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 34%, transparent);
  border-radius: 99px; border: 2px solid var(--panel);
}
.scroll::-webkit-scrollbar-track { background: transparent; }

.count { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------------- tooltip ---------------- */

.tooltip {
  position: absolute; pointer-events: none; z-index: 5;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 9px; padding: 7px 10px; font-size: 11.5px;
  box-shadow: 0 6px 20px rgba(16, 24, 40, .16);
  min-width: 132px;
}
.tooltip .t-when { color: var(--muted); font-size: 10px; margin-bottom: 4px; }
.tooltip .t-row { display: flex; justify-content: space-between; gap: 14px; line-height: 1.7; }
.tooltip .t-row b { font-variant-numeric: tabular-nums; font-weight: 620; }

.empty { color: var(--muted); font-size: 12px; padding: 18px; text-align: center; }

/* ---------------- controls ---------------- */

.controls { display: flex; align-items: center; gap: 10px; }

.seg {
  display: inline-flex; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 8px; padding: 2px; gap: 2px;
}
.seg button {
  font: inherit; font-size: 11px; font-weight: 560;
  padding: 3px 10px; border: 0; border-radius: 6px;
  background: transparent; color: var(--ink-2); cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.seg button:hover { color: var(--ink); }
.seg button.on { background: var(--accent); color: var(--accent-in); }

.field { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--muted); }
.field select {
  font: inherit; font-size: 11px; color: var(--ink);
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 7px; padding: 3.5px 7px; max-width: 190px; cursor: pointer;
}

/* ---------------- table ---------------- */

table { width: 100%; border-collapse: separate; border-spacing: 0; }

thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--panel);
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .06em;
  font-weight: 640; color: var(--muted);
  text-align: left; padding: 7px 10px; white-space: nowrap;
  border-bottom: 1px solid var(--line);
  cursor: pointer; user-select: none;
  transition: color .12s ease;
}
thead th:hover { color: var(--ink-2); }
thead th.right { text-align: right; }
thead th.sorted { color: var(--accent); }
thead th.sorted::after { content: " ↓"; font-size: 8px; }
thead th.sorted.asc::after { content: " ↑"; }

tbody td {
  padding: 7px 10px; border-bottom: 1px solid var(--line-soft);
  vertical-align: top;
}
tbody td.right { text-align: right; }
/* short values should never wrap onto a second line */
tbody td:nth-child(3), tbody td:nth-child(6),
tbody td:nth-child(7), tbody td:nth-child(8) { white-space: nowrap; }
tbody tr { transition: background .1s ease; }
tbody tr:hover td { background: var(--panel-2); }

tbody tr.flagged td { opacity: .5; }
tbody tr.bargain td:first-child { box-shadow: inset 2.5px 0 0 var(--good); }
tbody tr.bargain .unit { color: var(--good); }

/* discount vs the scan mean: a number, not a yes/no badge */
.off {
  font-size: 10.5px; font-weight: 600; color: var(--muted);
  font-variant-numeric: tabular-nums; margin-top: 1px;
}
.off.strong { color: var(--good); }

.unit { font-size: 14px; font-weight: 650; letter-spacing: -.015em; }
.sub-2 { font-size: 10.5px; color: var(--muted); margin-top: 1px; }
.nobid { color: var(--warn); }

.tl { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.tl a { color: var(--ink); text-decoration: none; font-weight: 520; }
.tl a:hover { color: var(--accent); text-decoration: underline; }

.badge {
  display: inline-block; font-size: 9.5px; font-weight: 640; letter-spacing: .02em;
  padding: 1px 6px; border-radius: 5px; white-space: nowrap;
  border: 1px solid currentColor;
}
.b-new     { color: var(--accent); }
.b-bargain { color: var(--good); background: var(--good-bg); border-color: transparent; }
.b-multi   { color: var(--warn); }
.b-flag    { color: var(--muted); }

.delta-down { color: var(--good); font-weight: 600; }
.delta-up   { color: var(--bad); }

.ovr { display: flex; gap: 5px; align-items: center; margin-top: 5px; }
.ovr input {
  width: 48px; font: inherit; font-size: 11px; padding: 2px 6px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel-2); color: var(--ink);
}
.ovr button {
  font: inherit; font-size: 10.5px; font-weight: 560; padding: 2.5px 9px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel-2); color: var(--ink-2); cursor: pointer;
  transition: border-color .12s ease, color .12s ease;
}
.ovr button:hover { border-color: var(--accent); color: var(--accent); }

.hist-cell { background: var(--panel-2); padding: 10px 14px 12px; }
.hist-cell .hh { font-size: 10.5px; color: var(--muted); margin-bottom: 4px; }
.hist-cell svg { display: block; width: 100%; height: 92px; }

/* ---------------- responsive fallback ---------------- */

/* Genuinely short: scroll the page rather than crush the listings into a sliver. */
@media (max-height: 620px) {
  html, body { overflow: auto; }
  .app { height: auto; min-height: 100vh; }
  .grid { grid-template-rows: 520px; }
}

/* ---------------- product switcher ---------------- */

.products {
  display: flex; flex-wrap: wrap; gap: 3px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 9px; padding: 3px; margin-left: 4px;
}
.products button {
  font: inherit; font-size: 11.5px; font-weight: 550;
  padding: 4px 11px; border: 0; border-radius: 6px;
  background: transparent; color: var(--ink-2); cursor: pointer; white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.products button:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 6%, transparent); }
.products button.on { background: var(--accent); color: var(--accent-in); }
.products button .n {
  font-size: 10px; font-variant-numeric: tabular-nums; opacity: .65; margin-left: 5px;
}

/* ---------------- Pokémon theming ---------------- */

/* No wash, no gold bar across the header. Theming the chrome fought the
   numbers, which are the point of the page. The identity lives in the mark,
   the accent colour and the type dots instead. */

h1 {
  font-weight: 700;
  letter-spacing: -.015em;
}

.kpi .val { font-weight: 700; }


/* Product tabs carry a type colour, so a product is recognisable by its
   colour before you have read the label. */
.products button { position: relative; }
/* A small type dot, not a colour fill: the product stays recognisable at a
   glance without a muddy darkened swatch behind the label. */
.products button::before {
  content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--type, var(--muted)); margin-right: 6px; vertical-align: 1px;
}
.products button.on {
  background: var(--accent);
  color: var(--accent-in);
  font-weight: 650;
}
.products button.on::before { background: currentColor; opacity: .85; }

/* Poké Ball status: the pill gets a ball that pulses while a scan runs. */
.pill { display: inline-flex; align-items: center; gap: 6px; }
.pill::before {
  content: ""; width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: linear-gradient(to bottom, currentColor 0 46%, transparent 46% 54%, currentColor 54%);
  box-shadow: inset 0 0 0 1px currentColor;
}
.pill.warn::before { animation: catching 1.1s ease-in-out infinite; }
@keyframes catching {
  0%, 100% { transform: rotate(-14deg); }
  50%      { transform: rotate(14deg); }
}

/* Panels get the faintest card edge too, on the header rule. */
.panel-head { border-bottom-color: var(--line); }
.panel { position: relative; }

/* A bargain is a "hit": gold, not just green. */
tbody tr.bargain td:first-child { box-shadow: inset 3px 0 0 var(--good); }
.badge.b-bargain {
  color: #6b4a00; background: var(--poke-gold); border-color: transparent; font-weight: 700;
}
:root[data-theme="dark"] .badge.b-bargain,
:root:not([data-theme="light"]) .badge.b-bargain { color: #3d2a00; }

/* Empty and loading states get a ball rather than bare text. */
.empty::before {
  content: ""; display: block; width: 26px; height: 26px; margin: 0 auto 8px;
  border-radius: 50%;
  background: linear-gradient(to bottom, var(--muted) 0 46%, transparent 46% 54%, var(--muted) 54%);
  box-shadow: inset 0 0 0 1.5px var(--muted);
  opacity: .5;
}

/* The sort menu only exists for phones, where the column headers are hidden. */
.field-sort { display: none; }

/* ---------------- phones ---------------- */

/* Desktop layout is unchanged; everything below applies only on a narrow
   screen. The page scrolls as a whole instead of inside a panel, the product
   tabs become one swipeable row, the headline numbers a two-column grid, and
   each listing a card: title across the top, price per box on the left, and
   the rest labelled beside it. An eight-column table on a phone only scrolled
   sideways and squeezed each title into a column two words wide. */
@media (max-width: 640px) {
  html, body { overflow: auto; }
  .app { height: auto; min-height: 100vh; padding: 8px 8px 16px; gap: 8px; }
  .grid { grid-template-rows: auto; }
  .panel { overflow: visible; }
  .panel-body.scroll { overflow: visible; }

  /* header */
  .topbar { padding: 10px 12px; gap: 8px; }
  .brand { gap: 8px 10px; }
  h1 { font-size: 15px; }
  .products {
    flex-basis: 100%; margin-left: 0;
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity;
  }
  .products::-webkit-scrollbar { display: none; }
  .products button { flex: none; scroll-snap-align: start; padding: 6px 12px; font-size: 12.5px; }

  /* headline numbers: two even columns, trend across the bottom */
  .kpis {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 10px;
    padding-top: 10px;
  }
  .kpi, .kpi:first-child { padding: 0; border-left: 0; }
  .kpi .val { font-size: 19px; white-space: nowrap; }
  .kpi .lab { white-space: normal; line-height: 1.3; }
  .kpi-trend { grid-column: 1 / -1; padding-top: 10px; border-top: 1px solid var(--line-soft); }
  .kpi-trend .trend-head { justify-content: space-between; }
  .kpi-trend .trend-row { justify-content: space-between; }
  .seg.seg-mini button { padding: 2px 9px; line-height: 18px; font-size: 10.5px; }

  /* listings header: title, then the controls on their own full-width row */
  .panel-head { flex-wrap: wrap; padding: 10px 12px; position: static; }
  .controls { flex-basis: 100%; flex-wrap: wrap; gap: 8px; }
  .controls .seg { flex: 1 1 100%; }
  .controls .seg button { flex: 1; padding: 6px 10px; font-size: 12px; }
  .field-sort { display: flex; }
  .controls .field { flex: 1 1 0; min-width: 0; }
  .controls .field select { flex: 1; max-width: none; min-width: 0; padding: 6px 8px; font-size: 12px; }

  /* listings as cards */
  #listings thead { display: none; }
  #listings, #listings tbody { display: block; }
  #listings tbody tr {
    display: grid;
    grid-template-columns: minmax(74px, auto) repeat(3, minmax(0, 1fr));
    grid-template-areas:
      "title title title title"
      "unit  bid   bn    close"
      "unit  type  res   qty";
    column-gap: 12px; row-gap: 6px;
    padding: 12px 12px 12px 14px;
    border-bottom: 1px solid var(--line);
    position: relative;
  }
  #listings tbody td {
    border: 0; padding: 0; background: none !important;
    text-align: left; white-space: normal;
  }
  #listings tbody td.c-unit  { grid-area: unit; text-align: left; }
  #listings tbody td.c-title { grid-area: title; font-size: 14px; }
  #listings tbody td.c-bid   { grid-area: bid; }
  #listings tbody td.c-bn    { grid-area: bn; }
  #listings tbody td.c-close { grid-area: close; }
  #listings tbody td.c-res   { grid-area: res; }
  #listings tbody td.c-type  { grid-area: type; }
  #listings tbody td.c-qty   { grid-area: qty; }
  #listings tbody td[data-label] { font-size: 13px; line-height: 1.35; }
  #listings tbody td[data-label]::before {
    content: attr(data-label); display: block;
    font-size: 9px; font-weight: 640; letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted); margin-bottom: 1px;
  }
  #listings .unit { font-size: 20px; }
  #listings .tl { gap: 4px 6px; }
  #listings .tl a { font-weight: 600; }
  #listings .ovr { flex-wrap: wrap; }
  #listings .ovr input, #listings .ovr button { font-size: 13px; padding: 5px 10px; }
  #listings .ovr input { width: 64px; }

  /* the bargain accent moves from the first cell to the card edge */
  #listings tbody tr.bargain td:first-child { box-shadow: none; }
  #listings tbody tr.bargain { box-shadow: inset 3px 0 0 var(--good); }
  #listings tbody tr:hover { background: none; }

  /* price history and the empty state span the whole card */
  #listings tbody tr.hist-row { display: block; padding: 0; }
  #listings tbody tr.hist-row td { display: block; padding: 10px 12px 12px; background: var(--panel-2) !important; }
  #listings tbody td.empty { grid-column: 1 / -1; text-align: center; }
}
