/* =====================================================================
   CARDBOARD CONNOISSEUR — design system
   =====================================================================
   Merged from the three explored directions:
     · sidebar shell, profit waterfall, queue/detail   ("Workstation")
     · serif display, mono figures, dense tables, rail ("Ledger")
     · card-art tiles, single foil gradient moment     ("Foil")

   IMPORTANT CONTRACT NOTE
   Every class name used by the existing ~130 PHP templates is preserved
   below (.stat-grid, .deals-table, .card-tile, .chip, .add-form, .flash,
   .panel, .bento, .span-N, .num, .positive/.negative …). The new look is
   applied UNDERNEATH those names, so swapping this file plus the two
   chrome partials restyles the whole app without touching page bodies.
   New components (.rail, .wf, .parallel-*, .bulk-*) are additive.
   ===================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600;9..144,700&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap');

:root{
  --bg-main:#14110F;
  --bg-elevated:#1B1713;
  --panel:#1B1713;
  --panel-2:#211C17;
  --bg-zebra:#211C18;
  --bg-hover:#2C251E;
  --bg-input:#100D0B;
  --sunk:#100D0B;

  --text-primary:#F5EFE6;
  --text-secondary:#A99C8C;
  --text-tertiary:#786B5C;
  --ink:#F5EFE6;
  --muted:#A99C8C;
  --faint:#786B5C;

  --border-subtle:#3A322A;
  --rule:#3A322A;
  --rule-2:#4A4033;
  --radius:8px;
  --radius-lg:14px;
  --radius-pill:20px;

  --color-primary:#E0A458;
  --color-success:#6FBF7E;
  --color-alert:#E2664F;
  --color-pending:#E0A458;
  --accent:#E0A458;
  --gain:#6FBF7E;
  --loss:#E2664F;

  --color-primary-tint:color-mix(in srgb, var(--color-primary) 15%, transparent);
  --color-success-tint:color-mix(in srgb, var(--color-success) 15%, transparent);
  --color-alert-tint:color-mix(in srgb, var(--color-alert) 15%, transparent);
  --color-pending-tint:color-mix(in srgb, var(--color-pending) 15%, transparent);
  --accent-tint:var(--color-primary-tint);

  --font-display:'Fraunces',Georgia,serif;
  --font-sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --font-mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  /* The single gradient in the system. Warm metal, not tech-blue —
     it has to read as card foil, and it appears on exactly one
     element per page (the dashboard hero figure). */
  --foil:linear-gradient(100deg,#E0A458 0%,#C97B4A 35%,#B85C6B 62%,#E0A458 100%);
}

[data-theme="light"]{
  --bg-main:#FBF7F1;
  --bg-elevated:#FFFFFF;
  --panel:#FFFFFF;
  --panel-2:#F3ECE1;
  --bg-zebra:#F3ECE1;
  --bg-hover:#F0E6D8;
  --bg-input:#FFFFFF;
  --sunk:#F3ECE1;

  --text-primary:#241D14;
  --text-secondary:#6B5D4B;
  --text-tertiary:#9C8C76;
  --ink:#241D14;
  --muted:#6B5D4B;
  --faint:#9C8C76;

  --border-subtle:#E4D9C7;
  --rule:#E4D9C7;
  --rule-2:#D8C9AF;

  --color-primary:#B5762A;
  --color-success:#3E8B54;
  --color-alert:#C1503B;
  --color-pending:#B5762A;
  --accent:#B5762A;
  --gain:#3E8B54;
  --loss:#C1503B;

  --foil:linear-gradient(100deg,#B5762A 0%,#A5643A 35%,#9A5560 62%,#B5762A 100%);
}

/* ---------------------------------------------------------------------
   BASE
   --------------------------------------------------------------------- */
*{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;}
body{
  margin:0;background:var(--bg-main);color:var(--text-primary);
  font-family:var(--font-sans);font-size:15px;line-height:1.45;
  -webkit-font-smoothing:antialiased;
  transition:background .15s,color .15s;
}
a{color:inherit;text-decoration:none;}
:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px;}

.num{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}
.positive,.up,.margin{color:var(--color-success);font-weight:700;}
.negative,.down{color:var(--color-alert);font-weight:700;}
.thin{color:var(--color-pending);}
.muted-text{color:var(--text-secondary);}

/* ---------------------------------------------------------------------
   SHELL — sidebar rail + main. On narrow screens the rail becomes a
   horizontal scroller rather than a hamburger: with ~20 destinations,
   hiding them behind a button costs a tap on every single navigation.
   --------------------------------------------------------------------- */
.app{display:grid;grid-template-columns:210px 1fr;min-height:100vh;}

.rail{
  background:var(--bg-elevated);border-right:1px solid var(--border-subtle);
  padding:1.1rem .75rem;position:sticky;top:0;height:100vh;overflow-y:auto;
  display:flex;flex-direction:column;
}
.mark{padding:.15rem .5rem 1.1rem;}
.mark b{display:block;font-family:var(--font-display);font-weight:700;font-size:1.02rem;letter-spacing:-.015em;line-height:1.15;}
.mark b em{font-style:normal;color:var(--color-primary);}
.mark small{
  display:block;font-family:var(--font-mono);font-size:.6rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--text-tertiary);margin-top:.35rem;
}
.railgroup{margin-bottom:1rem;}
.railgroup h6{
  font-family:var(--font-mono);font-size:.6rem;font-weight:500;letter-spacing:.13em;
  text-transform:uppercase;color:var(--text-tertiary);margin:0 0 .3rem .55rem;
}
.rail a{
  display:flex;justify-content:space-between;align-items:center;gap:.5rem;
  padding:.36rem .55rem;border-radius:6px;font-size:.84rem;color:var(--text-secondary);
}
.rail a:hover{background:var(--bg-hover);color:var(--text-primary);}
.rail a.active{background:var(--color-primary-tint);color:var(--color-primary);font-weight:600;}
.rail a .badge{font-family:var(--font-mono);font-size:.66rem;color:var(--text-tertiary);}
.rail a.active .badge{color:var(--color-primary);}
.rail-foot{margin-top:auto;padding-top:1rem;border-top:1px solid var(--border-subtle);}

.theme-toggle{
  width:100%;background:var(--bg-input);border:1px solid var(--border-subtle);color:var(--text-secondary);
  font-family:var(--font-mono);font-size:.7rem;letter-spacing:.06em;text-transform:uppercase;
  padding:.4rem;border-radius:6px;cursor:pointer;
}
.theme-toggle:hover{border-color:var(--color-primary);color:var(--color-primary);}

main{padding:1.6rem 2rem 4rem;max-width:1280px;}
main.wide{max-width:1440px;}

/* ---------------------------------------------------------------------
   PAGE HEAD
   --------------------------------------------------------------------- */
.pagehead{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-bottom:1.4rem;}
.pagehead h1{font-family:var(--font-display);font-size:1.9rem;font-weight:600;letter-spacing:-.02em;margin:0;}
.pagehead p,.set-subtitle{margin:.25rem 0 0;color:var(--text-secondary);font-size:.87rem;}
.crumb{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.06em;color:var(--text-tertiary);margin-bottom:.4rem;}
.crumb a{color:var(--color-primary);}
.crumb a:hover{text-decoration:underline;}
.actions{display:flex;gap:.5rem;flex-wrap:wrap;}

.btn,button.btn{
  border:0;border-radius:7px;padding:.5rem 1rem;font-family:var(--font-sans);
  font-size:.84rem;font-weight:600;cursor:pointer;background:var(--color-primary);color:var(--bg-main);
}
.btn:hover{filter:brightness(1.08);}
.btn-ghost{background:var(--bg-elevated);color:var(--text-primary);border:1px solid var(--rule-2);}
.btn-ghost:hover{border-color:var(--color-primary);color:var(--color-primary);}
.btn-danger{
  background:var(--color-alert);color:#fff;border:none;font-weight:600;
  padding:.45rem .9rem;border-radius:6px;cursor:pointer;font-size:.82rem;font-family:var(--font-sans);
}
.btn-danger:hover{filter:brightness(1.08);}
.confirm-label{font-size:.8rem;color:var(--text-secondary);display:flex;align-items:center;gap:.35rem;}
.summary-link{cursor:pointer;font-size:.8rem;color:var(--color-primary);}
.summary-link:hover{text-decoration:underline;}

/* ---------------------------------------------------------------------
   HERO FIGURE — one gradient moment, dashboard only
   --------------------------------------------------------------------- */
.hero{
  background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);
  padding:1.5rem 1.6rem;display:flex;align-items:center;justify-content:space-between;
  gap:2rem;flex-wrap:wrap;margin-bottom:1.5rem;
}
.hero-label{font-family:var(--font-mono);font-size:.65rem;letter-spacing:.14em;text-transform:uppercase;color:var(--text-tertiary);}
.hero-num{
  font-family:var(--font-display);font-weight:700;font-size:3rem;line-height:1;letter-spacing:-.03em;margin-top:.3rem;
  background:var(--foil);background-size:220% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;
  animation:sweep 8s linear infinite;
}
@keyframes sweep{0%{background-position:0% 50%;}100%{background-position:220% 50%;}}
@media(prefers-reduced-motion:reduce){.hero-num{animation:none;}}
.hero-sub{color:var(--text-secondary);font-size:.85rem;margin-top:.4rem;max-width:36ch;}
.hero-stats{display:flex;gap:1.8rem;flex-wrap:wrap;}
.hs-label{font-family:var(--font-mono);font-size:.6rem;letter-spacing:.12em;text-transform:uppercase;color:var(--text-tertiary);}
.hs-val{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:1.3rem;font-weight:500;margin-top:.2rem;}

/* ---------------------------------------------------------------------
   FIGURES STRIP + legacy .stat-grid / .stat-card contract
   --------------------------------------------------------------------- */
.figures{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  background:var(--bg-elevated);border:1px solid var(--border-subtle);
  border-radius:var(--radius);margin-bottom:1.6rem;
}
.fig{padding:.9rem 1.1rem;border-left:1px solid var(--border-subtle);}
.fig:first-child{border-left:0;}
.fig-label,.stat-label{
  font-family:var(--font-mono);font-weight:500;font-size:.63rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-tertiary);
}
.fig-value,.stat-value{
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:1.3rem;
  font-weight:600;margin-top:.25rem;letter-spacing:-.01em;overflow-wrap:break-word;color:var(--text-primary);
}
.fig-note,.stat-note{font-size:.72rem;color:var(--text-secondary);margin-top:.2rem;line-height:1.35;}

.stat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:.75rem;margin-bottom:1.5rem;}
.stat-card{background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:1rem;}

/* Bento panels (legacy dashboard system) */
.bento{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem;margin-bottom:1.5rem;}
.panel{background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:1.1rem 1.2rem;grid-column:span 12;}
.span-3{grid-column:span 3;} .span-4{grid-column:span 4;} .span-5{grid-column:span 5;}
.span-6{grid-column:span 6;} .span-7{grid-column:span 7;} .span-8{grid-column:span 8;} .span-9{grid-column:span 9;}
.panel-body .stat-card{background:transparent;border:none;padding:0;}

.box{background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:1.1rem 1.2rem;}
.box h3{font-family:var(--font-mono);font-size:.62rem;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--text-tertiary);margin:0 0 .8rem;}
.cols2{display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin-bottom:1rem;}

/* ---------------------------------------------------------------------
   FILTER CHIPS
   --------------------------------------------------------------------- */
.filters,.filter-bar{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;margin-bottom:1rem;}
.filters .lab,.filter-label{
  font-family:var(--font-mono);font-size:.63rem;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-tertiary);margin-right:.15rem;
}
.chip,.chip-btn{
  font-size:.78rem;padding:.28rem .7rem;border:1px solid var(--border-subtle);border-radius:var(--radius-pill);
  background:var(--bg-elevated);color:var(--text-secondary);cursor:pointer;font-family:var(--font-sans);
}
.chip.chip-on,.chip.on,.chip.active{background:var(--color-primary-tint);border-color:var(--color-primary);color:var(--color-primary);font-weight:600;}
.chip:hover:not(.chip-on):not(.on){color:var(--text-primary);border-color:var(--rule-2);}

/* ---------------------------------------------------------------------
   TABLES + MARGIN RAIL
   --------------------------------------------------------------------- */
.sheet{background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius);overflow:hidden;}
table,.deals-table{width:100%;border-collapse:collapse;font-size:.9rem;}
thead th,.deals-table th{
  font-family:var(--font-mono);font-size:.63rem;font-weight:500;letter-spacing:.09em;text-transform:uppercase;
  color:var(--text-tertiary);text-align:left;padding:.6rem .9rem;border-bottom:1px solid var(--rule-2);
}
thead th.r,.deals-table th.num{text-align:right;}
tbody td,.deals-table td{padding:.75rem .9rem;border-bottom:1px solid var(--border-subtle);vertical-align:top;overflow-wrap:break-word;word-break:break-word;}
tbody td.r,.deals-table td.num{text-align:right;}
tbody tr:last-child td{border-bottom:0;}
tbody tr:nth-child(even):not(.row-best){background:var(--bg-zebra);}
tbody tr:hover{background:var(--bg-hover);}
.row-best{background:var(--color-success-tint);}
.name{font-weight:600;font-size:.92rem;line-height:1.25;}
.set,.deals-table .set{display:block;color:var(--text-secondary);font-size:.76rem;margin-top:1px;}
.money{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:.9rem;}
.money.big{font-weight:600;}
.pct{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-weight:600;font-size:.94rem;color:var(--color-success);}
.act{font-size:.78rem;color:var(--color-primary);border-bottom:1px solid transparent;white-space:nowrap;}
.act:hover{border-bottom-color:var(--color-primary);}
.stack{display:flex;flex-direction:column;gap:.3rem;align-items:flex-end;}

.rail-bar{position:relative;height:4px;background:var(--border-subtle);margin-top:.5rem;max-width:180px;border-radius:1px;}
.rail-bar i{position:absolute;left:0;top:0;bottom:0;background:var(--color-success);border-radius:1px;display:block;}
.rail-bar b{position:absolute;top:-3px;bottom:-3px;width:1px;background:var(--text-primary);opacity:.5;}
.rail-cap{font-family:var(--font-mono);font-size:.65rem;color:var(--text-tertiary);margin-top:.25rem;}

.sheet-foot{
  display:flex;justify-content:space-between;align-items:center;padding:.7rem .9rem;
  border-top:1px solid var(--rule-2);font-size:.78rem;color:var(--text-secondary);background:var(--sunk);
}

/* ---------------------------------------------------------------------
   PARALLEL / VARIANT UI  — the sports-card fix
   ---------------------------------------------------------------------
   A base card row that expands to show all its printings, ordered by the
   normalized tier. This replaces the flat grid where 40 parallels of the
   same player appeared as 40 unrelated tiles in alphabetical order.
   --------------------------------------------------------------------- */
.parallel-card{
  background:var(--bg-elevated);border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);margin-bottom:.6rem;overflow:hidden;
}
.parallel-head{
  display:flex;align-items:center;gap:.9rem;padding:.75rem .95rem;cursor:pointer;list-style:none;
}
.parallel-head::-webkit-details-marker{display:none;}
.parallel-head:hover{background:var(--bg-hover);}
.parallel-thumb{
  width:38px;height:53px;border-radius:4px;flex-shrink:0;
  background:var(--sunk);border:1px solid var(--border-subtle);
  object-fit:cover;display:block;
}
.parallel-title{flex:1;min-width:0;}
.parallel-title b{display:block;font-weight:600;font-size:.92rem;}
.parallel-title span{display:block;color:var(--text-secondary);font-size:.76rem;margin-top:1px;}
.parallel-count{
  font-family:var(--font-mono);font-size:.7rem;color:var(--text-tertiary);
  border:1px solid var(--border-subtle);border-radius:var(--radius-pill);padding:.15rem .55rem;white-space:nowrap;
}
.parallel-body{border-top:1px solid var(--border-subtle);}

.pv-row{
  display:grid;grid-template-columns:1fr 108px 96px 92px 40px;align-items:center;gap:.6rem;
  padding:.5rem .95rem;border-bottom:1px solid var(--border-subtle);font-size:.84rem;
}
.pv-row:last-child{border-bottom:0;}
.pv-row:hover{background:var(--bg-hover);}
.pv-label{display:flex;align-items:center;gap:.5rem;min-width:0;}
.pv-name{font-weight:500;overflow-wrap:break-word;}
.pv-run{font-family:var(--font-mono);font-variant-numeric:tabular-nums;color:var(--text-secondary);text-align:right;font-size:.8rem;}
.pv-price{font-family:var(--font-mono);font-variant-numeric:tabular-nums;text-align:right;}

/* Scarcity dot — a single 8px mark whose color encodes the band, so you
   can read the tier without reading text. Ordered warm→cool as scarcity
   drops, matching the accent at the top end. */
.pv-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;}
.dot-100{background:#F0D080;box-shadow:0 0 0 2px color-mix(in srgb,#F0D080 30%,transparent);}
.dot-90{background:#E0A458;}
.dot-80{background:#D07C4A;}
.dot-70{background:#B85C6B;}
.dot-60{background:#8A6A9E;}
.dot-40{background:#5F7A96;}
.dot-20{background:#6B6157;}
.dot-0{background:var(--border-subtle);}

.band-tag{
  font-family:var(--font-mono);font-size:.6rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-tertiary);border:1px solid var(--border-subtle);border-radius:4px;padding:.1rem .38rem;white-space:nowrap;
}

/* ---------------------------------------------------------------------
   BULK WATCH BUILDER
   --------------------------------------------------------------------- */
.bulk-grid{display:grid;grid-template-columns:1fr 320px;gap:1.25rem;align-items:start;}
.bulk-sets{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:.5rem;}
.set-check{
  display:flex;align-items:center;gap:.6rem;padding:.6rem .7rem;
  background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius);
  cursor:pointer;font-size:.84rem;
}
.set-check:hover{border-color:var(--rule-2);}
.set-check input{accent-color:var(--color-primary);width:16px;height:16px;flex-shrink:0;margin:0;}
.set-check input:checked ~ .set-check-text b{color:var(--color-primary);}
.set-check:has(input:checked){border-color:var(--color-primary);background:var(--color-primary-tint);}
.set-check-text{min-width:0;}
.set-check-text b{display:block;font-weight:600;overflow-wrap:break-word;}
.set-check-text span{display:block;color:var(--text-secondary);font-size:.72rem;margin-top:1px;}

.bulk-summary{
  position:sticky;top:1.5rem;background:var(--bg-elevated);border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);padding:1.1rem 1.2rem;
}
.bulk-count{font-family:var(--font-display);font-size:2.4rem;font-weight:700;letter-spacing:-.03em;line-height:1;color:var(--color-primary);}
.bulk-count-label{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.12em;text-transform:uppercase;color:var(--text-tertiary);margin-top:.35rem;}

.select-row{display:flex;flex-direction:column;gap:.3rem;margin-bottom:.9rem;}
.select-row label{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-tertiary);}
select,input[type=text],input[type=number],input[type=search],.add-form input,.add-form select{
  background:var(--bg-input);border:1px solid var(--border-subtle);color:var(--text-primary);
  padding:.5rem .65rem;border-radius:6px;font-size:.85rem;font-family:var(--font-sans);width:100%;
}
.add-form{
  display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1.5rem;background:var(--bg-elevated);
  padding:1rem;border-radius:var(--radius-lg);border:1px solid var(--border-subtle);
}
.add-form button{background:var(--color-primary);border:none;color:var(--bg-main);font-weight:700;padding:.5rem 1rem;border-radius:6px;cursor:pointer;}

/* ---------------------------------------------------------------------
   PROFIT WATERFALL
   --------------------------------------------------------------------- */
.wf{display:flex;flex-direction:column;gap:.05rem;}
.wf-row{display:grid;grid-template-columns:118px 1fr 88px;align-items:center;gap:.7rem;padding:.3rem 0;}
.wf-lab{font-size:.8rem;color:var(--text-secondary);}
.wf-track{height:12px;background:var(--sunk);border-radius:2px;position:relative;overflow:hidden;}
.wf-track i{position:absolute;top:0;bottom:0;display:block;border-radius:2px;}
.wf-val{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:.83rem;text-align:right;}
.b-in{background:var(--text-secondary);opacity:.55;}
.b-out{background:var(--color-alert);opacity:.55;}
.b-net{background:var(--color-success);}
.wf-total{border-top:1px solid var(--rule-2);margin-top:.5rem;padding-top:.55rem;}
.wf-total .wf-lab{font-weight:700;color:var(--text-primary);}
.wf-total .wf-val{font-weight:700;color:var(--color-success);font-size:.96rem;}
.wf-note{margin-top:.75rem;font-size:.78rem;color:var(--text-secondary);}

.kv{display:flex;justify-content:space-between;padding:.34rem 0;border-bottom:1px solid var(--border-subtle);font-size:.83rem;}
.kv:last-child{border-bottom:0;}
.kv span:first-child{color:var(--text-secondary);}
.kv span:last-child{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}

/* ---------------------------------------------------------------------
   CARD-ART TILES (legacy .card-grid / .card-tile contract)
   --------------------------------------------------------------------- */
.card-grid,.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:1rem;}
.card-tile{
  background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);
  overflow:hidden;transition:transform .16s ease,border-color .16s ease;
}
.card-tile:hover{transform:translateY(-3px);border-color:var(--rule-2);}
@media(prefers-reduced-motion:reduce){.card-tile:hover{transform:none;}}
.card-tile.is-watched{border-color:var(--color-success);outline:1px solid var(--color-success);outline-offset:-1px;}
.card-tile-img,.art{
  display:block;position:relative;aspect-ratio:5/7;background:var(--bg-main);
  border-bottom:1px solid var(--border-subtle);overflow:hidden;
}
.card-tile-img img{width:100%;height:100%;object-fit:cover;display:block;}
.card-tile-img.no-image{display:flex;align-items:center;justify-content:center;text-align:center;padding:.5rem;color:var(--text-tertiary);font-size:.68rem;line-height:1.3;}
.card-check-wrap{position:absolute;top:6px;left:6px;z-index:3;background:color-mix(in srgb,var(--bg-main) 85%,transparent);border-radius:5px;padding:3px 4px;line-height:0;cursor:pointer;}
.card-check{width:17px;height:17px;accent-color:var(--color-success);cursor:pointer;margin:0;}
.card-body{padding:.7rem .8rem .8rem;}
.crow{display:flex;justify-content:space-between;align-items:baseline;font-size:.78rem;color:var(--text-secondary);margin-bottom:.28rem;}
.crow .num{color:var(--text-primary);}
.csplit{border-top:1px solid var(--border-subtle);margin:.55rem 0 .5rem;}
.cprofit{display:flex;justify-content:space-between;align-items:baseline;}
.cprofit .amt{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-weight:600;font-size:1rem;}
.search-links{display:flex;flex-wrap:wrap;gap:.35rem;margin-bottom:.5rem;}
.search-links a{font-size:.7rem;color:var(--color-primary);background:var(--bg-input);border:1px solid var(--border-subtle);padding:.2rem .45rem;border-radius:5px;}

/* ---------------------------------------------------------------------
   MESSAGES, MISC
   --------------------------------------------------------------------- */
.flash{background:var(--color-success-tint);color:var(--color-success);border:1px solid var(--color-success);padding:.75rem 1rem;border-radius:var(--radius);font-size:.85rem;margin-bottom:1.25rem;}
.warning-note{background:var(--color-pending-tint);color:var(--color-pending);border:1px solid var(--color-pending);padding:.75rem 1rem;border-radius:var(--radius);font-size:.85rem;margin-bottom:1.25rem;}
.error-note{background:var(--color-alert-tint);color:var(--color-alert);border:1px solid var(--color-alert);padding:.75rem 1rem;border-radius:var(--radius);font-size:.85rem;margin-bottom:1.25rem;}
.empty-state{color:var(--text-secondary);text-align:center;padding:3rem 1rem;}
.collapsible{background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:.85rem 1rem;margin-bottom:1rem;}
.collapsible summary{cursor:pointer;font-weight:600;font-size:.9rem;}
.pill{display:inline-block;font-family:var(--font-mono);font-size:.63rem;letter-spacing:.08em;text-transform:uppercase;background:var(--color-primary-tint);color:var(--color-primary);border-radius:4px;padding:.16rem .5rem;margin-top:.55rem;}
.secret-value{font-size:1rem;font-family:var(--font-mono);letter-spacing:.1em;word-break:break-all;}
.uri-block{word-break:break-all;font-size:.75rem;display:inline-block;max-width:100%;}
.spark{display:flex;align-items:flex-end;gap:3px;height:56px;margin-top:.2rem;}
.spark i{flex:1;background:var(--color-primary);opacity:.35;border-radius:1px 1px 0 0;}
.spark i:last-child{opacity:1;}

/* Login — standalone, no shell */
.login-shell{max-width:400px;margin:0 auto;min-height:100vh;display:flex;align-items:center;padding:2rem 1.25rem;}
.login-card{width:100%;background:var(--bg-elevated);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:1.75rem 1.5rem;}
.login-card h1{font-family:var(--font-display);font-size:1.3rem;margin:0 0 1.25rem;font-weight:700;}
.login-form{flex-direction:column;align-items:stretch;background:transparent;border:none;padding:0;margin-bottom:0;}
.login-form input,.login-form button{width:100%;}
.totp-input{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:1.3rem;letter-spacing:.3em;text-align:center;}

/* ---------------------------------------------------------------------
   RESPONSIVE
   --------------------------------------------------------------------- */
@media(max-width:1100px){
  .span-3,.span-4,.span-5,.span-6,.span-7,.span-8,.span-9{grid-column:span 12;}
  .bulk-grid{grid-template-columns:1fr;}
  .bulk-summary{position:static;}
}
@media(max-width:980px){
  /* minmax(0,1fr), not 1fr: a bare 1fr still respects the child's
     min-content width, which for a flex row of nav links is the sum of
     every link's width. That silently widened the WHOLE PAGE to 730px
     inside a 402px viewport — .rail's own overflow-x:auto was scrolling
     correctly, but nothing stopped the grid track itself from growing to
     fit, so the page scrolled instead of just the nav. */
  .app{grid-template-columns:minmax(0,1fr);}
  .rail{
    position:static;height:auto;flex-direction:row;align-items:flex-start;
    overflow-x:auto;padding:.85rem 1rem;border-right:0;border-bottom:1px solid var(--border-subtle);
    min-width:0;
  }
  main{min-width:0;}
  .mark{padding:0 .9rem 0 .2rem;flex-shrink:0;}
  .railgroup{margin:0;display:flex;align-items:center;gap:.15rem;flex-shrink:0;}
  .railgroup h6{margin:0 .3rem 0 0;}
  .rail a{padding:.3rem .55rem;white-space:nowrap;}
  .rail-foot{margin:0 0 0 .5rem;padding:0;border-top:0;flex-shrink:0;}
  .theme-toggle{width:auto;padding:.35rem .6rem;}
  main{padding:1.2rem 1rem 3rem;}
  .cols2{grid-template-columns:1fr;}
  .figures{grid-template-columns:repeat(2,1fr);}
  .fig{border-left:1px solid var(--border-subtle);border-top:1px solid var(--border-subtle);}
  .fig:nth-child(-n+2){border-top:0;}
  .fig:nth-child(odd){border-left:0;}
}
@media(max-width:780px){
  .deals-table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch;}
  .deals-table thead,.deals-table tbody{display:table;width:100%;min-width:480px;}
  .stat-grid{grid-template-columns:repeat(2,1fr);}
  .card-grid,.grid{grid-template-columns:repeat(2,1fr);}
  .add-form{flex-direction:column;align-items:stretch;}
  .pv-row{grid-template-columns:1fr 78px 40px;}
  .pv-run{display:none;}
}
@media(max-width:600px){
  .pagehead h1{font-size:1.45rem;}
  .hero-num{font-size:2.1rem;}
  .rail-bar{max-width:110px;}
  .card-check{width:22px;height:22px;}
}

/* =====================================================================
   v2.1 — TRUST SIGNALS
   =====================================================================
   Every rule below exists so a number you shouldn't act on cannot be
   mistaken for one you should. All three signals carry TEXT as well as
   colour: colour alone fails for anyone with a colour vision deficiency,
   and these are the exact signals that must not be missed.
   ===================================================================== */

/* ---- price freshness decay ---- */
.stale-warn{
  color:var(--text-tertiary);
  text-decoration:underline dotted var(--color-pending);
  text-underline-offset:3px;
}
.stale-dead{
  color:var(--text-tertiary);
  opacity:.55;
  text-decoration:line-through;
  text-decoration-color:var(--color-alert);
}
.stale-age{
  font-family:var(--font-mono);font-size:.62rem;
  color:var(--color-pending);margin-left:.3rem;
  vertical-align:super;letter-spacing:.02em;
}

/* ---- comp confidence ---- */
.conf{
  display:inline-block;font-family:var(--font-mono);font-size:.6rem;
  letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;
  padding:.13rem .4rem;border-radius:4px;border:1px solid;
}
.conf-high{
  color:var(--color-success);border-color:var(--color-success);
  background:var(--color-success-tint);
}
.conf-medium{
  color:var(--color-pending);border-color:var(--color-pending);
  background:var(--color-pending-tint);
}
/* Low deliberately reads as a warning, not a neutral label — a thin comp
   set is the single most common way to talk yourself into a bad buy. */
.conf-low{
  color:var(--color-alert);border-color:var(--color-alert);
  background:var(--color-alert-tint);
}
.conf-none{
  color:var(--text-tertiary);border-color:var(--border-subtle);
  background:transparent;
}

/* ---- velocity ---- */
.vel{
  display:inline-block;font-family:var(--font-mono);font-size:.6rem;
  letter-spacing:.05em;white-space:nowrap;
  padding:.13rem .42rem;border-radius:var(--radius-pill);
  border:1px solid var(--border-subtle);color:var(--text-secondary);
}
.vel-very-fast{color:#7FD8A0;border-color:#3E7A55;background:rgba(111,191,126,.12);}
.vel-fast{color:#A8D48C;border-color:#4A6B3A;background:rgba(140,190,110,.10);}
.vel-moderate{color:var(--color-pending);border-color:#6B5424;background:var(--color-pending-tint);}
.vel-slow{color:#D89A72;border-color:#6E4A32;background:rgba(200,130,80,.10);}
.vel-illiquid{color:var(--color-alert);border-color:#6E3428;background:var(--color-alert-tint);}
.vel-unknown{color:var(--text-tertiary);}

[data-theme="light"] .vel-very-fast{color:#2C6B41;border-color:#8CC3A0;background:rgba(62,139,84,.12);}
[data-theme="light"] .vel-fast{color:#4A6B2E;border-color:#A8C48C;background:rgba(90,130,60,.10);}
[data-theme="light"] .vel-slow{color:#8A5228;border-color:#D0A882;background:rgba(160,100,50,.10);}

/* ---- annualized return ---- */
.annual{
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  font-weight:600;font-size:.94rem;
}
.annual-hot{color:var(--color-success);}
.annual-good{color:var(--color-success);opacity:.85;}
.annual-ok{color:var(--text-primary);}
.annual-poor{color:var(--text-tertiary);}
.annual-unknown{color:var(--text-tertiary);font-weight:400;}

/* ---- keyboard triage ---- */
.kbd-hint{
  display:flex;align-items:center;gap:.3rem;flex-wrap:wrap;
  font-size:.72rem;color:var(--text-tertiary);
  margin:-.4rem 0 .9rem;
}
.kbd-hint kbd{
  font-family:var(--font-mono);font-size:.65rem;
  background:var(--bg-input);border:1px solid var(--border-subtle);
  border-bottom-width:2px;border-radius:4px;
  padding:.05rem .3rem;color:var(--text-secondary);
}
/* Touch devices have no keyboard — advertising shortcuts there is noise. */
@media (hover: none){ .kbd-hint{ display:none; } }

/* The focused row in keyboard triage. Uses an inset ring rather than a
   background change so it stays visible on top of zebra striping and the
   .row-best highlight, which a background swap would have fought with. */
tbody tr.triage-focus{
  box-shadow:inset 3px 0 0 var(--color-primary), inset 0 0 0 1px var(--border-subtle);
  background:var(--bg-hover) !important;
}
tr.triage-done{opacity:.4;}
tr.triage-done td{text-decoration:line-through;text-decoration-color:var(--text-tertiary);}

.triage-toast{
  position:fixed;left:50%;bottom:1.5rem;transform:translateX(-50%);
  background:var(--bg-elevated);border:1px solid var(--color-primary);
  color:var(--text-primary);padding:.5rem 1rem;border-radius:var(--radius);
  font-size:.84rem;z-index:50;box-shadow:0 6px 24px rgba(0,0,0,.35);
  opacity:0;transition:opacity .18s ease;pointer-events:none;
}
.triage-toast.show{opacity:1;}
@media(prefers-reduced-motion:reduce){.triage-toast{transition:none;}}

.kbd-modal{
  position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:60;
  display:flex;align-items:center;justify-content:center;padding:1.5rem;
}
.kbd-modal[hidden]{display:none;}
.kbd-modal-inner{
  background:var(--bg-elevated);border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);padding:1.4rem 1.5rem;max-width:420px;width:100%;
}
.kbd-modal-inner h3{font-family:var(--font-display);font-size:1.05rem;margin:0 0 1rem;color:var(--text-primary);text-transform:none;letter-spacing:0;}
.kbd-row{display:flex;justify-content:space-between;padding:.32rem 0;border-bottom:1px solid var(--border-subtle);font-size:.85rem;}
.kbd-row:last-child{border-bottom:0;}

/* ---- quick add camera ---- */
.capture-zone{
  border:2px dashed var(--rule-2);border-radius:var(--radius-lg);
  padding:1.5rem 1rem;text-align:center;background:var(--bg-elevated);
  margin-bottom:1rem;
}
.capture-zone.has-image{border-style:solid;border-color:var(--color-primary);padding:.6rem;}
.capture-preview{max-width:100%;max-height:260px;border-radius:var(--radius);display:block;margin:0 auto;}
.capture-btn{
  display:inline-flex;align-items:center;gap:.5rem;
  background:var(--color-primary);color:var(--bg-main);border:0;
  padding:.75rem 1.4rem;border-radius:8px;font-weight:600;font-size:.95rem;
  cursor:pointer;font-family:var(--font-sans);
  /* 48px minimum: this is tapped one-handed at a card show, often in a hurry. */
  min-height:48px;
}
.capture-hint{color:var(--text-secondary);font-size:.8rem;margin-top:.6rem;}

/* ---- settings page ---- */
.setting-row{
  display:grid;grid-template-columns:1fr 160px;gap:1rem;align-items:center;
  padding:.7rem 0;border-bottom:1px solid var(--border-subtle);
}
.setting-row:last-child{border-bottom:0;}
.setting-row label b{display:block;font-size:.88rem;font-weight:600;}
.setting-row label span{display:block;color:var(--text-secondary);font-size:.76rem;margin-top:.15rem;}
@media(max-width:620px){ .setting-row{grid-template-columns:1fr;gap:.4rem;} }

/* ---------------------------------------------------------------------
   CARD TILE OVERLAY TAG + EMPTY-IMAGE PLACEHOLDER
   ---------------------------------------------------------------------
   The .tag rule existed only in the early mockups and never made it into
   the production sheet, so status tags rendered as inline text and ran
   straight into the card name ("Sell signalUmbreon ex").
   --------------------------------------------------------------------- */
.card-tile-img .tag,
.art .tag{
  position:absolute;top:.55rem;left:.55rem;z-index:2;
  font-family:var(--font-mono);font-size:.58rem;letter-spacing:.08em;
  text-transform:uppercase;white-space:nowrap;
  background:color-mix(in srgb, var(--bg-main) 82%, transparent);
  backdrop-filter:blur(4px);
  border:1px solid var(--border-subtle);
  color:var(--text-secondary);
  padding:.16rem .45rem;border-radius:4px;line-height:1.4;
}
.card-tile-img .tag.sell{
  background:var(--color-success-tint);border-color:var(--color-success);color:var(--color-success);
}
.card-tile-img .tag.hold{
  background:var(--color-pending-tint);border-color:var(--color-pending);color:var(--color-pending);
}

/* A card with no artwork is normal — vault entries are often typed in by
   hand, and sports catalogs rarely ship images. It should read as a
   deliberate placeholder rather than a broken image, so the name is set
   properly and a faint card-shaped frame holds the space. */
.card-tile-img.no-image{
  display:flex;align-items:center;justify-content:center;text-align:center;
  padding:1.4rem .75rem;line-height:1.35;
  background:
    linear-gradient(180deg, var(--bg-elevated) 0%, var(--bg-main) 100%);
}
.card-tile-img.no-image::before{
  content:"";position:absolute;inset:14% 18%;
  border:1px solid var(--border-subtle);border-radius:6px;opacity:.5;
}
.card-tile-img.no-image .placeholder-name{
  position:relative;z-index:1;
  font-family:var(--font-display);font-weight:600;
  font-size:.82rem;color:var(--text-secondary);
  overflow-wrap:break-word;max-width:100%;
}

/* ---------------------------------------------------------------------
   MOBILE NUMERIC INTEGRITY + TABLE SCROLL
   ---------------------------------------------------------------------
   Two bugs found by screenshotting the real pages at 402px:

   1. `word-break:break-word` on table cells (added to stop long card
      names overflowing) also applied to prices, so $412.00 wrapped as
      "$4 / 12.00". A number broken across two lines is not a smaller
      number, it is a WRONG number — and on a page where every figure is
      a buying decision that is the worst possible failure.

   2. ui_table() emits a plain <table>; the horizontal-scroll rule only
      ever targeted the legacy .deals-table class, so v2 tables ran off
      the side of the screen with no way to reach the right-hand columns.
   --------------------------------------------------------------------- */
.money, .num, .pct, .annual, .fig-value, .stat-value, .hs-val,
.wf-val, .pv-run, .pv-price, .compare td.r, .kv span:last-child{
  white-space:nowrap;
  word-break:normal;
  overflow-wrap:normal;
}

@media(max-width:900px){
  /* Let the table scroll inside its panel rather than pushing the page
     wide. The panel keeps its rounded border; only the rows move. */
  .sheet{overflow-x:auto;-webkit-overflow-scrolling:touch;}
  .sheet > table{min-width:660px;}

  /* One stat per row below this width. Two columns forced the value and
     its label to collide at 402px. */
  .figures{grid-template-columns:1fr;}
  .fig{border-left:0;border-top:1px solid var(--border-subtle);}
  .fig:first-child{border-top:0;}

  /* Filter rows scroll sideways instead of stacking into a tall wall of
     chips that pushes the actual data off-screen. */
  .filters{
    flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;
    padding-bottom:.3rem;
  }
  .filters .chip{flex:0 0 auto;}
  .filters .lab{flex:0 0 auto;}
}

@media(max-width:620px){
  .pagehead{gap:.6rem;}
  .pagehead .actions{width:100%;}
  .pagehead .actions .btn{flex:1;text-align:center;}
  /* 44px minimum touch target — these get tapped one-handed at a show. */
  .btn, .btn-ghost{min-height:44px;display:inline-flex;align-items:center;justify-content:center;}
  .card-grid,.grid{grid-template-columns:repeat(2,1fr);gap:.6rem;}
  .parallel-head{padding:.65rem .7rem;}
  .pv-row{grid-template-columns:1fr 62px 34px;gap:.45rem;padding:.5rem .7rem;}
  .pv-row .pv-run:first-of-type{display:none;}  /* band name; the /50 stays */
}
