/* Lootquidity curated theme system. Every color in this file references a
   token; gold/ember are brand + interaction, --pos/--neg strictly semantic.
   :root holds the "obsidian" theme (true-black OLED, brand golds shared
   with the kraken mark, assets/logo-kraken.png) and is the default —
   <html> without data-theme renders obsidian. Each [data-theme] block below is a COMPLETE token set; no
   theme inherits obsidian implicitly. The only unthemed colors are the
   camera overlays (letterbox, guide dim, video text-shadows), which sit
   over live video, not chrome. */

/* MTG-027a P3.1: the hidden ATTRIBUTE must always win. Any class that sets
   display (flex/grid) silently defeats the UA's [hidden] rule — that is
   exactly how the scan basket overlay shipped rendering open over the
   camera. The three per-selector patches below (.view/.scrim/
   .message-center[hidden]) were earlier fights with the same bug; this
   rule supersedes them all and protects every future element. */
[hidden] { display: none !important; }
:root {
  color-scheme: dark;
  --bg-page: #000000;      /* page canvas */
  --bg-card: #0b0a09;      /* tiles, cards, table surface */
  --bg-raised: #121110;    /* sidebar, menus, hover fills */
  --border: #262019;       /* default hairline (darker: no glow on black) */
  --border-gold: #443927;  /* inner "tooled" line on cards */
  --text-hi: #ece6dc;      /* primary text */
  --text-mid: #a89c8e;     /* secondary */
  --text-low: #6e6459;     /* muted/hints */
  /* Dark ink on the red badge: cream-on-red (forge's legacy pairing) sits
     near 3.2:1; the newer themes take the AA-passing pairing instead. */
  --text-inverse: #16110e;
  --gold: #c9a961;         /* wordmark, headings, active nav */
  --gold-bright: #e8c67a;  /* polished band in metal display type */
  --gold-deep: #8a6d3b;    /* rings, dividers, quiet accents */
  --ember: #e8833a;        /* hovers, active-edge, links */
  --pos: #4caf78;          /* gains, in stock */
  --neg: #d05a4a;          /* losses, failing */
  --scrim: rgba(0, 0, 0, 0.7);        /* mobile-nav backdrop */
  --scrim-modal: rgba(0, 0, 0, 0.75); /* modal backdrop */
  --shadow: rgba(0, 0, 0, 0.5);       /* popovers, menus, tooltip */
  --shadow-deep: rgba(0, 0, 0, 0.6);  /* modals, overlay sidebar */
  --shadow-soft: rgba(0, 0, 0, 0.35); /* tile hover lift */
  /* Metal display-type gradient stops at 0/30/50/70/100%: deep edges,
     polished band through the middle. */
  /* TEXTURE-1 foil ladder: pale gold at the lit top edge down to deep
     amber — engraved foil under a high candle, not a glow. */
  --metal-1: #f2e2b6;
  --metal-2: #ddbe7d;
  --metal-3: #c9a961;
  --metal-4: #a3803f;
  --metal-5: #7a5a26;
  --chart-line: #c9a961;    /* value line (gold) */
  --chart-fill: #c9a9611a;  /* area under the line (~10% alpha) */
  --chart-grid: #201b17;    /* y-axis gridlines */
  --sb-w: 240px;           /* sidebar width (rail: 56px) */
  /* TEXTURE-1 surface ladder: page < panel < raised < modal, plus the
     recessed chart well. Shadows are soft and tight — dark-theme
     elevation whispers, it never floats. Themes without overrides
     inherit these :root shadow values (parchment overrides warm). */
  --surf-3: #181614;
  --surf-inset: #060505;
  --elev-1: 0 1px 2px rgba(0, 0, 0, 0.35), 0 2px 10px rgba(0, 0, 0, 0.22);
  --elev-2: 0 2px 4px rgba(0, 0, 0, 0.4), 0 6px 18px rgba(0, 0, 0, 0.28);
  --elev-3: 0 16px 48px var(--shadow-deep);
  --inset-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.4), inset 0 0 0 1px var(--border);
  /* Base-page material (TEXTURE-1.3): fine stone grain, coarsened and
     raised until it reads (1.3: bF 0.9->0.5, contrast 0.55->0.9,
     alpha 0.05->0.12, stitched tiles). */
  --texture: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.5' numOctaves='2' seed='4' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.8  0 0 0 0 0.78  0 0 0 0 0.74  0 0 0 0.9 0'/></filter><rect width='140' height='140' filter='url(%23t)'/></svg>");
  --texture-opacity: 0.15; /* 1.4: one notch up per the desk verdict */
}
html.sb-collapsed { --sb-w: 56px; }

/* The original forge-dark look: warm coals a shade above black. */
:root[data-theme="forge"] {
  color-scheme: dark;
  --bg-page: #0d0c0b;
  --bg-card: #151312;
  --bg-raised: #1d1a17;
  --border: #2b2622;
  --border-gold: #4a3d2a;
  --text-hi: #ece6dc;
  --text-mid: #a89c8e;
  --text-low: #6e6459;
  --text-inverse: #ece6dc; /* legacy cream-on-red badge, kept exactly */
  --gold: #c9a961;
  --gold-bright: #e8c67a;
  --gold-deep: #8a6d3b;
  --ember: #e8833a;
  --pos: #4caf78;
  --neg: #d05a4a;
  --scrim: rgba(0, 0, 0, 0.55);
  --scrim-modal: rgba(0, 0, 0, 0.6);
  --shadow: rgba(0, 0, 0, 0.5);
  --shadow-deep: rgba(0, 0, 0, 0.6);
  --shadow-soft: rgba(0, 0, 0, 0.35);
  /* TEXTURE-1 foil ladder: pale gold at the lit top edge down to deep
     amber — engraved foil under a high candle, not a glow. */
  --metal-1: #f2e2b6;
  --metal-2: #ddbe7d;
  --metal-3: #c9a961;
  --metal-4: #a3803f;
  --metal-5: #7a5a26;
  --chart-line: #c9a961;
  --chart-fill: #c9a9611a;
  --chart-grid: #2b2622;
  --surf-3: #262019;
  --surf-inset: #100e0d;
  /* TEXTURE-1 material: hammered iron mottle (1.4 de-grid: two layers
     at 2760x1560 + 2704x1512 (1.5: both beyond 2560x1440, no seams), amplitudes split
     0.62/0.42 to hold 1.3's perceived strength). */
  --texture:
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='2760' height='1560'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.045' numOctaves='3' seed='9' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.75  0 0 0 0 0.64  0 0 0 0 0.52  0 0 0 0.8 0'/></filter><rect width='2760' height='1560' filter='url(%23t)'/></svg>"),
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='2704' height='1512'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.09' numOctaves='2' seed='17' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.7  0 0 0 0 0.6  0 0 0 0 0.5  0 0 0 0.55 0'/></filter><rect width='2704' height='1512' filter='url(%23t)'/></svg>");
  --texture-opacity: 0.1;
}

/* Light theme: warm paper, dark ink. Gold/ember/pos/neg all darkened for
   AA contrast against light surfaces (verified programmatically). The
   metal type flips to an engraved cut — dark heart, lit bevel edges —
   instead of the dark themes' glowing polish band. */
:root[data-theme="parchment"] {
  color-scheme: light;
  --bg-page: #ece2cd;
  --bg-card: #f6efdf;
  --bg-raised: #faf4e7;
  --border: #d4c5a5;
  --border-gold: #b39b6b;
  --text-hi: #2e2718;
  --text-mid: #5d5240;
  --text-low: #635642;
  --text-inverse: #faf5ea;
  --gold: #6b501f;
  --gold-bright: #9c7c40;
  --gold-deep: #8a6d3b;
  --ember: #97490f;
  --pos: #27603c;
  --neg: #9c2f21;
  --scrim: rgba(45, 35, 20, 0.45);
  --scrim-modal: rgba(45, 35, 20, 0.5);
  --shadow: rgba(90, 70, 40, 0.25);
  --shadow-deep: rgba(90, 70, 40, 0.35);
  --shadow-soft: rgba(90, 70, 40, 0.18);
  --metal-1: #8d7440;
  --metal-2: #6b5426;
  --metal-3: #4f3d18;
  --metal-4: #6b5426;
  --metal-5: #8d7440;
  --chart-line: #6b5426;
  --chart-fill: #6b542620;
  --chart-grid: #d9cbab;
  --surf-3: #fdf8ee;
  --surf-inset: #efe6d2;
  --elev-1: 0 1px 2px rgba(90, 70, 40, 0.14), 0 2px 10px rgba(90, 70, 40, 0.1);
  --elev-2: 0 2px 4px rgba(90, 70, 40, 0.16), 0 6px 18px rgba(90, 70, 40, 0.12);
  --elev-3: 0 16px 48px var(--shadow-deep);
  --inset-shadow: inset 0 2px 8px rgba(90, 70, 40, 0.16), inset 0 0 0 1px var(--border);
  /* TEXTURE-1 material: laid paper fiber (1.4: a LIGHT page needs far
     larger absolute deltas than dark ones — Weber contrast — so
     parchment alone runs alpha 0.28 (documented exception to the 0.16
     ceiling). Two layers: laid fiber 1240x880 + soft mottle 871x618. */
  --texture:
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='1240' height='880'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.012 0.075' numOctaves='2' seed='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.36  0 0 0 0 0.29  0 0 0 0 0.17  0 0 0 0.95 0'/></filter><rect width='1240' height='880' filter='url(%23t)'/></svg>"),
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='871' height='618'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.035' numOctaves='2' seed='7' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.4  0 0 0 0 0.33  0 0 0 0 0.2  0 0 0 0.65 0'/></filter><rect width='871' height='618' filter='url(%23t)'/></svg>");
  --texture-opacity: 0.28;
}

/* Steel theme: desaturated cool grays, ember shifts to steel blue, the
   wordmark runs pale silver-gold. Chart line follows the blue accent. */
:root[data-theme="cold-iron"] {
  color-scheme: dark;
  --bg-page: #0e1013;
  --bg-card: #16191d;
  --bg-raised: #1d2126;
  --border: #2c323a;
  --border-gold: #414c57;
  --text-hi: #e3e7eb;
  --text-mid: #9aa4ad;
  --text-low: #667079;
  --text-inverse: #14171a; /* dark ink on the badge fill (AA vs --neg) */
  --gold: #c6c0aa;
  --gold-bright: #e6dfc6;
  --gold-deep: #85806a;
  --ember: #6a9bc0;
  --pos: #4aa87a;
  --neg: #d46a5d;
  --scrim: rgba(0, 0, 0, 0.55);
  --scrim-modal: rgba(0, 0, 0, 0.6);
  --shadow: rgba(0, 0, 0, 0.5);
  --shadow-deep: rgba(0, 0, 0, 0.6);
  --shadow-soft: rgba(0, 0, 0, 0.35);
  /* TEXTURE-1: cold iron takes the same foil ladder in worn silver. */
  --metal-1: #f2eede;
  --metal-2: #d8d2bc;
  --metal-3: #c6c0aa;
  --metal-4: #9d977f;
  --metal-5: #75705c;
  --chart-line: #7fa8c9;
  --chart-fill: #7fa8c91a;
  --chart-grid: #262c33;
  --surf-3: #262b31;
  --surf-inset: #0b0d10;
  /* TEXTURE-1 material: brushed steel streaks (1.3: contrast 0.5->0.75,
     alpha 0.05->0.10, stitched). */
  --texture: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='320' height='120'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.002 0.35' numOctaves='2' seed='6' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.74  0 0 0 0 0.8  0 0 0 0 0.88  0 0 0 0.75 0'/></filter><rect width='320' height='120' filter='url(%23t)'/></svg>");
  --texture-opacity: 0.1;
}

/* Red-forward theme: forge-warm surfaces pulled toward umber, accents lean
   ember red, wordmark stays gold. --neg is deliberately shifted to crimson
   (pink-leaning) so losses stay hue-distinct from the orange-red brand
   accent; where they'd still be close, the surrounding context (sign,
   arrow, pill label) carries the meaning. */
:root[data-theme="ember"] {
  color-scheme: dark;
  --bg-page: #120c0a;
  --bg-card: #1a1210;
  --bg-raised: #231813;
  --border: #362519;
  --border-gold: #543528;
  --text-hi: #f0e6de;
  --text-mid: #b39c8f;
  --text-low: #7d6a5e;
  --text-inverse: #1c1210; /* dark ink on the badge fill (AA vs --neg) */
  --gold: #c9a961;
  --gold-bright: #e8c67a;
  --gold-deep: #8a6d3b;
  --ember: #da6048;
  --pos: #4caf78;
  --neg: #e0506c;
  --scrim: rgba(0, 0, 0, 0.55);
  --scrim-modal: rgba(0, 0, 0, 0.6);
  --shadow: rgba(0, 0, 0, 0.5);
  --shadow-deep: rgba(0, 0, 0, 0.6);
  --shadow-soft: rgba(0, 0, 0, 0.35);
  /* TEXTURE-1 foil ladder: pale gold at the lit top edge down to deep
     amber — engraved foil under a high candle, not a glow. */
  --metal-1: #f2e2b6;
  --metal-2: #ddbe7d;
  --metal-3: #c9a961;
  --metal-4: #a3803f;
  --metal-5: #7a5a26;
  --chart-line: #da6048;
  --chart-fill: #da60481a;
  --chart-grid: #362519;
  --surf-3: #2d211a;
  --surf-inset: #0d0908;
  /* TEXTURE-1 material: charred slate grain (1.4 de-grid: 1150x820 +
     811x577 layers, amplitudes 0.62/0.42 to hold 1.3's strength). */
  --texture:
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='1150' height='820'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.14' numOctaves='2' seed='12' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.85  0 0 0 0 0.55  0 0 0 0 0.4  0 0 0 0.85 0'/></filter><rect width='1150' height='820' filter='url(%23t)'/></svg>"),
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='811' height='577'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.065' numOctaves='2' seed='5' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.8  0 0 0 0 0.5  0 0 0 0 0.38  0 0 0 0.58 0'/></filter><rect width='811' height='577' filter='url(%23t)'/></svg>");
  --texture-opacity: 0.11;
}

/* Abyss: deep-sea luxury. Violet-tinged near-blacks, the black+gold
   identity untouched (gold family, metal type and chart line are
   obsidian's), and the ember/accent role shifted to a DESATURATED
   abyssal violet — an accent dose (hovers, active edges, links), never
   a flood. --neg leans rose so losses stay hue-distinct from the
   violet accent. All text/background pairs verified AA. */
:root[data-theme="abyss"] {
  color-scheme: dark;
  --bg-page: #050408;
  --bg-card: #0d0b13;
  --bg-raised: #141120;
  --border: #272138;
  --border-gold: #443927;
  --text-hi: #eae5f0;
  --text-mid: #a79dbb;
  --text-low: #857c9b;
  --text-inverse: #14101c; /* dark ink on the badge fill (AA vs --neg) */
  --gold: #c9a961;
  --gold-bright: #e8c67a;
  --gold-deep: #8a6d3b;
  --ember: #8d7bb0;
  --pos: #4caf78;
  --neg: #d0566a;
  --scrim: rgba(8, 5, 16, 0.6);
  --scrim-modal: rgba(8, 5, 16, 0.7);
  --shadow: rgba(3, 2, 8, 0.55);
  --shadow-deep: rgba(3, 2, 8, 0.65);
  --shadow-soft: rgba(3, 2, 8, 0.4);
  /* TEXTURE-1 foil ladder: pale gold at the lit top edge down to deep
     amber — engraved foil under a high candle, not a glow. */
  --metal-1: #f2e2b6;
  --metal-2: #ddbe7d;
  --metal-3: #c9a961;
  --metal-4: #a3803f;
  --metal-5: #7a5a26;
  --chart-line: #c9a961;
  --chart-fill: #c9a9611a;
  --chart-grid: #1d1929;
  --surf-3: #1b1631;
  --surf-inset: #080611;
  /* TEXTURE-1.4 rework — deep-water caustics in two scales: broad slow
     light-clouds (2720x1540) — 1.5: every layer exceeds 2560x1440, no tile edge on screen over fine ripple
     detail (2740x1520). Non-integer tile ratio: the layers' periods never
     realign, so no grid survives even at 2560. Static, stitched. */
  --texture:
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='2720' height='1540'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.0028 0.0035' numOctaves='3' seed='23' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.66  0 0 0 0 0.6  0 0 0 0 0.9  0 0 0 0.72 0'/></filter><rect width='2720' height='1540' filter='url(%23t)'/></svg>"),
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='2740' height='1520'><filter id='t'><feTurbulence type='fractalNoise' baseFrequency='0.022' numOctaves='2' seed='31' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.55  0 0 0 0 0.52  0 0 0 0 0.85  0 0 0 0.45 0'/></filter><rect width='2740' height='1520' filter='url(%23t)'/></svg>");
  --texture-opacity: 0.13;
}

@font-face {
  font-family: "Cinzel";
  src: url("/fonts/cinzel-var.woff2") format("woff2");
  font-weight: 400 900;
  font-display: swap;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg-page);
  color: var(--text-hi);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 14px;
  line-height: 1.4;
}

/* Sidebar */
.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--sb-w);
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border-right: 1px solid var(--border);
  transition: width 0.15s ease;
  overflow: hidden;
  z-index: 30;
}
/* MTG-029.1: stacked crest lockup — crest above wordmark, centered;
   spacing stays on the sidebar's existing 10/12/14/18 scale. */
.sb-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 18px 14px 14px;
}
/* Kraken medallion: feathered disc asset inside a theme-drawn hairline
   ring (--gold-deep is the ring token); the inner padding keeps the
   feathered rim off the ring. Hover brightens the ring to --gold on the
   house 150ms standard. */
.sb-crest {
  width: 64px;
  height: 64px;
  padding: 4px;
  flex: none;
  border: 1px solid var(--gold-deep);
  border-radius: 50%;
  transition: border-color 150ms ease;
}
a.sb-brand:hover .sb-crest { border-color: var(--gold); }
.wordmark {
  font-family: "Cinzel", Georgia, serif;
  font-size: 23px;
  font-weight: 650;
  letter-spacing: 0.03em;
  line-height: 1.1;
  white-space: nowrap;
}
/* MTG-060: beta hallmark — engraved small print tucked under the
   wordmark. No pill, no border, no background, no hover response: an
   engraving, not a sticker. Muted gold keeps it in the metal family
   without competing with the foil above. The negative margin pulls it
   inside the lockup's 10px gap; the left margin rebalances the
   letter-spacing's trailing space so the mark centers optically. */
.sb-beta {
  font-family: "Cinzel", Georgia, serif;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.42em;
  margin: -7px 0 0 0.42em;
  color: color-mix(in srgb, var(--gold) 52%, transparent);
}

/* "Gold bar" metal display type: deep gold edges, polished band through the
   middle. Solid --gold fallback where background-clip: text is unsupported.
   Display elements only — never nav labels or data text. */
.metal { color: var(--gold); }
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  /* TEXTURE-1: section headers wear the QUIET single-step foil… */
  .metal {
    background-image: linear-gradient(
      180deg,
      var(--metal-2) 0%,
      var(--metal-3) 48%,
      var(--metal-5) 100%
    );
    background-size: 100% 200%;
    background-position: 50% 35%;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
  }
  /* …view titles, the wordmark and the position title get the full
     engraved foil: pale lit top edge to deep amber, one hairline light
     above and one soft dark shadow below (drop-shadow follows the
     clipped glyphs — text-shadow would paint over them). No bevels, no
     outer glow, no animation. */
  .view-title,
  .wordmark,
  .cd-title,
  .scan-handoff h2 {
    background-image: linear-gradient(
      180deg,
      var(--metal-1) 0%,
      var(--metal-2) 28%,
      var(--metal-3) 52%,
      var(--metal-4) 76%,
      var(--metal-5) 100%
    );
    filter: drop-shadow(0 -1px 0 rgba(255, 240, 205, 0.13))
            drop-shadow(0 1px 1px rgba(0, 0, 0, 0.45));
  }
  .sb-brand .wordmark { transition: background-position 0.45s ease; }
  .sb-brand:hover .wordmark { background-position: 50% 65%; }
  /* (TEXTURE-1.6: the 1.1 title shimmer moved to the total-value hero —
     see the hero-fig section at file end. Titles keep the static foil.) */
}
/* MTG-029.1: hairline + diamond come from the shared seam-grammar rules
   ("Hairline dividers with intent", texture section at file end); only
   this site's geometry lives here. */
.sb-divider {
  position: relative;
  margin: 0 16px 12px;
}
.sb-divider::after {
  top: 50%;
  transform: translate(-50%, -50%) rotate(45deg);
}
.sb-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 8px;
  flex: 1;
}
.sb-nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 10px;
  border-left: 2px solid transparent;
  border-radius: 6px;
  color: var(--text-mid);
  text-decoration: none;
  white-space: nowrap;
}
.sb-nav a svg { flex: none; }
.sb-nav a:hover {
  background: var(--bg-card);
  color: var(--text-hi);
}
.sb-nav a.active {
  background: var(--bg-card);
  border-left-color: var(--ember);
  color: var(--gold);
  font-weight: 600;
}
/* Pinned add-card action: distinct but quiet (gold plus, dashed hairline) */
.sb-add {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 8px 4px;
  padding: 9px 10px;
  background: none;
  border: 1px dashed var(--gold-deep);
  border-radius: 6px;
  color: var(--text-mid);
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.sb-add svg { color: var(--gold); flex: none; }
.sb-add:hover {
  background: var(--bg-card);
  color: var(--gold);
  border-color: var(--gold);
}

.sb-collapse {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px;
  padding: 9px 12px;
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text-low);
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.sb-collapse:hover {
  background: var(--bg-card);
  color: var(--text-hi);
}
.sb-collapse svg { flex: none; transition: transform 0.15s ease; }

/* Collapsed rail (desktop) */
html.sb-collapsed .sb-label,
html.sb-collapsed .wordmark { display: none; }
html.sb-collapsed .sb-brand { justify-content: center; padding: 16px 0 12px; }
html.sb-collapsed .sb-crest { width: 40px; height: 40px; padding: 3px; }
html.sb-collapsed .sb-divider { display: none; } /* MTG-029.1: rail = crest alone */
/* MTG-060: the hallmark rides the wordmark — no wordmark, no mark. */
html.sb-collapsed .sb-beta { display: none; }
html.sb-collapsed .sb-nav { padding: 0 6px; }
html.sb-collapsed .sb-nav a { justify-content: center; padding: 10px 0; }
html.sb-collapsed .sb-add { justify-content: center; padding: 9px 0; margin: 0 6px 4px; }
html.sb-collapsed .sb-collapse { justify-content: center; }
html.sb-collapsed .sb-collapse svg { transform: rotate(180deg); }

/* Content column. Since 028e.1 the tab bar is mobile-only, so desktop
   keeps plain padding; the MOBILE block below carries the tab-bar +
   safe-area clearance, which sizeScanView/sizeHomeView measure as their
   bottom gap — the viewport-fitting views track it automatically. */
.content {
  margin-left: var(--sb-w);
  padding: 20px 24px 24px;
  transition: margin-left 0.15s ease;
}
main {
  max-width: 1200px;
  margin: 0 auto;
}
.view {
  display: grid;
  gap: 16px;
}
.view[hidden] { display: none; }

/* Top bar */
.topbar {
  max-width: 1200px;
  margin: 0 auto 20px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.view-title {
  flex: 1;
  margin: 0;
  font-family: "Cinzel", Georgia, serif;
  font-size: 32px;
  font-weight: 600;
  letter-spacing: 0.05em;
  line-height: 1.15;
}
.hamburger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-mid);
  cursor: pointer;
}
.hamburger:hover { color: var(--text-hi); }

/* Mobile: sidebar becomes an overlay behind a scrim */
.scrim {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  z-index: 25;
}
.scrim[hidden] { display: none; }

@media (max-width: 768px) {
  html, html.sb-collapsed { --sb-w: 0px; }
  /* 041b.4: the topbar has no room for the hallmark next to the bell on
     phones; identity moves to the sidebar row (the menu surface). */
  .lq-identity { display: none; }
  html.lq-signed-in .lq-identity-sb { display: flex; }
  .content {
    margin-left: 0;
    padding: 16px;
    padding-bottom: calc(16px + var(--tab-h) + env(safe-area-inset-bottom, 0px));
  }
  .sidebar {
    width: 230px;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
  }
  html.sb-open .sidebar { transform: none; box-shadow: 0 0 32px var(--shadow-deep); }
  .sb-collapse { display: none; }
  .hamburger { display: flex; }

  /* The rail state never applies to the overlay: labels stay visible. */
  html.sb-collapsed .sb-label,
  html.sb-collapsed .wordmark { display: inline; }
  /* MTG-060: the hallmark rides the wordmark back in with the drawer's
     full lockup. */
  html.sb-collapsed .sb-beta { display: inline; }
  /* MTG-029.1: the overlay always shows the full stacked lockup — the
     rail state is a desktop concept. */
  html.sb-collapsed .sb-brand { padding: 18px 14px 14px; }
  html.sb-collapsed .sb-crest { width: 64px; height: 64px; padding: 4px; }
  html.sb-collapsed .sb-divider { display: block; }
  html.sb-collapsed .sb-nav a { justify-content: flex-start; padding: 10px 10px; }
  html.sb-collapsed .sb-add { justify-content: flex-start; padding: 9px 10px; margin: 0 8px 4px; }
}

/* MTG-041b.4 identity chrome: who is signed in. Hidden markup until
   app.js gets a 200 from /api/me (flag off = 404, signed out = 401 —
   either way this never renders). Desktop: a quiet hallmark by the bell
   with a one-action menu (Sign out). Mobile: the line lives in the
   sidebar (the existing menu surface) instead — see the 768px block.
   Display convention (041b ruling): handle prominent, #NNNN muted small. */
.lq-identity { position: relative; }
.lq-id-btn {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 7px 10px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  font: inherit;
  cursor: pointer;
}
.lq-id-btn:hover { border-color: var(--border); }
.lq-id-handle { color: var(--text-hi); font-weight: 600; }
.lq-id-num { color: var(--text-low); font-size: 11px; }
.lq-id-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 60; /* above sidebar (30), like the theme panel */
  min-width: 130px;
  padding: 6px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 32px var(--shadow-deep);
}
.lq-signout {
  width: 100%;
  padding: 8px 10px;
  background: none;
  border: none;
  border-radius: 6px;
  color: var(--text-mid);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.lq-signout:hover { background: var(--bg-card); color: var(--text-hi); }
/* Sidebar identity row (mobile's menu surface); desktop uses the topbar. */
.lq-identity-sb {
  display: none;
  align-items: baseline;
  gap: 6px;
  margin: 0 8px;
  padding: 9px 12px;
  border-top: 1px solid var(--border);
}
.lq-identity-sb .lq-id-num { flex: 1; }
.lq-signout-sb {
  padding: 4px 10px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-mid);
  font: inherit;
  font-size: 11.5px;
  cursor: pointer;
}
.lq-signout-sb:hover { color: var(--text-hi); border-color: var(--gold-deep); }
/* 027a.4 grammar: the scan topbar stays menu + title only. */
.content:has(#view-scan:not([hidden])) .lq-identity { display: none; }

/* Notification bell + message center */
.bell-wrap { position: relative; }
.bell {
  position: relative;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-mid);
  cursor: pointer;
}
.bell:hover { color: var(--text-hi); }
.bell-badge {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--neg);
  color: var(--text-inverse);
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  text-align: center;
}
.message-center {
  position: absolute;
  right: 0;
  top: 44px;
  width: min(380px, calc(100vw - 48px));
  max-height: 480px;
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px var(--shadow);
  z-index: 10;
}
.message-center[hidden] { display: none; }
.mc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}
.mc-mark-all {
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-mid);
  font-size: 11px;
  padding: 3px 8px;
  cursor: pointer;
}
.mc-mark-all:hover { color: var(--text-hi); }
.mc-list { overflow-y: auto; }
.mc-item {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.mc-item:last-child { border-bottom: none; }
.mc-item.read { opacity: 0.55; }
.mc-title { color: var(--text-hi); font-weight: 600; }
.mc-body {
  margin-top: 2px;
  color: var(--text-mid);
  font-size: 12px;
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.mc-meta {
  margin-top: 4px;
  color: var(--text-low);
  font-size: 11px;
}
.mc-link {
  color: var(--ember);
  text-decoration: none;
}
.mc-link:hover { text-decoration: underline; }
.mc-empty { padding: 16px 12px; color: var(--text-low); }
.mc-foot {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-top: 1px solid var(--border);
}
.mc-push {
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-mid);
  font-size: 11px;
  padding: 3px 8px;
  cursor: pointer;
}
.mc-push:hover:not(:disabled) { color: var(--text-hi); }
.mc-push:disabled { opacity: 0.55; cursor: default; }
.mc-push-state { color: var(--text-low); font-size: 11px; }

/* Summary tiles */
.summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
}
.tile {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 16px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold), var(--elev-1);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.tile:hover {
  border-color: color-mix(in srgb, var(--gold) 35%, transparent);
  box-shadow: inset 0 0 0 0.5px var(--border-gold), var(--elev-2);
}
.tile-label {
  color: var(--text-mid);
  margin-bottom: 6px;
}
.tile-value {
  font-size: 26px;
  font-weight: 600;
}
.tile-value.hero { font-size: 34px; }
.tile-sub {
  margin-top: 4px;
  color: var(--text-low);
  font-size: 12px;
}
/* MTG-058.1: scope changes swap this line between empty (All) and
   populated (the scoped day-change line) — an empty div collapses to
   0px and the hero row shifted 21px on every pill click. A zero-width
   space reserves exactly one line box in the tile's own font metrics,
   so the tile height is constant across every scope state, both
   branches of the conditional, forever. */
#sum-value-sub:empty::before { content: "\200B"; }
.gain-up { color: var(--pos); }
.gain-down { color: var(--neg); }

/* Cards (chart + table containers) */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 16px 20px 20px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold), var(--elev-1);
}
.card h2 {
  margin: 0 0 12px;
  font-family: "Cinzel", Georgia, serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.07em;
  color: var(--text-hi);
}

.chart-wrap {
  position: relative;
  height: 300px;
}
.chart-note {
  margin: 10px 0 0;
  color: var(--text-low);
  font-size: 12px;
}

/* Chart range selector + change readout */
.chart-head {
  display: flex;
  align-items: baseline;
  gap: 12px 16px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
/* 028e.3: section headers step up — between the 32px view title and body */
.chart-head h2 { margin: 0; font-size: 18px; }
.card-head h2 { font-size: 18px; }
.chart-readout {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-variant-numeric: tabular-nums;
  font-size: 13px;
}
.ro-value { font-size: 15px; font-weight: 600; color: var(--text-hi); }
.ro-range { color: var(--text-low); font-size: 11px; }
.range-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-left: auto;
}
.range-row button {
  padding: 3px 10px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-mid);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.range-row button:hover { color: var(--text-hi); }
.range-row button.active {
  background: color-mix(in srgb, var(--gold) 15%, transparent);
  border-color: var(--gold-deep);
  color: var(--gold);
  font-weight: 600;
}

/* Custom HTML chart tooltip (crosshair + card-addition thumbnails) */
.chart-tooltip {
  position: absolute;
  pointer-events: none;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
  box-shadow: 0 8px 24px var(--shadow);
  opacity: 0;
  transition: opacity 0.1s ease;
  z-index: 5;
  max-width: 240px;
}
.ct-date { color: var(--text-low); font-size: 11px; }
.ct-value { color: var(--text-hi); font-weight: 600; margin-top: 2px; }
.ct-adds {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border);
  color: var(--gold);
  font-weight: 600;
}
.ct-cards { display: flex; gap: 6px; margin-top: 6px; }
.ct-card { width: 40px; }
.ct-card img {
  width: 40px;
  border-radius: 3px;
  background: var(--bg-raised);
  display: block;
}
.ct-card-name {
  margin-top: 2px;
  color: var(--text-mid);
  font-size: 9px;
  line-height: 1.2;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* Binder bar: pill per binder, value-descending, All restores totals */
.binder-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 10px;
}
.binder-bar[hidden] { display: none; }
.bb-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 4px 12px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-mid);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.bb-pill:hover { color: var(--text-hi); }
/* MTG-048.1: 048's visible per-pill counts line was vetoed at the desk
   (pill bloat, row wrap). Counts live on the scope line under the bar
   and the pill hover tooltip; pills stay one-line compact. */
.bb-pill.active {
  background: color-mix(in srgb, var(--gold) 15%, transparent);
  border-color: var(--gold-deep);
  color: var(--gold);
  font-weight: 600;
}
.bb-value {
  color: var(--text-low);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.bb-pill.active .bb-value { color: color-mix(in srgb, var(--gold) 70%, var(--text-low)); }
/* MTG-058.2: the desktop folder-color surface — a leading dot on bar
   pills and table Folder cells, painted inline from binderColor. NEVER
   a pill tint: the pill background is the active-state grammar (048.1)
   and no .active variant of this rule may exist — the dot is identical
   across states, battery-pinned. */
.fold-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
  flex: none;
}
/* Inside the pill's flex row the 7px gap is the spacing; the dot rides
   centered while name and value keep their baseline alignment. */
.bb-pill .fold-dot { margin-right: 0; align-self: center; }
/* Binder column hides when filtered to one binder (or only one exists) */
#holdings-table.binder-hidden .col-binder { display: none; }

/* Binder manager: gear pill at the bar's end + compact popover */
.bb-manage {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-low);
  cursor: pointer;
}
.bb-manage:hover { color: var(--text-hi); }
.binder-manager {
  position: fixed;
  z-index: 50;
  width: min(340px, calc(100vw - 16px));
  max-height: min(420px, calc(100vh - 24px));
  overflow-y: auto;
  padding: 12px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold), 0 8px 24px var(--shadow-deep);
  font-size: 12px;
}
.binder-manager[hidden] { display: none; }
.bm-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}
.bm-title {
  font-family: "Cinzel", Georgia, serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
}
.bm-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 2px;
  border-top: 1px solid var(--border);
}
.bm-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-hi);
  font-weight: 600;
}
.bm-counts {
  flex: none;
  color: var(--text-low);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.bm-row button {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  background: none;
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--text-low);
  cursor: pointer;
}
.bm-row button:hover { border-color: var(--border); color: var(--text-hi); }
.bm-row .bm-delete:hover { color: var(--neg); }
/* MTG-058: folder-color picker. The dot wears the effective color; the
   swatch strip expands under the row (bm-move's expansion grammar). The
   default swatch shows the folder's hash hue behind a slash — "this is
   what auto looks like". */
.bm-color {
  flex: none;
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  line-height: 0;
}
.bm-dot {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1px solid var(--border);
}
.bm-color:hover .bm-dot { border-color: var(--text-mid); }
.bm-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 2px 2px 10px;
}
.bm-swatch {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid var(--border);
  cursor: pointer;
  padding: 0;
}
.bm-swatch.active {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}
.bm-swatch-default {
  background-image: linear-gradient(135deg, transparent 44%,
      var(--text-low) 44%, var(--text-low) 56%, transparent 56%);
}

.bm-move {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 2px 2px 8px;
  color: var(--text-mid);
}
.bm-move select {
  flex: 1;
  min-width: 90px;
  padding: 4px 8px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
}
.bm-foot {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: flex-end;
}

/* ManaBox import modal */
.imp-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 28px 16px;
  border: 1.5px dashed var(--border);
  border-radius: 10px;
  text-align: center;
}
.imp-drop.dragover {
  border-color: var(--gold-deep);
  background: color-mix(in srgb, var(--gold) 8%, transparent);
}
.imp-drop.busy { opacity: 0.6; pointer-events: none; }
.imp-drop-main { margin: 0; color: var(--text-hi); font-weight: 600; }
.imp-drop-sub { margin: 0; color: var(--text-low); font-size: 12px; }
.imp-hint { margin: 10px 2px 0; color: var(--text-low); font-size: 12px; }
.imp-counts {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 8px;
}
.imp-count-main {
  color: var(--text-hi);
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.imp-count-sub { color: var(--text-low); font-size: 12px; }
.imp-binders { margin-bottom: 8px; }
.imp-binder-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 4px 2px;
  border-top: 1px solid var(--border);
  font-size: 12px;
}
.imp-binder-name { color: var(--text-hi); font-weight: 600; }
.imp-binder-counts {
  color: var(--text-low);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.imp-notes { margin-bottom: 8px; }
.imp-note { color: var(--text-mid); font-size: 12px; padding: 2px 2px; }
.imp-unresolved {
  max-height: 150px;
  overflow-y: auto;
  margin-bottom: 8px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
}
.imp-unres-head { color: var(--text-mid); font-size: 12px; margin-bottom: 4px; }
.imp-unres-row { color: var(--text-low); font-size: 11px; padding: 1px 0; }
.imp-actions {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-top: 4px;
}

/* Holdings table */
.table-meta {
  margin: 0 0 10px;
  color: var(--text-low);
  font-size: 12px;
}
.table-wrap { overflow-x: auto; }

/* Empty collection (MTG-044): the first-run teaching card replaces the
   empty table — truly-empty only; a filter with no matches keeps the
   table's quiet no-matches row. House grammar: hairline gold tiles on
   the card surface, tokens only.
   MTG-044.1: the tile row is CONTAINER-driven, not viewport-driven — in
   the 769-~1000px band the desktop main column is too narrow for three
   tiles across (chip-verified squish at width=885), and no viewport
   breakpoint can know the column's real width (sidebar + side widgets
   eat viewport). flex-wrap + a 220px basis makes tiles sit three across
   only when the card genuinely has ~684px, wrap 2+1 in between, and
   stack in narrow columns; a lone tile narrower than its basis shrinks
   (no min-width) so nothing ever overflows. Note: at <=768px the 028b
   mobile split hides this whole section (mobile collection takes over),
   so the phone block below is inert belt-and-braces. */
.empty-collection {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 40px 16px 48px;
  text-align: center;
}
.ec-title {
  margin: 0;
  font-family: "Cinzel", Georgia, serif;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.06em;
}
.empty-collection .ec-line {
  margin: 0;
  max-width: 56ch;
  color: var(--text-mid);
}
.ec-paths {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  width: 100%;
  max-width: 760px;
  margin-top: 10px;
}
.ec-path {
  flex: 1 1 220px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px 16px;
  text-align: left;
  background: none;
  border: 1px solid var(--border-gold);
  border-radius: 8px;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.ec-path:hover,
.ec-path:focus-visible {
  background: var(--bg-raised);
  border-color: var(--gold-deep);
}
.ec-path-title {
  color: var(--gold);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.ec-path-sub {
  color: var(--text-mid);
  font-size: 12.5px;
  line-height: 1.5;
}
.ec-desk-only { display: none; color: var(--text-low); }
@media (min-width: 769px) {
  .ec-desk-only { display: block; }
}
@media (max-width: 768px) {
  .ec-paths { flex-direction: column; max-width: 420px; }
}

/* MTG-045: mobile first-run teaching treatment. Lives inside
   .mob-collection, so desktop widths never render it (028b split) and
   no media query is needed. The hero reuses the 044 tile grammar
   (hairline gold, gold title, quiet sub); the secondary rows are
   compact list-style buttons, title-only. No QR line — the phone IS
   the camera. */
.mob-empty {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px 4px 8px;
  text-align: center;
  overflow-y: auto;
  min-height: 0;
}
.mob-empty .ec-line { margin: 0 auto; }
.me-hero {
  flex: none; /* .ec-path's 220px basis is a row measure; inert in this column */
  align-items: center;
  text-align: center;
  gap: 8px;
  padding: 22px 16px;
  margin-top: 6px;
  color: var(--gold); /* the camera glyph rides currentColor */
}
.me-row {
  flex: none;
  background: none;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  color: var(--text-hi);
  font: inherit;
  cursor: pointer;
}
.me-row:hover,
.me-row:focus-visible {
  background: var(--bg-raised);
  border-color: var(--gold-deep);
}

/* Collapsible holdings header (MTG-026): chevron + live count + filter */
.hold-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex: none;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text-low);
  cursor: pointer;
}
.hold-toggle:hover {
  background: var(--bg-raised);
  border-color: var(--border);
  color: var(--text-hi);
}
.hold-toggle svg { transition: transform 0.15s ease; }
html.hold-collapsed .hold-toggle svg { transform: rotate(-90deg); }
.hold-count {
  /* inside the metal h2: opt back out of the gradient text fill */
  background: none;
  -webkit-text-fill-color: var(--text-mid);
  color: var(--text-mid);
  font-size: 17px;
  font-weight: 400;
}
.hold-filter-wrap {
  position: relative;
  flex: 0 1 250px;
  min-width: 150px;
  margin-left: auto;
}
.hold-filter {
  width: 100%;
  padding: 6px 26px 6px 10px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
  font-size: 13px;
}
.hold-filter:focus {
  outline: none;
  border-color: var(--gold-deep);
}
.hold-filter::-webkit-search-cancel-button { display: none; }
.hold-filter-clear {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  padding: 0;
  background: none;
  border: none;
  border-radius: 5px;
  color: var(--text-low);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.hold-filter-clear:hover { background: var(--bg-raised); color: var(--text-hi); }
html.hold-collapsed #view-collection #hold-filter-wrap,
html.hold-collapsed #view-collection #table-meta,
html.hold-collapsed #view-collection .table-wrap,
html.hold-collapsed #view-collection #empty-collection { display: none; }

tr.no-matches td {
  padding: 18px 12px;
  color: var(--text-low);
  text-align: center;
}
tbody tr.no-matches:hover { background: none; }

/* Side-widget column (MTG-026): reusable container + header + body pattern;
   desktop only — mobile reflow is MTG-028. */
.side-col {
  display: grid;
  gap: 16px;
  align-content: start;
}
.side-widget .sw-head { margin-bottom: 10px; }
.side-widget .sw-head h2 { margin: 0; font-size: 17px; }
.sw-body { display: grid; gap: 10px; }
/* Showcase rows (MTG-026.1): larger art and type than the dense table. */
.sw-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px;
  border-radius: 6px;
  transition: background-color 0.1s ease;
}
.sw-row:hover { background: var(--bg-raised); }
.sw-row .thumb,
.sw-row .thumb-blank {
  width: 50px;
  height: 70px;
  border-radius: 4px;
}
.sw-main { flex: 1; min-width: 0; }
.sw-name {
  color: var(--text-hi);
  font-size: 14px;
  line-height: 1.25;
}
.sw-binder {
  display: inline-block;
  margin-top: 4px;
  padding: 1px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-low);
  font-size: 11px;
}
/* Movers rail rows (028e.2): Recently added's grammar, priced. */
.sw-sub {
  display: block;
  margin-top: 3px;
  color: var(--text-low);
  font-size: 11px;
}
.sw-price-col {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.sw-price { color: var(--text-hi); font-size: 13.5px; }
.sw-delta { font-size: 11px; }
.sw-quiet { padding: 6px 8px; color: var(--text-low); font-size: 12.5px; }
/* 028e.3: rail entries open the position page */
.sw-openable { cursor: pointer; }



.sw-del {
  flex: none;
  width: 28px;
  height: 28px;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--text-mid);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.1s ease;
}
.sw-row:hover .sw-del,
.sw-del:focus-visible { opacity: 1; }
.sw-del:hover { border-color: var(--border); color: var(--neg); }

/* 028e.2: the desktop landing IS Collection; Home is mobile-only, so its
   sidebar entry hides at the sidebar breakpoint (the overlay keeps it). */
@media (min-width: 769px) {
  .sb-nav a[data-view="home"] { display: none; }
}

/* Wordmark home-link: subtle hover, no geometry change (MTG-026.1) */
a.sb-brand {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
a.sb-brand:hover { background: var(--bg-card); }

/* Themed remove confirmation (MTG-026.1) */
.confirm-panel { max-width: 420px; }
.confirm-body {
  margin: 0 0 16px;
  color: var(--text-mid);
}
.confirm-input {
  width: 100%;
  margin: 0 0 16px;
  padding: 8px 12px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
}
.confirm-input:focus {
  outline: none;
  border-color: var(--gold-deep);
}
.confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
.btn-danger {
  padding: 7px 16px;
  background: none;
  border: 1px solid var(--neg);
  border-radius: 6px;
  color: var(--neg);
  font: inherit;
  cursor: pointer;
}
.btn-danger:hover {
  background: var(--neg);
  color: var(--text-inverse);
}

/* Binder pill picker (MTG-026.2): binder-bar visual language, wraps freely */
.af-binder-block { grid-column: 1 / -1; }
.af-binder-block,
.re-binder-block {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.bp-label { color: var(--text-mid); }
.bp-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
/* Destination pills read button-like (6px corners) so they never pass for
   the fully-rounded binder-bar FILTER pills (MTG-026.3). */
.bp-pill {
  padding: 4px 12px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-mid);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.bp-pill:hover { color: var(--text-hi); }
.bp-pill.active {
  background: color-mix(in srgb, var(--gold) 15%, transparent);
  border-color: var(--gold-deep);
  color: var(--gold);
  font-weight: 600;
}
/* Unsorted = the not-yet-sorted state: italic + dashed, still selectable.
   (Dashed intentionally rhymes with "+ New binder…" — both mark a
   not-a-settled-destination.) */
.bp-pill.bp-unsorted { font-style: italic; border-style: dashed; }
.bp-pill.bp-new { border-style: dashed; color: var(--text-low); }
.bp-pill.bp-new:hover { color: var(--gold); border-color: var(--gold-deep); }
.bp-pill.bp-new.active { border-style: dashed; }
.bp-new-input {
  flex: 1 1 140px;
  min-width: 120px;
  padding: 4px 10px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
  font-size: 12px;
}
.bp-new-input:focus { outline: none; border-color: var(--gold-deep); }

/* Recently-added quantity badge */
.sw-qty {
  margin-left: 7px;
  padding: 0 6px;
  border: 1px solid var(--border-gold);
  border-radius: 5px;
  color: var(--gold);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (min-width: 769px) {
  main:has(> #view-collection:not([hidden])) { max-width: 1500px; }
  /* The topbar tracks the active view's main width, so the view title is
     always flush with the content column (MTG-026.1). */
  .content:has(#view-collection:not([hidden])) .topbar { max-width: 1500px; }
  #view-collection {
    grid-template-columns: minmax(0, 1fr) 284px;
    /* MTG-059: pin the row template. The side-col spans rows 2-3; as a
       spanning item its rail height distributes into every spanned AUTO
       track, and align-items:start let row 2 grow invisibly beneath the
       chart — the Holdings top edge dropped by exactly that growth
       (measured +282px rail-wide, +714px single rail, on a 3-row
       scope). With row 3 the one flexible track, spanned extra lands
       there exclusively: row 2 is the chart's height, and the Holdings
       top edge is dead still across every scope, at every width. The
       051 rail contract (display:contents box rendering) is untouched. */
    grid-template-rows: auto auto 1fr;
    align-items: start;
  }
  #view-collection > .summary-grid { grid-column: 1 / -1; }
  #view-collection > .card { grid-column: 1; }
  #view-collection > .side-col { grid-column: 2; grid-row: 2 / span 2; }
}
@media (max-width: 768px) {
  .side-col { display: none; }
}

table {
  width: 100%;
  border-collapse: collapse;
  white-space: nowrap;
}
th, td {
  padding: 6px 10px;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
th {
  color: var(--text-mid);
  font-weight: 600;
  font-size: 12px;
  border-bottom: 1px solid var(--border-gold);
  user-select: none;
}
th.sortable { cursor: pointer; }
th.sortable:hover { color: var(--text-hi); }
th .arrow { color: var(--text-low); font-size: 10px; margin-left: 3px; }
th.num, td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
td { color: var(--text-mid); }
td.card-cell {
  color: var(--text-hi);
  display: flex;
  align-items: center;
  gap: 8px;
}
.thumb {
  width: 28px;
  height: 39px;
  object-fit: cover;
  border-radius: 3px;
  background: var(--bg-raised);
  flex: none;
}
.thumb-blank {
  width: 28px;
  height: 39px;
  border-radius: 3px;
  background: var(--bg-raised);
  flex: none;
}

tbody tr { transition: background-color 0.1s ease; }
tbody tr:hover { background: var(--bg-raised); }

tr.unpriced td { color: var(--text-low); }
tr.unpriced td.card-cell { color: var(--text-low); }
tr.unpriced .thumb { opacity: 0.5; }
.badge {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 6px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-low);
  font-size: 10px;
  vertical-align: middle;
}

/* Restocks view */
.restocks-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
}
.restock-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold);
  transition: border-color 0.15s ease;
}
.restock-card:hover { border-color: color-mix(in srgb, var(--gold) 35%, transparent); }
.rc-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.rc-name { font-weight: 600; color: var(--text-hi); }
.rc-retailer { color: var(--text-low); font-size: 12px; }
.rc-price {
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.rc-meta { color: var(--text-low); font-size: 12px; }
.rc-link {
  margin-top: 2px;
  color: var(--ember);
  font-size: 12px;
  text-decoration: none;
}
.rc-link:hover { text-decoration: underline; }
.pill {
  flex: none;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.pill-green { background: color-mix(in srgb, var(--pos) 15%, transparent); color: var(--pos); }
.pill-gold { background: color-mix(in srgb, var(--gold) 15%, transparent); color: var(--gold); }
.pill-muted { background: color-mix(in srgb, var(--text-mid) 10%, transparent); color: var(--text-low); }
.pill-red { background: color-mix(in srgb, var(--neg) 15%, transparent); color: var(--neg); }

/* Buttons */
.btn-gold {
  padding: 5px 14px;
  background: color-mix(in srgb, var(--gold) 14%, transparent);
  border: 1px solid var(--gold-deep);
  border-radius: 999px;
  color: var(--gold);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.btn-gold:hover {
  background: color-mix(in srgb, var(--gold) 22%, transparent);
  border-color: var(--gold);
}
.btn-quiet {
  padding: 5px 12px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-mid);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.btn-quiet:hover { color: var(--text-hi); }

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.card-head h2 { margin: 0; }

/* Add-card modal */
.modal {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 40;
}
.modal[hidden] { display: none; }
.modal-scrim {
  position: absolute;
  inset: 0;
  background: var(--scrim-modal);
}
.modal-panel {
  position: relative;
  width: min(520px, calc(100vw - 32px));
  max-height: min(640px, calc(100vh - 48px));
  display: flex;
  flex-direction: column;
  padding: 16px;
  background: var(--surf-3); /* TEXTURE-1: the modal is the top surface step */
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold), var(--elev-3);
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.modal-head h3 {
  margin: 0;
  font-family: "Cinzel", Georgia, serif;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.06em;
}
.modal-close {
  width: 28px;
  height: 28px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-mid);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.modal-close:hover { color: var(--text-hi); }
.search-input {
  width: 100%;
  padding: 9px 12px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-hi);
  font: inherit;
}
.search-input:focus {
  outline: none;
  border-color: var(--gold-deep);
}
.search-results {
  margin-top: 8px;
  max-height: 380px;
  overflow-y: auto;
}
.sr-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  border-left: 2px solid transparent;
  border-radius: 6px;
  cursor: pointer;
}
/* Exactly one active row at a time, driven by mouse OR keyboard via the
   shared .active class — no separate :hover styling that could coexist. */
.sr-item.active {
  background: var(--bg-card);
  border-left-color: var(--gold);
}

/* Trailing add cue: fixed-width slot, gold plus on the active row only. */
.row-cue {
  flex: none;
  width: 20px;
  text-align: center;
  font-size: 15px;
  font-weight: 600;
  color: var(--gold);
}
.sr-item.active .row-cue::before,
.sv-item.active .row-cue::before {
  content: "+";
}
.sr-thumb {
  width: 33px;
  height: 46px;
  object-fit: cover;
  border-radius: 3px;
  background: var(--bg-card);
  flex: none;
}
.sr-main { flex: 1; min-width: 0; }
.sr-name {
  display: block;
  color: var(--text-hi);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sr-set { display: block; color: var(--text-low); font-size: 11px; }
.sr-prices {
  color: var(--text-mid);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  flex: none;
}
.sr-empty { padding: 14px 8px; color: var(--text-low); }

/* Confirm step: two columns — large card image left, form right. The panel
   scales with the viewport; the form column stays comfortable on ultrawide. */
.modal-panel.wide { width: min(clamp(740px, 62vw, 1040px), calc(100vw - 48px)); }
.af-cols { display: flex; gap: 20px; }
.af-image { flex: none; width: clamp(300px, 34%, 420px); }
.af-right { max-width: 560px; }
.af-big {
  display: block;
  width: 100%;
  border-radius: 14px; /* matches real card corner geometry at this size */
  background: var(--bg-card);
}
.af-flip {
  display: block;
  margin: 8px auto 0;
}
.af-right {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.af-head { margin-bottom: 12px; }
.af-name { color: var(--text-hi); font-weight: 600; font-size: 16px; }
.af-set { color: var(--text-low); font-size: 12px; margin-top: 2px; }

@media (max-width: 768px) {
  .af-cols { flex-direction: column; }
  .af-image { width: auto; align-self: center; }
  .af-big { width: auto; max-width: 100%; max-height: 40vh; margin: 0 auto; }
}
.af-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.af-fields label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--text-mid);
  font-size: 12px;
}
.af-fields select,
.af-fields input {
  padding: 7px 9px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
}
.af-fields select:focus,
.af-fields input:focus {
  outline: none;
  border-color: var(--gold-deep);
}
.af-extra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
}
.af-lang {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-low);
  font-size: 12px;
}
.af-lang select {
  padding: 4px 6px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
  font-size: 12px;
}
.af-notes {
  width: 100%;
  margin-top: 8px;
  padding: 7px 9px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
  font-size: 12px;
  resize: vertical;
}
.af-notes:focus { outline: none; border-color: var(--gold-deep); }

.af-actions {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-top: 14px;
}
.af-msg { margin-top: 8px; font-size: 12px; color: var(--pos); min-height: 16px; }
.af-msg.error { color: var(--neg); }

/* Search view */
.search-view { padding: 24px 20px 20px; }
.sv-input {
  display: block;
  max-width: 560px;
  margin: 0 auto;
  font-size: 16px;
  padding: 12px 16px;
}
.sv-hint {
  margin: 10px 0 16px;
  text-align: center;
  color: var(--text-low);
  font-size: 12px;
}
.sv-results {
  max-width: 720px;
  margin: 0 auto;
  display: grid;
  gap: 4px;
}
.sv-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border-left: 2px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  outline: none;
}
.sv-item.active {
  background: var(--bg-raised);
  border-left-color: var(--gold);
}
.sv-thumb {
  width: 48px;
  height: 67px;
  object-fit: cover;
  border-radius: 4px;
  background: var(--bg-raised);
  flex: none;
}
.sv-main { flex: 1; min-width: 0; }
.sv-name {
  display: block;
  color: var(--text-hi);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sv-set { display: block; color: var(--text-low); font-size: 12px; }
.sv-prices {
  flex: none;
  text-align: right;
  color: var(--text-mid);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.sv-empty {
  padding: 16px;
  text-align: center;
  color: var(--text-low);
}

/* Card scanner */
.search-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
}
.search-row .search-input { flex: 1; }
.sv-row {
  max-width: 560px;
  margin: 0 auto;
}
.sv-row .sv-input { margin: 0; }

@keyframes scan-flash {
  0% {
    border-color: var(--pos);
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.35), 0 0 18px color-mix(in srgb, var(--pos) 90%, transparent);
  }
  100% {
    border-color: color-mix(in srgb, var(--gold) 75%, transparent);
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.35);
  }
}

.search-row { position: relative; }
.scan-entry {
  width: auto;
  gap: 6px;
  padding: 0 12px;
  font: inherit;
  font-size: 12px;
}

@keyframes recv-pulse {
  0%, 100% { opacity: 0.3; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1); }
}

@media (max-width: 768px) {

}

/* Row actions (appear on hover/focus only) + row editor popover */
th.actions-th { width: 1%; }
td.row-actions {
  white-space: nowrap;
  text-align: right;
  width: 1%;
}
.row-actions button {
  width: 24px;
  height: 24px;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--text-mid);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.1s ease;
  vertical-align: middle;
}
tbody tr:hover .row-actions button,
.row-actions button:focus-visible { opacity: 1; }
.row-actions button:hover {
  border-color: var(--border);
  color: var(--text-hi);
}
.row-actions .ra-del:hover { color: var(--neg); }
.row-editor {
  position: fixed;
  z-index: 50;
  display: grid;
  gap: 8px;
  padding: 12px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold), 0 8px 24px var(--shadow-deep);
  font-size: 12px;
}
.row-editor[hidden] { display: none; }
.row-editor label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  color: var(--text-mid);
}
.badge-lang {
  color: var(--gold);
  border-color: var(--gold-deep);
}

/* MTG-082.1: the gilded treatment pill — ONE chrome for every site a
   treatment renders (holdings table, add-modal and card-detail headers,
   mobile list, scanner picker, manual search, basket). Static
   gold-gradient fill from the house family, ink from --text-inverse
   (the .mfs-badge pairing), standard pill geometry. No animation, no
   shimmer, no glow — still water governs; the gleam is painted, not
   performed. Hairline pills (set, lang, "no price") never take this
   class. Self-sufficient: renders identically standalone or on the
   .badge base (spacing comes from context, not the pill). */
.badge-treat {
  display: inline-block;
  padding: 1px 7px;
  border: 1px solid var(--gold-deep);
  border-radius: 999px;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold) 55%, var(--gold-deep));
  color: var(--text-inverse);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: middle;
}

.row-editor select {
  padding: 5px 8px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
}
.row-editor input {
  width: 90px;
  padding: 5px 8px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
  font-variant-numeric: tabular-nums;
}
.row-editor input:focus { outline: none; border-color: var(--gold-deep); }
.re-actions { display: flex; justify-content: flex-end; gap: 8px; }
.re-hint { color: var(--text-low); font-size: 11px; }

/* MTG-061: bug-report modal — mailbox grammar. The context block is
   read-only and visible because it is SENT; the thanks line replaces
   the form in place (no report ID — a mailbox, not a tracker). */
#bug-form { display: flex; flex-direction: column; gap: 8px; }
.bug-label { color: var(--text-mid); font-size: 12.5px; }
.bug-input {
  width: 100%;
  padding: 8px 10px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font: inherit;
  font-size: 14px;
}
.bug-input:focus { outline: none; border-color: var(--gold-deep); }
.bug-desc { resize: vertical; min-height: 110px; }
.bug-ctx {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 2px;
  color: var(--text-low);
  font-size: 11px;
}
.bug-ctx-head { color: var(--text-mid); }
#bug-ctx-lines { overflow-wrap: anywhere; }
.bug-msg { margin: 0; color: var(--neg); font-size: 13px; }
.bug-msg:empty { display: none; }
.bug-actions { display: flex; justify-content: flex-end; }
.bug-thanks { margin: 4px 0 8px; color: var(--text-hi); font-size: 14.5px; }

/* MTG-062: Account modal + deletion ceremony. The danger zone is the
   app's FIRST red — desaturated on purpose (tempered toward the page's
   own grays via color-mix, never a full-saturation alarm) and visually
   fenced behind a hairline. The ceremony screens reuse the 061 form
   classes; Cancel wears the gold (prominent) weight on the warning
   screen because the safe path is the prominent one. */
.acct-identity { display: flex; flex-direction: column; gap: 3px; }
.acct-idline { display: flex; align-items: baseline; gap: 6px; }
.acct-idline .lq-id-handle { font-size: 16px; }
.acct-since { color: var(--text-mid); font-size: 12.5px; }
.acct-doors { color: var(--text-low); font-size: 12px; }
.acct-export { margin-top: 14px; }
.acct-csv { text-decoration: none; }
.acct-danger {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--border);
}
.acct-danger[hidden] { display: none; }
.acct-danger-btn {
  padding: 7px 14px;
  background: none;
  border: 1px solid color-mix(in srgb, var(--neg) 45%, var(--border));
  border-radius: 999px;
  color: color-mix(in srgb, var(--neg) 65%, var(--text-mid));
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}
.acct-danger-btn:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--neg) 70%, var(--border));
  color: var(--neg);
}
.acct-danger-btn:disabled { opacity: 0.45; cursor: default; }
.acct-warn-copy { margin: 0 0 10px; color: var(--text-hi); font-size: 14px; }
.acct-export-offer { margin: 0; color: var(--text-mid); font-size: 13px; }
.acct-export-offer a { color: var(--gold); }
.acct-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 14px;
}
#acct-confirm .bug-label { display: block; margin-bottom: 6px; }
#acct-confirm .bug-msg { margin-top: 8px; }

/* Settings: gear at the sidebar bottom (above Collapse) + theme picker */
.sb-settings {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 8px;
  padding: 9px 12px;
  background: none;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--text-low);
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.sb-settings:hover {
  background: var(--bg-card);
  color: var(--text-hi);
}
.sb-settings svg { flex: none; }
html.sb-collapsed .sb-settings { justify-content: center; padding: 9px 0; }
@media (max-width: 768px) {
  /* Unlike Collapse, the gear stays available in the overlay sidebar. */
  html.sb-collapsed .sb-settings { justify-content: flex-start; padding: 9px 12px; }
}

.theme-panel {
  position: fixed;
  z-index: 60; /* above the sidebar (30) and mobile scrim (25) */
  width: 264px;
  padding: 12px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold), 0 8px 24px var(--shadow);
}
.theme-panel[hidden] { display: none; }
.tp-head {
  margin-bottom: 10px;
  font-family: "Cinzel", Georgia, serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--text-hi);
}
.tp-swatches {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.tp-swatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 0;
  background: none;
  border: none;
  font: inherit;
  cursor: pointer;
  color: var(--text-mid);
  font-size: 11px;
}
.tp-swatch:hover { color: var(--text-hi); }
.tp-swatch.active { color: var(--gold); font-weight: 600; }
/* Live preview tile: the theme's card surface with its gold + accent chips.
   Chip colors are set inline from the THEME_META swatch table in app.js. */
.tp-tile {
  width: 100%;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: 8px;
}
.tp-swatch.active .tp-tile {
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold);
}
.tp-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
}
.tp-bar {
  width: 18px;
  height: 5px;
  border-radius: 999px;
}

/* ===== Scanner view (MTG-027a P3) — tokens only, all six themes ===== */
/* 027a.2: camera-is-home fits ONE viewport — no page scroll, ever. The
   column is dvh-sized (tracks iOS Safari's dynamic toolbar) minus the
   measured chrome above it (--mfs-top, set by the scanner on enter/resize
   — the topbar's height is content-driven, so it is measured, not
   hardcoded) and the safe-area/home-indicator gap below. The viewfinder
   FLEXES to whatever remains; strip/pill/editors take natural height, and
   an opened editor shrinks the viewfinder instead of scrolling the page. */
.scan-home {
  /* 028a: no separate safe-area term — the measured bottom gap (content
     padding) now carries the tab bar AND the home-indicator inset. */
  display: flex; flex-direction: column; gap: 10px;
  height: calc(100vh - var(--mfs-top, 120px) - var(--mfs-bottom-gap, 16px));
}
@supports (height: 100dvh) {
  .scan-home {
    height: calc(100dvh - var(--mfs-top, 120px) - var(--mfs-bottom-gap, 16px));
  }
}
.mfs-stage {
  position: relative; background: var(--bg-card);
  border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
  flex: 1 1 auto; min-height: 120px;
}
.mfs-stage video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; /* full-bleed viewfinder; overlay math maps the crop */
}
.mfs-bottom { flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px; }

/* 027a.3: the view title must not outrank the camera — scan view only,
   same :has() scoping the collection view already uses. Tap sizes on the
   icon buttons are untouched. */
.content:has(#view-scan:not([hidden])) .topbar { margin-bottom: 8px; }
.content:has(#view-scan:not([hidden])) .view-title { font-size: 17px; }
/* 027a.4: the scan topbar is menu + title only — the bell lives everywhere else */
.content:has(#view-scan:not([hidden])) .bell-wrap { display: none; }

/* 027a.3: corner ticks — static frame marking a CARD-shaped zone
   (63:88), centered. Under the overlay canvas.
   MTG-074.1: promoted from chrome to THE target. Since 074's calm
   search they are the only always-present affordance on the stage, but
   they still wore secondary styling (the dark --border-gold tooled
   line, 2px, 0.55) from behind the old always-drawing quad. Now they
   pop in the house grammar: display gold, longer arms, 3px stroke,
   near-full opacity, and a dark under-halo (drop-shadow follows the
   painted L-arms) so gold reads on BRIGHT card backs as well as the
   dark desk. Geometry box (63:88, 72% height, centering) untouched;
   no animation — still water, and the target never moves. Any desk
   retune must update battery_audit_scan_scope's pins IN THE SAME
   COMMIT (the 074 lesson). */
.mfs-ticks {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  aspect-ratio: 63 / 88; height: 72%; max-width: 80%;
  pointer-events: none;
}
.mfs-ticks i {
  position: absolute; width: 26px; height: 34px;
  border: 0 solid var(--gold); opacity: 0.92;
  filter: drop-shadow(0 0 1.5px rgba(0, 0, 0, 0.65));
}
.mfs-ticks i:nth-child(1) { left: 0; top: 0;
  border-left-width: 3px; border-top-width: 3px; border-top-left-radius: 8px; }
.mfs-ticks i:nth-child(2) { right: 0; top: 0;
  border-right-width: 3px; border-top-width: 3px; border-top-right-radius: 8px; }
.mfs-ticks i:nth-child(3) { right: 0; bottom: 0;
  border-right-width: 3px; border-bottom-width: 3px; border-bottom-right-radius: 8px; }
.mfs-ticks i:nth-child(4) { left: 0; bottom: 0;
  border-left-width: 3px; border-bottom-width: 3px; border-bottom-left-radius: 8px; }
#mfs-overlay { position: absolute; inset: 0; pointer-events: none; }
/* MTG-074 Part A: first-scan coaching — one dismissible line at the
   stage's top; non-blocking (only the × takes pointer events). */
.mfs-first-hint {
  position: absolute; left: 8px; right: 8px; top: 8px; z-index: 5;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  background: color-mix(in srgb, var(--bg-card) 88%, transparent);
  border: 1px solid var(--border-gold);
  border-radius: 8px;
  color: var(--text-hi); font-size: 13px;
  pointer-events: none;
}
.mfs-first-hint button {
  flex: none; margin-left: auto; width: 26px; height: 26px; padding: 0;
  background: none; border: 1px solid var(--border); border-radius: 50%;
  color: var(--text-low); font-size: 15px; line-height: 1; cursor: pointer;
  pointer-events: auto;
}
/* MTG-074 Part C: credit for success — "Added [name] ✓", ~1.5s, house
   gold, never blocking (the P4.1 fly/pop stays as the motion layer;
   this is the WORD a fast-moving user cannot miss). */
.mfs-accept-toast {
  position: absolute; left: 50%; bottom: 84px; transform: translateX(-50%);
  z-index: 6; pointer-events: none;
  padding: 8px 14px;
  background: color-mix(in srgb, var(--gold) 18%, var(--bg-card));
  border: 1px solid var(--gold-deep); border-radius: 999px;
  color: var(--gold); font-size: 14px; font-weight: 600;
  white-space: nowrap; max-width: 92%; overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0; transition: opacity 180ms ease;
}
.mfs-accept-toast.showing { opacity: 1; }
.mfs-status {
  position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--text-mid); background: var(--bg-card); font-size: 14px;
  padding: 16px; text-align: center;
}
.mfs-rail {
  position: absolute; top: 10px; right: 10px;
  display: flex; flex-direction: column; gap: 8px;
}
.mfs-rail-btn {
  position: relative; width: 42px; height: 42px; border-radius: 12px;
  display: grid; place-items: center; cursor: pointer;
  background: var(--bg-raised); border: 1px solid var(--border-gold);
  color: var(--text-hi); touch-action: manipulation;
}
.mfs-rail-btn.on { color: var(--gold-bright); border-color: var(--gold); }
.mfs-badge {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px;
  border-radius: 999px; background: var(--gold); color: var(--text-inverse);
  font-size: 11px; font-weight: 700; display: grid; place-items: center;
  padding: 0 4px;
}
.mfs-sheet {
  /* z 7 (027a.6.2): the sheet must drop OVER the mfdebug pre-lock chip
     (z 6) that shares its corner on debug URLs. Production-invisible —
     nothing else ever overlaps the sheet. */
  position: absolute; top: 10px; right: 60px; z-index: 7;
  background: var(--bg-raised); border: 1px solid var(--border-gold);
  border-radius: 10px; padding: 10px 12px; box-shadow: 0 6px 18px var(--shadow);
  display: flex; flex-direction: column; gap: 8px;
}
.mfs-toggle { color: var(--text-hi); font-size: 13.5px; display: flex; gap: 8px; }
.mfs-sheet-note { color: var(--text-low); font-size: 11.5px; }
.mfs-notice {
  color: var(--gold-bright); font-size: 13px; padding: 2px 4px;
}
.mfs-strip { display: flex; gap: 6px; overflow-x: auto; align-items: center; }
.mfs-strip-empty { min-height: 0; }
.mfs-strip-hint { color: var(--text-low); font-size: 12px; line-height: 1.3; }
.mfs-chip {
  position: relative; width: 30px; height: 42px; border-radius: 4px;
  border: 1px solid var(--border); background: var(--bg-raised);
  padding: 0; cursor: pointer; flex: 0 0 auto;
}
.mfs-chip img { width: 100%; height: 100%; object-fit: cover; border-radius: 3px; }
.mfs-chip-undo { border-color: var(--gold-deep); }
.mfs-chip-x {
  position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--gold-bright); background: var(--scrim); font-size: 15px;
  border-radius: 3px;
}
/* 027a.3: ONE continuous capsule — hairline dividers between segments,
   muted labels over values, the app's gold-hairline language. The unset
   condition renders as a segment highlight INSIDE the capsule. */
.mfs-pill {
  display: flex; background: var(--bg-raised);
  border: 1px solid var(--border-gold); border-radius: 14px;
  overflow: hidden;
}
.mfs-seg {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 6px 4px 7px; cursor: pointer;
  background: none; border: none; border-left: 1px solid var(--border);
  border-radius: 0; color: var(--text-hi); touch-action: manipulation;
}
.mfs-seg:first-child { border-left: none; }
.mfs-seg-label { font-size: 9.5px; color: var(--text-low); text-transform: uppercase; letter-spacing: 0.08em; }
.mfs-seg-value {
  font-size: 13px; font-weight: 600; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mfs-seg-unset {
  background: color-mix(in srgb, var(--ember) 14%, transparent);
  animation: mfs-pulse-bg 1.6s ease-in-out infinite;
}
.mfs-seg-unset .mfs-seg-value { color: var(--ember); }
@keyframes mfs-pulse-bg {
  0%, 100% { background-color: color-mix(in srgb, var(--ember) 8%, transparent); }
  50% { background-color: color-mix(in srgb, var(--ember) 22%, transparent); }
}
@keyframes mfs-pulse {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--ember) 30%, transparent); }
}
.mfs-seg-editor {
  display: flex; gap: 6px; flex-wrap: wrap; padding: 8px;
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: 10px;
}
.mfs-opt {
  padding: 6px 12px; border-radius: 8px; cursor: pointer;
  background: var(--bg-card); border: 1px solid var(--border);
  color: var(--text-hi);
}
.mfs-opt:hover { border-color: var(--gold-deep); }
.mfs-setlock {
  width: 100px; background: var(--bg-card); color: var(--text-hi);
  border: 1px solid var(--border); border-radius: 8px; padding: 6px 8px;
}
/* 027a.9: commit-model feedback + the locked pill's gold mark. */
.mfs-setlock-bad { border-color: var(--ember); }
.mfs-setlock-note { color: var(--ember); font-size: 12px; align-self: center; }
.mfs-seg-locked .mfs-seg-value { color: var(--gold); font-weight: 600; }
/* 027a.10: the done affordance — 44px target beside clear. */
.mfs-setlock-done {
  min-width: 44px; min-height: 44px; touch-action: manipulation;
  color: var(--gold); font-size: 16px;
}
.mfs-matchcard {
  position: absolute; left: 10px; right: 62px; bottom: 10px;
  background: var(--bg-raised); border: 1px solid var(--border-gold);
  border-radius: 12px; padding: 10px; box-shadow: 0 8px 24px var(--shadow-deep);
}
/* 027a.6 (1b): fresh-session pill nudge — one coach LINE over the lower
   viewfinder, right above the pill it points at. Never a scanning block:
   it sits before the match card in the DOM, so an open flow paints over
   it, and capture logic never consults it. */
.mfs-nudge {
  position: absolute; left: 10px; right: 62px; bottom: 10px;
  background: var(--bg-raised); border: 1px solid var(--border-gold);
  border-radius: 12px; padding: 9px 12px; text-align: left; cursor: pointer;
  color: var(--text-hi); font-size: 13.5px; line-height: 1.45;
  box-shadow: 0 8px 24px var(--shadow-deep);
}
.mfs-nudge b { color: var(--gold-bright); }
.mfs-mc-head { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.mfs-mc-name { color: var(--text-hi); font-weight: 600; }
.mfs-mc-range { color: var(--gold); font-size: 12.5px; }
.mfs-mc-status { color: var(--text-mid); font-size: 13.5px; }
.mfs-mc-gate {
  color: var(--ember); font-size: 12.5px; margin-top: 4px;
  animation: mfs-pulse 1.6s ease-in-out infinite; border-radius: 6px;
  padding: 2px 6px; display: inline-block;
}
.mfs-mc-hint { color: var(--text-low); font-size: 12px; margin-right: auto; }
.mfs-printings { display: flex; gap: 8px; overflow-x: auto; margin: 8px 0; }
.mfs-printing {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 6px; border-radius: 10px; cursor: pointer; flex: 0 0 auto;
  background: var(--bg-card); border: 1px solid var(--border);
  color: var(--text-mid);
}
.mfs-printing img { width: 58px; height: 81px; object-fit: cover; border-radius: 4px; }
.mfs-printing.chosen { border-color: var(--gold); color: var(--text-hi); }
/* 027a.8: locked-set printings lead the chooser, visually marked. */
.mfs-printing-locked .mfs-p-set { color: var(--gold); font-weight: 600; }
.mfs-lock-note { color: var(--text-mid); font-size: 12px; margin-top: 4px; }
.mfs-p-set { font-size: 11px; color: var(--text-low); }
.mfs-p-owned {
  font-size: 10.5px; color: var(--pos); border: 1px solid var(--pos);
  border-radius: 999px; padding: 0 6px;
}
.mfs-ladder { display: flex; gap: 8px; align-items: center; justify-content: flex-end; }
.mfs-search-results { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; max-height: 200px; overflow-y: auto; }
.mfs-sr {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text-hi); cursor: pointer; text-align: left;
}
.mfs-sr img { width: 24px; height: 33px; object-fit: cover; border-radius: 3px; }
.mfs-basket-panel {
  position: fixed; inset: 0; z-index: 60; display: flex; flex-direction: column;
  gap: 10px; padding: 14px; background: var(--bg-page);
}
.mfs-basket-head { display: flex; align-items: baseline; gap: 10px; color: var(--text-hi); }
.mfs-basket-head .metal { font-size: 18px; }
.mfs-basket-meta { color: var(--text-mid); font-size: 13px; margin-right: auto; }
.mfs-basket-rows { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.mfs-brow {
  display: flex; align-items: center; gap: 8px; padding: 6px 8px;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
}
.mfs-brow-nocond { border-color: var(--ember); }
.mfs-brow img { width: 34px; height: 47px; object-fit: cover; border-radius: 4px; }
.mfs-brow-main { display: flex; flex-direction: column; margin-right: auto; min-width: 0; }
.mfs-brow-name { color: var(--text-hi); font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mfs-brow select, .mfs-brow input {
  background: var(--bg-raised); color: var(--text-hi);
  border: 1px solid var(--border); border-radius: 7px; padding: 3px 4px;
}
.mfs-brow input[type="number"] { width: 52px; }
/* 027a.6 (1a): iOS Safari zooms the page when a focused text control sits
   under 16px computed — so every input/select in the scan view holds a
   16px floor. Where 16px crowds a control (basket rows), the LAYOUT gives
   (tighter padding above); the floor itself is never undercut. */
#view-scan input, #view-scan select { font-size: 16px; }
.mfs-brow-del {
  background: none; border: none; color: var(--neg); font-size: 18px;
  cursor: pointer; padding: 2px 6px;
}
.mfs-basket-foot { display: flex; align-items: center; gap: 10px; justify-content: flex-end; }
.mfs-commit-note { color: var(--ember); font-size: 12.5px; }
#mfs-commit:disabled { opacity: 0.55; cursor: not-allowed; }

/* P3.2 dev debug overlay (?mfdebug=1): display-only diagnosis pane */
.mfs-debug {
  position: absolute; top: 10px; left: 10px; z-index: 4; max-width: 46%;
  background: var(--bg-raised); border: 1px solid var(--border-gold);
  border-radius: 10px; padding: 8px; box-shadow: 0 6px 18px var(--shadow);
  font-family: ui-monospace, Consolas, monospace; font-size: 11.5px;
  color: var(--text-mid); max-height: 70%; overflow-y: auto;
}
.mfs-debug-head { color: var(--gold); display: flex; justify-content: space-between; }
.mfs-debug-img { width: 96px; border-radius: 6px; border: 1px solid var(--border); margin: 6px 0; }
.mfs-debug-list div { padding: 1px 0; }
/* 027a.6.2: pre-lock save chip — mfdebug-only, injected by app.js. Owns
   the top-right lane (left of the rail); the matcher-saw summary owns the
   top-left lane — fixed lanes, no sandwiching at any width. 44px iOS tap
   floor, touch-action so Safari's double-tap zoom can never eat a tap. */
#mf-prelock-save {
  position: absolute; top: 10px; left: calc(50% + 8px); right: 62px;
  z-index: 6; min-height: 44px; touch-action: manipulation;
  background: var(--bg-raised); color: var(--gold);
  border: 1px solid var(--border-gold); border-radius: 999px;
  padding: 5px 10px; cursor: pointer;
  font-family: ui-monospace, Consolas, monospace; font-size: 11.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#mf-prelock-save:disabled {
  opacity: 0.55; cursor: default; color: var(--text-low);
  border-color: var(--border);
}
#mf-prelock-save.mf-prelock-err { color: var(--ember); border-color: var(--ember); }
/* 027a.7 (A4): live detection line under the chip — display-only. */
#mf-detect-debug {
  position: absolute; top: 58px; right: 62px; z-index: 4;
  pointer-events: none; color: var(--text-mid);
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: 8px; padding: 2px 8px;
  font-family: ui-monospace, Consolas, monospace; font-size: 10.5px;
}
/* 027a.6.2: phone panel ergonomics — the matcher-saw panel collapses to a
   one-line summary chip on narrow viewports (tap to expand); expanded it
   drops BELOW the top furniture lane and stays clear of the match card.
   Desktop (>= 769px) keeps the always-open panel: the summary row simply
   never displays there. */
.mfs-debug-summary { display: none; }
@media (max-width: 768px) {
  .mfs-debug-summary {
    display: flex; align-items: center; gap: 6px; width: 100%;
    min-height: 34px; padding: 0 2px; background: none; border: none;
    color: var(--gold); font: inherit; cursor: pointer;
    touch-action: manipulation; text-align: left;
  }
  .mfs-debug-sumtext {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .mfs-debug-caret { margin-left: auto; color: var(--text-low); }
  .mfs-debug { top: 80px; left: 10px; right: 62px; max-width: none;
    bottom: 224px; max-height: none; }
  .mfs-debug.mfs-debug-collapsed {
    top: 10px; right: auto; bottom: auto;
    max-width: calc(50% - 18px); min-height: 44px;
    padding: 5px 10px; overflow: hidden;
  }
  .mfs-debug-collapsed > * { display: none; }
  .mfs-debug-collapsed > .mfs-debug-summary { display: flex; }
}

/* P4 commit flow (tokens only) */
.mfs-commit-flow {
  background: var(--bg-card); border: 1px solid var(--border-gold);
  border-radius: 10px; padding: 10px 12px; display: flex;
  flex-direction: column; gap: 8px;
}
.mfs-cf-title { color: var(--gold); font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em; }
/* 027a.11: the new-target input owns a labeled full-width row. */
.mfs-cf-newlabel {
  font-size: 11px; color: var(--text-low); text-transform: uppercase;
  letter-spacing: 0.08em; margin-top: 2px;
}
.mfs-cf-input {
  width: 100%; background: var(--bg-card); color: var(--text-hi);
  border: 1px solid var(--border); border-radius: 8px; padding: 9px 10px;
}
.mfs-cf-actions { display: flex; gap: 8px; justify-content: flex-end; }
/* 027a.11: basket tools row + the armed clear-all state. */
.mfs-basket-tools { display: flex; gap: 8px; align-items: center; }
.mfs-basket-tools .search-input { flex: 1; min-width: 0; }
#mfs-basket-clear { white-space: nowrap; touch-action: manipulation; }
#mfs-basket-clear.mfs-clear-armed { color: var(--ember); border-color: var(--ember); }
.mfs-cf-line { color: var(--text-hi); font-size: 14px; }
.mfs-cf-line b { color: var(--gold-bright); }
.mfs-cf-merge { color: var(--text-mid); font-size: 13px; padding-left: 8px; }
#mfs-cf-plan { display: flex; flex-direction: column; gap: 6px; }

/* P4.1 accept feedback: fly-to-badge + badge pop (on-event, then gone) */
.mfs-fly {
  position: fixed; z-index: 70; border-radius: 6px; pointer-events: none;
  object-fit: cover; opacity: 0.95;
  transition: transform 0.45s cubic-bezier(0.5, 0, 0.8, 0.4), opacity 0.45s ease-in;
  box-shadow: 0 4px 14px var(--shadow);
}
.mfs-badge-popping { animation: mfs-badge-pop 0.35s ease-out; }
@keyframes mfs-badge-pop {
  0% { transform: scale(1); }
  40% { transform: scale(1.22); }
  100% { transform: scale(1); }
}

/* P5: ticker, coach marks, tips (tokens only) */
.mfs-ticker {
  background: var(--bg-raised); border: 1px solid var(--border-gold);
  border-radius: 10px; padding: 8px 12px; color: var(--text-hi);
  font-size: 14px;
}
.mfs-coach {
  position: fixed; inset: 0; z-index: 80; display: grid; place-items: center;
  background: var(--scrim-modal); padding: 20px;
}
.mfs-coach-card {
  background: var(--bg-card); border: 1px solid var(--border-gold);
  border-radius: 14px; padding: 18px; max-width: 420px; width: 100%;
  box-shadow: 0 12px 32px var(--shadow-deep);
}
.mfs-coach-body { color: var(--text-hi); font-size: 15px; line-height: 1.55; }
.mfs-coach-body b { color: var(--gold-bright); }
.mfs-coach-foot {
  display: flex; align-items: center; gap: 10px; margin-top: 14px;
  justify-content: flex-end;
}
.mfs-coach-dots { color: var(--gold-deep); margin-right: auto; letter-spacing: 4px; }
.mfs-tips-list { margin: 8px 0 0 18px; color: var(--text-mid); font-size: 13.5px; }
.mfs-tips-list li { margin-bottom: 6px; }

/* 027a.2: safe-area guards (active under viewport-fit=cover; zero
   everywhere env() reports zero, so regular browser tabs are unchanged) */
.topbar { padding-top: env(safe-area-inset-top, 0px); }

/* ===== MTG-028a: bottom tab bar + Home view (tokens only) ===== */
/* Mobile-only chrome since 028e.1: the sidebar owns desktop navigation,
   so the bar hides at the sidebar breakpoint and spans the full viewport
   below it. --tab-h is the real bar height on Android (env() is 0);
   iOS adds the home-indicator inset as padding below the row. */
:root { --tab-h: 56px; }
.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20; /* over page content, under the mobile sidebar overlay (30) */
  display: flex;
  height: calc(var(--tab-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--bg-raised);
  border-top: 1px solid var(--border);
}
.tabbar a {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  border-top: 2px solid transparent;
  color: var(--text-mid);
  text-decoration: none;
  font-size: 11px;
  touch-action: manipulation;
}
.tabbar a svg { flex: none; }
.tabbar a:hover { color: var(--text-hi); }
.tabbar a.active {
  border-top-color: var(--ember);
  color: var(--gold);
  font-weight: 600;
}
/* 028e.1: no tab bar where the sidebar lives. */
@media (min-width: 769px) {
  .tabbar { display: none; }
}

/* Home: the 027a.2 viewport discipline — a dvh-derived flex column with
   the content-driven chrome above it measured into --mfh-top by app.js
   (same pattern as the scanner's --mfs-top). The binder strip and movers
   shrink and scroll internally under a short viewport; the page never
   scrolls. Phone-shaped column even on desktop: this is a glance view. */
.home-view {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  height: calc(100vh - var(--mfh-top, 120px) - var(--mfh-gap, 16px));
}
@supports (height: 100dvh) {
  .home-view {
    height: calc(100dvh - var(--mfh-top, 120px) - var(--mfh-gap, 16px));
  }
}
.home-hero {
  flex: none;
  padding-top: 6px;
  text-align: center;
}
.hh-value {
  color: var(--text-hi);
  font-size: 44px;
  font-weight: 650;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.hh-change {
  margin-top: 4px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.hh-when {
  margin-left: 6px;
  color: var(--text-low);
  font-size: 12px;
}

/* Per-binder strip: compact tappable rows -> Collection filtered to it */
.home-binders {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 10px;
}
.hb-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 9px 6px;
  background: none;
  border: none;
  border-top: 1px solid var(--border);
  border-radius: 0;
  color: var(--text-mid);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.hb-row:first-child { border-top: none; }
.hb-row:hover { background: var(--bg-raised); }
.hb-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-hi);
  font-weight: 600;
}
.hb-value {
  flex: none;
  color: var(--text-hi);
  font-variant-numeric: tabular-nums;
}
.hb-change {
  flex: none;
  min-width: 96px;
  text-align: right;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}

/* Today's movers: thumbnail rows; honest quiet-day line when nothing
   cleared the noise floor */
.home-movers {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
}
.hm-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
}
.hm-row + .hm-row { border-top: 1px solid var(--border); }
.hm-main { flex: 1; min-width: 0; }
.hm-name {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-hi);
}
.hm-sub { display: block; color: var(--text-low); font-size: 11px; }
.hm-right { flex: none; text-align: right; font-variant-numeric: tabular-nums; }
.hm-price { display: block; color: var(--text-hi); }
.hm-delta { display: block; font-size: 12px; }
.hm-quiet { padding: 4px 0 2px; color: var(--text-low); font-size: 13px; }

/* Watch feed (028a.1): up to 5 events, newest first, each dismissible.
   A ticker, not a page — about three rows visible, the rest scroll inside
   the box, and the box shrinks before the Home column may ever scroll. */
.home-watch {
  flex: 0 1 auto;
  min-height: 0;
  max-height: 96px;
  overflow-y: auto;
  padding: 2px 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold);
  font-size: 12.5px;
  color: var(--text-mid);
}
.hw-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
}
.hw-row + .hw-row { border-top: 1px solid var(--border); }
.hw-row svg { flex: none; color: var(--gold); }
.hw-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-hi);
}
a.hw-title { color: var(--ember); text-decoration: none; }
a.hw-title:hover { text-decoration: underline; }
.hw-when { flex: none; color: var(--text-low); font-size: 11px; }
.hw-dismiss {
  flex: none;
  width: 22px;
  height: 22px;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--text-low);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.hw-dismiss:hover { border-color: var(--border); color: var(--text-hi); }

/* Footer: pinned to the column bottom, out of the way */
.home-asof {
  flex: none;
  margin: auto 0 0;
  text-align: center;
  color: var(--text-low);
  font-size: 11px;
}

/* MTG-063: the flat-section grammar (mobile ruling 2026-08-04). ONE
   scroll — the page; sections size to their content: header -> N
   complete rows -> done. Never a clipped row, never an inner scrollbar
   — the bounded-box column above survives only as the (unreachable)
   >=769px form, byte-identical; every rule here is mobile-fenced. */
@media (max-width: 768px) {
  .home-view { height: auto; }
  .home-binders,
  .home-movers {
    flex: none;
    min-height: auto;
    max-height: none;
    overflow-y: visible;
  }
  /* The notification row leaves mobile Home: bell-only — the badge
     already announces unread. */
  .home-watch { display: none; }
  .home-asof { margin: 10px 0 0; }
  /* Two-line row anatomy, thumb-friendly (>=44px targets); the art
     thumbs stay — the hobby-feel principle. */
  .home-view .cm-row { min-height: 44px; padding: 7px 0; }
  .home-view .cm-name { font-size: 14px; }
  .home-view .cm-sub { font-size: 11.5px; }
  /* Quick-remove ✕: quiet until armed; armed wears the muted-red
     confirm state (the Clear-basket grammar). */
  .hr-del {
    flex: none;
    width: 30px;
    height: 30px;
    margin-left: 2px;
    padding: 0;
    background: none;
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--text-low);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
  }
  .hr-del.armed {
    border-color: color-mix(in srgb, var(--neg) 60%, var(--border));
    background: color-mix(in srgb, var(--neg) 12%, transparent);
    color: var(--neg);
  }
}
/* Desktop fence: the RA section and its ✕ are mobile-only surfaces —
   view-home never shows at >=769px (028e.2), this is the belt. */
@media (min-width: 769px) {
  .home-recent,
  .hr-del { display: none; }
}

/* MTG-064: mobile polish — pull-to-refresh + cold-boot skeletons.
   Everything here is mobile-fenced; motion lives ONLY inside the
   no-preference block below (prefers-reduced-motion is hard-off per
   the standing rule, and none of this touches the drift system). */
@media (max-width: 768px) {
  /* The native-gesture truce: Chrome's own reload gesture would fight
     the custom pull — containment ends the fight (iOS standalone has
     no native PTR, so ours is the only one there — the primary target). */
  html, body { overscroll-behavior-y: contain; }
  .ptr {
    position: fixed;
    top: -36px;
    left: 50%;
    transform: translate(-50%, 0);
    z-index: 40;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-raised);
    border: 1px solid var(--border);
    border-radius: 50%;
    box-shadow: 0 4px 14px var(--shadow-deep);
  }
  .ptr[hidden] { display: none; }
  .ptr-ring {
    display: block;
    width: 18px;
    height: 18px;
    border: 2px solid var(--border);
    border-top-color: var(--gold-deep);
    border-radius: 50%;
  }
  .ptr.ready .ptr-ring { border-top-color: var(--gold); }
  /* Skeletons: the 063 two-line cm-row box EXACTLY (44px min, 7px pad,
     8px gap, 28x39 thumb) so the data swap shifts nothing. */
  .sk-row {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 7px 0;
  }
  .sk-thumb {
    flex: none;
    width: 28px;
    height: 39px;
    border-radius: 3px;
    background: var(--bg-raised);
  }
  .sk-lines {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .sk-bar {
    display: block;
    width: 62%;
    height: 12px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--text-low) 22%, transparent);
  }
  .sk-bar-sub { width: 38%; height: 9px; }
  /* The Collection binder-list variant approximates the mc-brow box —
     unpinned feel-scale; the ruled exact match is the cm-row anatomy. */
  .sk-mc {
    padding: 12px 12px 12px 10px;
    min-height: 59px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
  }
  .sk-mc + .sk-mc { margin-top: 8px; }
}
@media (max-width: 768px) and (prefers-reduced-motion: no-preference) {
  .sk-thumb,
  .sk-bar { animation: sk-pulse 1.4s ease-in-out infinite; }
  .ptr.spinning .ptr-ring { animation: ptr-spin 0.8s linear infinite; }
}
@keyframes sk-pulse {
  50% { opacity: 0.45; }
}
@keyframes ptr-spin {
  to { transform: rotate(360deg); }
}

/* MTG-056.2: the scan surface's currency statement, in the basket-panel
   head — .mfs-basket-meta's margin-right:auto is the row's spacer, so
   this sits right-aligned beside the close button. (The desktop
   dashboard's statement is a plain .tile-sub in the Total value box —
   no dedicated class; the 056 grid-foot line is retired.) */
.mfs-usd {
  color: var(--text-low);
  font-size: 11px;
}

/* ===== MTG-028b: mobile Collection — binder list -> card list/grid ===== */
/* Width-driven split: phones get the two-level flow, desktop keeps the
   full dashboard untouched. Rotation/resize just swaps the chrome. */
@media (min-width: 769px) {
  .mob-collection { display: none !important; }
}
@media (max-width: 768px) {
  /* The desktop dashboard is pinch-zoom-only at phone width; below the
     breakpoint the mobile levels replace it wholesale. The card detail
     (028e) serves BOTH widths, so it is exempt here. */
  #view-collection > :not(.mob-collection):not(.card-detail) { display: none !important; }

  /* 027a.2 discipline: the view is a viewport-fitting column (chrome
     measured into --mfc-top by app.js, tab-bar clearance riding the
     .content padding contract); the row areas scroll, the page never. */
  #view-collection {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--mfc-top, 120px) - var(--mfc-gap, 16px));
  }
  @supports (height: 100dvh) {
    #view-collection {
      height: calc(100dvh - var(--mfc-top, 120px) - var(--mfc-gap, 16px));
    }
  }
  .mob-collection,
  .mcl {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    gap: 10px;
  }
  .mc-head {
    flex: none;
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .mc-head h2 {
    flex: 1;
    min-width: 0;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: "Cinzel", Georgia, serif;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: 0.06em;
  }
  .mc-export { flex: none; text-decoration: none; }
  .mc-back,
  .mc-mode {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text-mid);
    cursor: pointer;
  }
  .mc-back:hover,
  .mc-mode:hover { color: var(--text-hi); }
  .mc-mode .mc-ico-list { display: none; }
  .mc-mode.grid-on .mc-ico-grid { display: none; }
  .mc-mode.grid-on .mc-ico-list { display: block; }

  /* Level 1: binder rows, color strip on the leading edge */
  .mc-rows {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
  }
  .mc-brow {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 12px 12px 0;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: inset 0 0 0 0.5px var(--border-gold);
    color: var(--text-mid);
    font: inherit;
    text-align: left;
    cursor: pointer;
    overflow: hidden;
  }
  .mc-brow + .mc-brow { margin-top: 8px; }
  .mc-strip {
    flex: none;
    align-self: stretch;
    width: 4px;
  }
  .mc-bmain {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
  }
  .mc-bname {
    color: var(--text-hi);
    font-weight: 600;
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .mc-bcount { color: var(--text-low); font-size: 11.5px; }
  .mc-bright {
    flex: none;
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
  .mc-bvalue { color: var(--text-hi); font-weight: 600; }
  .mc-bchange { font-size: 11.5px; color: var(--text-low); }

  /* Level 2: sort pills + card list/grid */
  .mc-sort {
    flex: none;
    display: flex;
    gap: 6px;
  }
  .mc-sort button {
    padding: 4px 12px;
    background: none;
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-mid);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
  }
  .mc-sort button.active {
    background: color-mix(in srgb, var(--gold) 15%, transparent);
    border-color: var(--gold-deep);
    color: var(--gold);
    font-weight: 600;
  }
  .mc-cards {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
  }
  .mc-empty { padding: 16px 4px; color: var(--text-low); }
  .mc-crow {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 2px;
  }
  .mc-crow + .mc-crow { border-top: 1px solid var(--border); }
  .mc-crow .thumb,
  .mc-crow .thumb-blank { width: 32px; height: 45px; }
  .mc-cmain { flex: 1; min-width: 0; }
  .mc-cname {
    display: block;
    color: var(--text-hi);
    font-size: 13.5px;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .mc-csub { display: block; color: var(--text-low); font-size: 11px; }
  .mc-cright {
    flex: none;
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
  .mc-cprice { display: block; color: var(--text-hi); font-size: 13px; }
  .mc-cchange { display: block; font-size: 11px; color: var(--text-low); }

  /* Grid mode: 3-up art with price/qty badges over the card face. The
     badge scrim is a fixed dark token so it reads on any art in any
     theme; qty shows only above 1 — absence reads as one copy. */
  .mc-cards.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    align-content: start;
  }
  .mc-gcell { position: relative; }
  .mc-gcell img,
  .mc-gblank {
    display: block;
    width: 100%;
    aspect-ratio: 63 / 88;
    object-fit: cover;
    border-radius: 6px;
    background: var(--bg-raised);
  }
  /* 028e: with the detail open, the mobile levels give it the column */
  .mob-collection.detail-under { display: none; }

  /* Badges lie over card ART, not theme chrome — like the camera
     overlays they stay unthemed (parchment's dark ink on a dark scrim
     would vanish). */
  .mc-gprice {
    position: absolute;
    left: 4px;
    bottom: 4px;
    padding: 1px 6px;
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.65);
    color: #ece6dc;
    font-size: 11px;
    font-variant-numeric: tabular-nums;
  }
  .mc-gqty {
    position: absolute;
    top: 4px;
    right: 4px;
    padding: 0 5px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.65);
    color: #e8c67a;
    font-size: 11px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }
}

/* ===== MTG-028e: card detail / position page ===== */
/* Level 3 on mobile (fills the collection column, its own scroll area);
   on desktop the same node swaps in for the dashboard sections. */
.card-detail {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
}
.cd-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
}
.cd-title {
  flex: 1;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: "Cinzel", Georgia, serif;
  font-size: 21px; /* 028e.3: the position page's own title, above sections */
  font-weight: 600;
  letter-spacing: 0.06em;
}
.cd-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.cd-image {
  display: block;
  width: min(62%, 250px);
  margin: 2px auto 0;
  border-radius: 12px; /* real card corner geometry at this size */
  background: var(--bg-raised);
}
.cd-set {
  text-align: center;
  color: var(--text-low);
  font-size: 12px;
}
.cd-price-row {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 10px;
}
.cd-price {
  color: var(--text-hi);
  font-size: 26px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.cd-change {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--text-low); /* muted unless a gain class overrides */
}
/* Muted-by-default change values (house rule: exactly zero never reads as
   a gain). The compound selectors outrank both the base and inherited
   colors regardless of source order. */
.cd-mut { color: var(--text-low); }
.cd-mut.gain-up { color: var(--pos); }
.cd-mut.gain-down { color: var(--neg); }
.cd-chart-box {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold);
  padding: 10px 12px 8px;
}
.cd-chart { position: relative; }
.cd-chart svg { display: block; width: 100%; height: auto; }
/* 028e.2 rehaul: one solid line through every real point (gaps are longer
   runs between dots, never bridged), area fill under it. Cost basis is
   the ONLY dashed element. */
.cd-line { fill: none; stroke: var(--chart-line); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cd-area { fill: var(--chart-fill); stroke: none; }
.cd-cost { stroke: var(--gold-deep); stroke-width: 1.5; stroke-dasharray: 6 4; }
.cd-cost-label { fill: var(--gold); font-size: 9px; }
.cd-dot { fill: var(--chart-line); stroke: var(--bg-card); stroke-width: 1; pointer-events: none; }
.cd-hit { fill: transparent; cursor: pointer; }
.cd-tip {
  position: absolute;
  z-index: 2;
  padding: 2px 8px;
  background: var(--bg-page);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-hi);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  white-space: nowrap;
}
.cd-axis { fill: var(--text-low); font-size: 9px; font-variant-numeric: tabular-nums; }
.cd-range { margin-top: 6px; justify-content: flex-end; }
.cd-range-delta {
  margin-top: 6px;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.cd-rd-label { color: var(--text-low); font-size: 11px; margin-left: 4px; }
.cd-empty { padding: 18px 4px; color: var(--text-low); font-size: 13px; text-align: center; }
.cd-position {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 14px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold);
  padding: 12px 14px;
  font-size: 13px;
}
.cd-position dt { color: var(--text-low); margin: 0; }
.cd-position dd {
  margin: 0;
  color: var(--text-hi);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.cd-also {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cd-also-label {
  color: var(--text-low);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.cd-also-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 8px 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-mid);
  font: inherit;
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
}
.cd-also-row:hover { color: var(--text-hi); border-color: var(--gold-deep); }
.cd-also-row .cda-binder { color: var(--text-hi); font-weight: 600; }
.cd-also-row .cda-cost { margin-left: auto; font-variant-numeric: tabular-nums; }
.cd-asof {
  margin: 0 0 4px;
  text-align: center;
  color: var(--text-low);
  font-size: 11px;
}
/* Mobile keeps the 028e level-3 layout exactly: the panel and column
   wrappers are transparent to the flex column, the scrim and ✕ don't
   exist there. */
.cd-scrim { display: none; }
.cd-panel,
.cd-left,
.cd-right { display: contents; }
#cd-close { display: none; }
@media (min-width: 769px) {
  /* 028e.1/.2: desktop presents the SAME detail node as a translucent
     modal — Collection reads through dimly underneath, scroll position
     and all. */
  .card-detail {
    position: fixed;
    inset: 0;
    z-index: 40; /* the modal layer, same as add-card */
    display: grid;
    place-items: center;
    padding: 24px;
    gap: 0;
  }
  .cd-scrim {
    display: block;
    position: absolute;
    inset: 0;
    background: var(--scrim-modal);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
  }
  .cd-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: min(880px, calc(100vw - 48px));
    max-height: calc(100vh - 48px);
    padding: 16px 20px 18px;
    background: color-mix(in srgb, var(--surf-3) 84%, transparent);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: inset 0 0 0 0.5px var(--border-gold), var(--elev-3);
  }
  /* No backdrop blur -> a see-through panel would smear text over the
     dashboard; fall back to the opaque surface. */
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .cd-panel { background: var(--surf-3); }
  }
  #cd-back { display: none; }
  #cd-close { display: block; }
  tbody tr.row-openable { cursor: pointer; }

  /* Two-column detail (028e.2): image + identity + price on the left,
     chart + position on the right; also-in and the as-of footer span. */
  .cd-scroll {
    display: grid;
    grid-template-columns: minmax(0, 400px) minmax(0, 1fr);
    gap: 12px 24px;
    align-content: start;
  }
  .cd-left,
  .cd-right {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-width: 0;
  }
  .cd-image { width: 100%; max-width: 400px; margin: 0; }
  #cd-also { grid-column: 1 / -1; }
  .cd-asof { grid-column: 1 / -1; }
}

/* Desktop scan hand-off (028e.1): the camera never runs at desk width.
   Panel centers in the scan column; the QR stays dark-on-white in every
   theme — scannability beats theming, same doctrine as camera overlays. */
@media (min-width: 769px) {
  #view-scan .mfs-stage,
  #view-scan .mfs-bottom { display: none; }
}
.scan-handoff {
  margin: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 32px 40px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: inset 0 0 0 0.5px var(--border-gold);
  text-align: center;
}
/* 028e.2: the hand-off heading carries the view-title treatment — same
   serif register and size as Collection's title. */
.scan-handoff h2 {
  margin: 0;
  font-family: "Cinzel", Georgia, serif;
  font-size: 32px;
  font-weight: 600;
  letter-spacing: 0.05em;
  line-height: 1.15;
}
.sh-sub {
  margin: 0;
  max-width: 340px;
  color: var(--text-mid);
  font-size: 13px;
}
.sh-qr-box svg {
  display: block;
  width: 208px;
  height: 208px;
  border-radius: 8px;
}
.sh-url {
  color: var(--text-low);
  font-size: 12px;
  font-family: ui-monospace, Consolas, monospace;
  user-select: all;
}

/* ===== TEXTURE-1: materials, light, and ornament =====================
   Doctrine: luxury not casino — felt, never seen. One candle per view.
   Gold carries identity, violet stays a sub-10% accent, black is the
   material. All ornament is original abstract linework. */

/* Base-page material: per-theme whisper-opacity tile, painted on a fixed
   layer UNDER all content — panels sit over it, so dense data always
   rests on quiet surface. Static by doctrine (drift is banked). */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background-image: var(--texture, none);
  background-repeat: repeat;
  opacity: var(--texture-opacity, 0.05);
  pointer-events: none;
}

/* The rail sits one step above the panels. */
.side-widget {
  background: var(--bg-raised);
  box-shadow: inset 0 0 0 0.5px var(--border-gold), var(--elev-2);
}

/* Mobile card surfaces join the elevation ladder. */
.mc-brow,
.home-watch,
.home-binders,
.home-movers {
  box-shadow: inset 0 0 0 0.5px var(--border-gold), var(--elev-1);
}

/* THE ONE CANDLE: the sole glowing element per view — the total-value
   hero on Collection/Home, the current price in the position view. */
.candle {
  text-shadow: 0 0 16px color-mix(in srgb, var(--gold-bright) 30%, transparent);
}

/* Ornamental frame (TEXTURE-1.1): ONE original floral flourish — a
   flowing vine with tendril curls, a leaf pair and a blossom terminal,
   hairline strokes, drawn from scratch in-repo (nothing traced or
   sampled). Masked so it takes theme gold. Deployed on COLLECTION'S
   view title only, mirrored, blossom facing the text; desktop only. */
.view-title,
.cd-title,
.scan-handoff h2 {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}
@media (min-width: 769px) {
  /* 1.2: the full piece needs ~900px of viewport with the sidebar
     expanded; below that it scales down gracefully before the
     breakpoint hides it entirely. */
  .content:has(#view-collection:not([hidden])) .view-title::before,
  .content:has(#view-collection:not([hidden])) .view-title::after {
    content: "";
    flex: none;
    width: 110px;
    height: 16px;
    background: linear-gradient(90deg, var(--gold-deep), var(--gold));
    -webkit-mask: var(--flourish) no-repeat center / contain;
    mask: var(--flourish) no-repeat center / contain;
    opacity: 0.75;
  }
  .content:has(#view-collection:not([hidden])) .view-title::after {
    transform: scaleX(-1);
  }
}
@media (min-width: 900px) {
  .content:has(#view-collection:not([hidden])) .view-title::before,
  .content:has(#view-collection:not([hidden])) .view-title::after {
    width: 168px;
  }
}
/* Long card names: the name lives in a child span so it can ellipsize
   inside the flex title (anonymous flex text cannot). */
.cd-name-text {
  min-width: 0;
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:root {
  /* TEXTURE-1.2 hoard-gate filigree, authored from scratch: a looped
     crossover backbone with a second weaving strand, counter-rotating
     volutes at both ends, one six-petal and two five-petal blossoms,
     leaf pairs, nested tendril curls at three scales, bud terminals and
     granulation dots — all hairline; density from linework, never
     stroke weight. */
  --flourish: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 20'><g fill='none' stroke='black' stroke-width='1' stroke-linecap='round'><path d='M2 11 C 18 5 34 15 50 10 C 66 5.5 80 14 92 11 c 6 -1.5 10.5 -6.5 6 -9.2 c -4 -2.4 -8 2.6 -4 5.4 c 7.6 5.3 19 3.6 30.5 1.6 C 139 6.6 154 13.2 171 9.6 C 187 6.4 203 11.6 232 10.4'/><path d='M2 11 c 10.5 6.2 21 4 21.8 -2.2 c 0.9 -5.6 -7 -8.6 -11.4 -4.6 c -3.7 3.2 -1.6 8.2 2.7 8.4 c 3.5 0.2 5 -3.2 3.2 -5.4 c -1.5 -1.8 -4.2 -0.9 -4.3 1.1'/><path d='M232 10.4 c -9.5 -6.2 -20 -3.4 -20.5 2.2 c -0.5 5.2 6.8 7.8 10.8 4 c 3.3 -3 1.2 -7.8 -3 -7.6 c -3.1 0.2 -4.3 3.5 -2.4 5.4'/><path d='M12 8 C 30 14.5 46 5 62 11.5 C 76 16.8 90 6 106 13 C 122 18.5 138 8.5 152 12.5 C 166 16 182 7.5 196 11.8'/><path d='M120 8.2 c -1.8 -3.8 -1 -6.6 0 -7 c 1 0.4 1.8 3.2 0 7'/><path d='M120 8.2 c 2.7 -3.2 5.4 -4.3 6.1 -3.6 c 0.4 0.9 -1.7 3.2 -6.1 3.6'/><path d='M120 8.2 c 4.2 0.8 6.3 2.6 6 3.5 c -0.9 0.7 -3.9 -0.2 -6 -3.5'/><path d='M120 8.2 c 1.3 3.7 0.7 6.4 0 6.7 c -0.9 -0.3 -1.3 -3 0 -6.7'/><path d='M120 8.2 c -4.2 0.8 -6.3 2.6 -6 3.5 c 0.9 0.7 3.9 -0.2 6 -3.5'/><path d='M120 8.2 c -2.7 -3.2 -5.4 -4.3 -6.1 -3.6 c -0.4 0.9 1.7 3.2 6.1 3.6'/><path d='M70 14 c -0.9 -3 -0.4 -5 0.2 -5.3 c 0.8 0.5 1 3 -0.2 5.3'/><path d='M70 14 c 2.6 -1.6 4.6 -1.6 5 -0.8 c -0.2 0.9 -2.6 1.6 -5 0.8'/><path d='M70 14 c -2.6 -1.6 -4.6 -1.6 -5 -0.8 c 0.2 0.9 2.6 1.6 5 0.8'/><path d='M70 14 c 1.6 2.2 1.8 4 1 4.4 c -0.9 0 -1.8 -2.2 -1 -4.4'/><path d='M70 14 c -1.6 2.2 -1.8 4 -1 4.4 c 0.9 0 1.8 -2.2 1 -4.4'/><path d='M171 5.2 c 0.9 -2.8 0.4 -4.6 -0.2 -4.9 c -0.8 0.5 -1 2.8 0.2 4.9'/><path d='M171 5.2 c 2.7 -1 4.6 -0.6 4.9 0.3 c -0.5 0.8 -2.8 0.9 -4.9 -0.3'/><path d='M171 5.2 c -2.7 -1 -4.6 -0.6 -4.9 0.3 c 0.5 0.8 2.8 0.9 4.9 -0.3'/><path d='M171 5.2 c 2 1.8 2.4 3.4 1.7 3.9 c -0.9 0.1 -2 -1.8 -1.7 -3.9'/><path d='M171 5.2 c -2 1.8 -2.4 3.4 -1.7 3.9 c 0.9 0.1 2 -1.8 1.7 -3.9'/><path d='M40 8.6 q 4.2 -5.8 9 -5.2 q -4.6 4.4 -9 5.2'/><path d='M45 7.2 q 3.4 -4 6.8 -3.5 q -3.5 3.2 -6.8 3.5'/><path d='M86 12.8 q 4 5.4 8.6 5 q -4.2 -4.2 -8.6 -5'/><path d='M91 14.2 q 3.2 3.8 6.4 3.4 q -3.2 -3 -6.4 -3.4'/><path d='M146 8 q 3.6 -5 8 -4.6 q -4 4 -8 4.6'/><path d='M196 12 q 3.4 4.6 7.4 4.3 q -3.6 -3.7 -7.4 -4.3'/><path d='M14 5.4 q 0.6 -3.4 3 -4.4 q 0.4 3 -3 4.4'/><path d='M11 4.8 q -0.9 -3 -3.2 -3.6 q 0.1 3 3.2 3.6'/><path d='M58 9.7 c 2.8 -3 6.5 -2.2 6.1 0.6 c -0.3 2.3 -3.5 2 -3.7 0.1'/><path d='M104 11.8 c 2.5 2.9 5.8 2.2 5.5 -0.4 c -0.2 -2 -3.1 -1.8 -3.2 0.1'/><path d='M140 8.6 c 2 -2.4 4.9 -1.8 4.6 0.4 c -0.2 1.8 -2.7 1.6 -2.9 0.1'/><path d='M186 9.2 c 1.7 -1.9 4 -1.3 3.7 0.5 c -0.2 1.4 -2.1 1.3 -2.3 0.1'/><path d='M33 13.4 c 2 2.2 4.6 1.7 4.4 -0.3 c -0.2 -1.6 -2.4 -1.5 -2.5 0'/><path d='M50 9.9 q 1.2 -3.2 3.1 -4.6'/><path d='M53.1 5.3 q 1.3 -2.7 2.5 -2.5 q -0.4 2.5 -2.5 2.5'/><path d='M131 12.4 q 1 3 2.8 4.2'/><path d='M133.8 16.6 q 1.5 2.2 2.8 1.9 q -0.6 -2.4 -2.8 -1.9'/><path d='M216 8.4 q 1 -2.6 2.6 -3.7'/><path d='M218.6 4.7 q 1.2 -2.2 2.3 -2 q -0.4 2.2 -2.3 2'/><circle cx='120' cy='8.2' r='1.8'/></g><circle cx='120' cy='8.2' r='0.7' fill='black'/><circle cx='70' cy='14' r='0.9' fill='black'/><circle cx='171' cy='5.2' r='0.9' fill='black'/><circle cx='64' cy='6.2' r='0.7' fill='black'/><circle cx='98' cy='15.4' r='0.7' fill='black'/><circle cx='152' cy='15.6' r='0.7' fill='black'/><circle cx='181' cy='11.4' r='0.7' fill='black'/><circle cx='226' cy='7.4' r='0.7' fill='black'/></svg>");
  --empty-glyph: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 18'><g fill='none' stroke='black' stroke-width='1'><path d='M16 2l5 7-5 7-5-7z'/><path d='M2 9h7M23 9h7'/><path d='M10 15q6 3.5 12 0'/></g></svg>");
}
/* TEXTURE-1.1: the desktop hand-off card carries the Scan view — the
   small topbar heading goes; mobile scan keeps its topbar untouched. */
@media (min-width: 769px) {
  .content:has(#view-scan:not([hidden])) .view-title { display: none; }
}

/* Hairline dividers with intent: brightest center fading to transparent,
   deployed at structural seams only. Section headers get the plain line… */
.sw-head,
.card-head,
.chart-head {
  background: linear-gradient(90deg, transparent, var(--border-gold) 18%,
      var(--gold-deep) 50%, var(--border-gold) 82%, transparent)
    bottom / 100% 1px no-repeat;
  padding-bottom: 9px;
}
/* …seams between rail panels, above the modal footer and under the brand
   lockup (MTG-029.1) take the diamond (echoing the wordmark ornament).
   The pattern lives in the two shared rules below; per-site rules keep
   only their own geometry. */
.sb-divider,
.side-widget + .side-widget::before {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--border-gold) 20%,
      var(--gold-deep) 50%, var(--border-gold) 80%, transparent);
}
.sb-divider::after,
.side-widget + .side-widget::after,
.cd-asof::before {
  content: "";
  position: absolute;
  left: 50%;
  width: 5px;
  height: 5px;
  background: var(--gold-deep);
}
.side-widget + .side-widget { position: relative; }
.side-widget + .side-widget::before {
  content: "";
  position: absolute;
  left: 8%;
  right: 8%;
  top: -9px;
}
.side-widget + .side-widget::after {
  top: -11px;
  transform: translateX(-50%) rotate(45deg);
}
.cd-asof {
  position: relative;
  padding-top: 10px;
  background: linear-gradient(90deg, transparent, var(--border-gold) 25%,
      var(--gold-deep) 50%, var(--border-gold) 75%, transparent)
    center top / 70% 1px no-repeat;
}
.cd-asof::before {
  top: -2px;
  transform: translateX(-50%) rotate(45deg);
}

/* Chart as artifact: a recessed display case… */
.chart-wrap,
.cd-chart-box {
  background: var(--surf-inset);
  border-radius: 8px;
  box-shadow: var(--inset-shadow);
}
.chart-wrap { padding: 10px 10px 6px; }
.cd-chart-box { border: none; padding: 12px 12px 10px; }
/* …with a restrained luminous edge on the line (layered stroke, no glow
   sites added — the candle rule concerns text/box shadows). */
.cd-line-halo {
  fill: none;
  stroke: var(--chart-line);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.16;
}
.cd-area { stroke: none; } /* fill comes from the in-SVG gold→violet fade */

/* Gem thumbnails: rail art only; holdings-table thumbs stay untouched. */
.sw-row .thumb,
.sw-row .thumb-blank,
.hm-row .thumb,
.hm-row .thumb-blank {
  border: 1px solid color-mix(in srgb, var(--gold) 40%, transparent);
  box-shadow: 0 1px 4px var(--shadow-soft);
}

/* MTG-049: the market boxes' truth-surface footer — quiet as-of line
   echoing the Home "Prices as of" grammar (stale-but-labeled). Since
   MTG-050 it sits once, on the gainers/losers pair's foot. */
.sw-asof,
.hm-asof {
  margin: 8px 0 0;
  font-size: 11px;
  color: var(--text-low);
  text-align: right;
}

/* MTG-050: the compact mover row, shared by Your movers, both market
   boxes and Recently Added, desktop rail and mobile Home.
   MTG-070: TWO-LINE anatomy at every width (the 063 ruling, finally
   real — the old nested-inline cm-set could never leave the name's
   nowrap line). cm-main stacks line 1 (name owns the full row width +
   qty chip) over line 2 (muted set · price · signed delta). The 45px
   box the 39px thumb already forced absorbs both lines — row height
   is unchanged; title attr stays for the rare residual ellipsis. */
.cm-row {
  display: flex;
  align-items: center; /* MTG-051: rows carry the 28px art crop now */
  gap: 8px;
  padding: 3px 0; /* 39px thumb + 2x3px = 45px, under the 48px ceiling */
  min-width: 0;
}
.cm-row.sw-openable { cursor: pointer; }
.cm-row.sw-openable:hover .cm-name { color: var(--gold); }
.cm-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.cm-name {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-hi);
  font-size: 12.5px;
}
.cm-sub {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-low);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.cm-set { color: var(--text-low); }
.cm-qty {
  color: var(--text-low);
  font-size: 11px;
}
.cm-price { color: var(--text-mid); }
.cm-delta { font-size: 11px; }

/* MTG-051 Part 2: two-column rail at ultra-wide. CONTAINER-driven (the
   044.1 lesson): app.js measures .content with a ResizeObserver — the
   sidebar collapse changes real available width, which no viewport
   query can see — and stamps .rail-wide on #view-collection at >=2000px
   of content width (~2200px viewport, sidebar expanded). Below the
   stamp the wrappers are display:contents: the 050 single rail is
   byte-identical, purely-additive by construction. */
.rail-col { display: contents; }
#view-collection.rail-wide { grid-template-columns: minmax(0, 1fr) 584px; }
main:has(> #view-collection.rail-wide:not([hidden])) { max-width: 1800px; }
.content:has(#view-collection.rail-wide:not([hidden])) .topbar { max-width: 1800px; }
/* MTG-052: at ultra-wide the rail is a 2x2 grid of EQUAL-HEIGHT,
   edge-aligned boxes — col 1 personal (Recently Added / Your movers),
   col 2 market (gainers / losers). 1fr rows + default stretch equalize
   the panel; below the stamp the wrappers stay display:contents and the
   same four boxes stack at natural heights. */
.rail-wide .side-col {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}
.rail-wide .rail-col { display: contents; }
.rail-wide #recent-widget { grid-area: 1 / 1; }
.rail-wide #movers-widget { grid-area: 2 / 1; }
.rail-wide #market-gainers-widget { grid-area: 1 / 2; }
.rail-wide #market-losers-widget { grid-area: 2 / 2; }

/* MTG-052: mover-box headers are doors — quiet chevron, gold on hover. */
.sw-head.sw-door { display: flex; align-items: baseline; gap: 6px; }
.sw-door { cursor: pointer; }
.sw-door::after {
  content: "›";
  color: var(--text-low);
  font-size: 15px;
}
.sw-door:hover h2,
h2.sw-door:hover { color: var(--gold); }
.sw-door:hover::after { color: var(--gold); }

/* MTG-052: modal-depth rank numerals + the Recently Added date cell. */
.cm-rank {
  flex: none;
  width: 34px;
  color: var(--text-low);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.cm-date { color: var(--text-low); font-size: 11px; }

/* MTG-053: owned market rows — the FULL-BOX treatment (the active-
   folder-pill family: gold hairline + faint token-mixed wash), never
   louder than the gain/loss numbers. Padding trades against the border
   so the 48px row ceiling holds. */
.cm-row.cm-owned {
  border: 1px solid var(--gold-deep);
  border-radius: 6px;
  background: color-mix(in srgb, var(--gold) 8%, transparent);
  padding: 1px 6px;
}

/* MTG-053: modal polish — wider panel so names breathe before the
   ellipsis; reserved scrollbar gutter + the house thin scrollbar so
   rows never sit under the bar. */
#movers-modal .modal-panel { width: min(640px, calc(100vw - 32px)); }
.mm-body {
  overflow-y: auto;
  min-height: 0;
  display: grid;
  gap: 2px;
  scrollbar-gutter: stable;
  padding-right: 6px;
  scrollbar-width: thin;
  scrollbar-color: var(--gold-deep) transparent;
}
.mm-toggle {
  display: inline-flex;
  gap: 2px;
  margin-left: auto;
  margin-right: 10px;
}
.mm-toggle button {
  padding: 2px 10px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-mid);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.mm-toggle button.active {
  background: color-mix(in srgb, var(--gold) 15%, transparent);
  border-color: var(--gold-deep);
  color: var(--gold);
  font-weight: 600;
}

/* MTG-054: the modal's depth-100 expansion line — quiet, centered; the
   baited form names how many of YOUR cards hide below the fold. */
.mm-more {
  margin: 6px 0 2px;
  padding: 8px;
  background: none;
  border: none;
  color: var(--text-low);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  text-align: center;
}
.mm-more:hover { color: var(--gold); }

/* Empty-state flourish: the resting-glyph above quiet text. */
.sw-quiet,
.hm-quiet,
.mc-empty,
.cd-empty {
  text-align: center;
}
.sw-quiet::before,
.hm-quiet::before,
.mc-empty::before,
.cd-empty::before {
  content: "";
  display: block;
  width: 32px;
  height: 18px;
  margin: 2px auto 8px;
  background: var(--gold-deep);
  -webkit-mask: var(--empty-glyph) no-repeat center / contain;
  mask: var(--empty-glyph) no-repeat center / contain;
  opacity: 0.4;
}

/* Refined figures: tabular lining numerals via system font features —
   no vendored face, no runtime fetch. Column rhythm, not decoration. */
.fig,
.cd-position dd,
.cd-price {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: 0.01em;
}

/* Micro-interactions: one emphasis per element type, 150ms, color/
   background/shadow only — nothing that moves layout. */
tbody tr,
.sw-row,
.mc-brow,
.hm-row,
.hb-row,
.cd-also-row,
.btn-gold,
.btn-quiet,
.btn-danger,
.range-row button,
.mc-sort button,
.bb-pill,
.bp-pill,
.tabbar a,
.sb-nav a,
.mc-back,
.mc-mode,
.hw-dismiss,
.bell,
.hamburger,
.modal-close {
  transition: background-color 150ms ease, color 150ms ease,
    border-color 150ms ease, box-shadow 150ms ease;
}
@media (prefers-reduced-motion: reduce) {
  tbody tr,
  .sw-row,
  .mc-brow,
  .hm-row,
  .hb-row,
  .cd-also-row,
  .btn-gold,
  .btn-quiet,
  .btn-danger,
  .range-row button,
  .mc-sort button,
  .bb-pill,
  .bp-pill,
  .tabbar a,
  .sb-nav a,
  .mc-back,
  .mc-mode,
  .hw-dismiss,
  .bell,
  .hamburger,
  .modal-close,
  .tile,
  .sb-crest,
  .sb-brand .wordmark {
    transition: none !important;
  }
}

/* ===== TEXTURE-1.6: hero display face (STILL WATER since MTG-078.1) ==
   The total-value hero (Collection's tile and mobile Home) is the ONE
   figure that wears the display face and the full engraved foil; every
   other numeral in the app stays system tabular (.fig).
   MTG-078.1 ruling: ambient motion is DEAD. The 1.6 shimmer sweep and
   the abyss drift layers were convicted on the owner's own glass (prm
   HELD at read time: idle Collection 55% -> 6.8% of a core; fan noise
   on the first real user's machine) after three tuning passes left
   them imperceptible. Sunk-cost doctrine: no rescue. The STATIC field
   — abyss texture, gold, this engraved foil — remains untouched; only
   continuous motion died. git revert restores the animated world. */
.hero-fig { font-family: "Cinzel", Georgia, serif; }
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .hero-fig {
    background-image:
      linear-gradient(
        180deg,
        var(--metal-1) 0%,
        var(--metal-2) 28%,
        var(--metal-3) 52%,
        var(--metal-4) 76%,
        var(--metal-5) 100%
      );
    background-size: 100% 200%;
    background-position: 50% 35%;
    background-repeat: no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    /* The candle re-lights as a drop-shadow: a text-shadow would wash
       through the transparent clipped fill and gray the foil. Same glow
       color and radius as .candle. */
    text-shadow: none;
    filter: drop-shadow(0 -1px 0 rgba(255, 240, 205, 0.13))
            drop-shadow(0 1px 1px rgba(0, 0, 0, 0.45))
            drop-shadow(0 0 16px color-mix(in srgb, var(--gold-bright) 30%, transparent));
  }
}


/* TEXTURE-1.6.1: app-level ?mfdebug=1 motion readout — the element only
   exists when app.js creates it under the param; zero effect on normal
   loads. Sits clear of the mobile tab bar. */
#mf-motion-debug {
  position: fixed;
  right: 10px;
  bottom: 10px;
  /* MTG-083: instruments YIELD to action surfaces — z 5 sits under the
     match sheet (7), tab bar (20) and basket panel (60), so debug
     equipment can never paint over a commit button again (the prod
     occlusion, 2026-08-09). Display-only stays pointer-inert too. */
  z-index: 5;
  pointer-events: none;
  max-width: 60%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: var(--bg-raised);
  border: 1px solid var(--border-gold);
  border-radius: 8px;
  padding: 5px 9px;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 11.5px;
  color: var(--text-mid);
  pointer-events: none;
}
@media (max-width: 768px) {
  /* Above the tab bar AND the boot chip's mobile lane (64px) — the two
     bottom instruments stack instead of sandwiching (MTG-083). */
  #mf-motion-debug { bottom: 92px; }
}

/* MTG-083: the boot chip's inline style (index.html, the zero-dependency
   floor) pins z 5; these !important overrides own the MOBILE offset the
   inline floor cannot media-query — above the tab bar, below every
   action surface. */
@media (max-width: 768px) {
  #lq-boot-chip { bottom: 64px !important; }
}

/* MTG-066: quiet legal row at the sidebar's foot — the shell's footer
   surface, engraving-quiet. Shared by the desktop rail and the mobile
   drawer (one element); the icon-only collapsed rail hides it with the
   other labels, and the drawer's full-lockup override brings it back
   under 769px (the rail state is a desktop concept). File-end placement
   is deliberate: the cascade rule (028a.1/TEXTURE-1 lesson). */
.sb-legal {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 6px;
  /* Slim on purpose: at 360x640 the drawer already ran 610px tall, and
     the first cut of this row (8/10 padding) clipped it to 644 — the
     no-inner-scroll ruling is measured by battery_public_face, and the
     row owns its whole height budget (other rows' geometry is ruled
     elsewhere). */
  padding: 2px 12px 6px;
  font-size: 10.5px;
  color: var(--text-low);
  white-space: nowrap;
}
.sb-legal a { color: var(--text-low); text-decoration: none; }
.sb-legal a:hover { color: var(--text-hi); text-decoration: underline; }
html.sb-collapsed .sb-legal { display: none; }
@media (max-width: 768px) {
  html.sb-collapsed .sb-legal { display: flex; }
}
