:root {
  --bg: #0d1117;
  --bg-raise: #161b22;
  --bg-card: #1a2029;
  --line: #2a323d;
  --line-soft: #222932;
  --text: #e6edf3;
  --text-dim: #8b98a8;
  --accent: #c8aa6e;
  --accent-dim: #8a744a;
  --owned: #3fb950;
  --wish: #d9a441;

  --f-fury: #e0574a;
  --f-calm: #4a9de0;
  --f-mind: #a06fe0;
  --f-body: #4fb37a;
  --f-chaos: #d0499b;
  --f-order: #e0be4a;
  --f-colorless: #7d8896;

  --r-common: #7d8896;
  --r-uncommon: #4fb37a;
  --r-rare: #4a9de0;
  --r-epic: #a06fe0;
  --r-showcase: #c8aa6e;
  --r-promo: #d0499b;
}

* { box-sizing: border-box; }

/* The `hidden` attribute is only `display: none` in the browser's own sheet, so
   any class that sets a display beats it — and several here do. Every element
   toggled by `hidden` means it, so this settles the argument once rather than
   per component. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 "Segoe UI", system-ui, -apple-system, sans-serif;
}

button, input, select { font: inherit; color: inherit; }

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

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(13, 17, 23, .96);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
  padding: 12px 20px 10px;

  /* Wide layout: brand, search and actions share the first line, then the stat
     line and filters each claim one of their own. The two wrappers are
     display:contents here so the markup can fold into a dropdown on phones
     without moving anything in the DOM. */
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 16px;
}

.topbar-row,
.topbar-panel { display: contents; }

.brand {
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent);
  white-space: nowrap;
}
.brand span {
  color: var(--text-dim);
  font-weight: 400;
  margin-left: 6px;
}

.search-wrap { flex: 1 1 240px; min-width: 200px; position: relative; }

#search {
  width: 100%;
  padding: 8px 58px 8px 12px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 6px;
  outline: none;
}
#search:focus { border-color: var(--accent-dim); }

.search-hint {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  padding: 2px 6px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--bg-card);
  color: var(--text-dim);
  font: 11px/1.4 inherit;
  letter-spacing: .04em;
  pointer-events: none;
  transition: opacity .15s;
}
#search:focus ~ .search-hint { opacity: 0; }

.topbar-actions { display: flex; gap: 8px; flex: none; }

/* ---------- burger (narrow layout only) ---------- */

.menu-btn {
  display: none;
  position: relative;
  flex: none;
  width: 42px;
  height: 36px;
  place-items: center;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text-dim);
  cursor: pointer;
}
.menu-btn:hover { border-color: var(--accent-dim); }
.menu-btn[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }

.menu-icon,
.menu-icon::before,
.menu-icon::after {
  display: block;
  width: 18px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}
.menu-icon { position: relative; }
.menu-icon::before,
.menu-icon::after {
  content: '';
  position: absolute;
  left: 0;
  transition: transform .18s ease;
}
.menu-icon::before { top: -6px; }
.menu-icon::after { top: 6px; }

/* Open state turns the bars into an ✕ so the button reads as a close control. */
.menu-btn[aria-expanded="true"] .menu-icon { background: transparent; }
.menu-btn[aria-expanded="true"] .menu-icon::before { transform: translateY(6px) rotate(45deg); }
.menu-btn[aria-expanded="true"] .menu-icon::after { transform: translateY(-6px) rotate(-45deg); }

/* How many filters are in play. Without it a filtered grid looks like a bug,
   since the controls that caused it are hidden behind the button. */
.menu-badge {
  position: absolute;
  top: -7px;
  right: -7px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--accent);
  color: #14181d;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

.btn {
  padding: 7px 14px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { border-color: var(--accent-dim); color: var(--accent); }
.btn-quiet { color: var(--text-dim); }

/* ---------- export format menu ---------- */

.export-wrap { position: relative; }

#btn-export .caret { color: var(--text-dim); font-size: 10px; }
#btn-export[aria-expanded="true"] {
  border-color: var(--accent-dim);
  color: var(--accent);
}
#btn-export[aria-expanded="true"] .caret { color: inherit; }

/* Hangs off the button on the wide layout; the narrow layout below turns it
   into an inline block so it can't cover the filters behind it. */
.export-menu {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30;
  width: 268px;
  padding: 5px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 14px 30px rgba(0, 0, 0, .45);
}
.export-menu.is-open { display: block; }

.export-menu button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  background: none;
  border: 0;
  border-radius: 6px;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.export-menu button:hover,
.export-menu button:focus-visible { background: var(--bg-raise); outline: none; }
.export-menu button:hover b,
.export-menu button:focus-visible b { color: var(--accent); }

.export-menu b { display: block; font-size: 13px; font-weight: 600; }
.export-menu span {
  display: block;
  margin-top: 2px;
  color: var(--text-dim);
  font-size: 11.5px;
  line-height: 1.35;
}

/* ---------- stat line ---------- */

.statline {
  flex-basis: 100%;
  font-size: 13px;
  color: var(--text-dim);
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
}
.statline b { color: var(--text); font-weight: 600; }
.statline .pct { color: var(--accent); }

/* ---------- filters ---------- */

.filters {
  flex-basis: 100%;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}

.sel {
  padding: 6px 10px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
  outline: none;
}
.sel:focus { border-color: var(--accent-dim); }

/* Sorting reorders rather than narrows, so it isn't counted by the filter
   badge — the accent is what tells you a non-default order is in effect. */
.sel-sort.is-set { border-color: var(--accent-dim); color: var(--accent); }

/* The domain filter names the six runes, so it wears their colours. An <option>
   can hold nothing but text, so the swatch is parked over the select's own left
   padding instead. It matches the rune symbol the rules text draws, one size
   down for the filter bar. */
.sel-wrap { position: relative; display: inline-flex; }
.sel-swatch {
  position: absolute;
  left: 10px;
  top: 50%;
  width: 11px;
  height: 11px;
  margin-top: -6px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .25);
  background: var(--swatch, var(--f-colorless));
  pointer-events: none;
}
.sel-domain { padding-left: 28px; }

.segmented {
  display: flex;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
}
.segmented button {
  padding: 6px 12px;
  background: var(--bg-raise);
  border: 0;
  border-right: 1px solid var(--line);
  cursor: pointer;
  color: var(--text-dim);
}
.segmented button:last-child { border-right: 0; }
.segmented button:hover { color: var(--text); }
.segmented button.active {
  background: var(--accent);
  color: #14181d;
  font-weight: 600;
}

.chk {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-dim);
  cursor: pointer;
  user-select: none;
}
.chk input { accent-color: var(--accent); cursor: pointer; }

/* ---------- set completion panel ---------- */

.stats-panel {
  padding: 16px 20px;
  background: var(--bg-raise);
  border-bottom: 1px solid var(--line);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px 28px;
}

/* Rows are buttons — clicking one filters the grid to that set. */
.setrow {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 10px;
  align-items: center;
  padding: 6px 8px;
  margin: -6px -8px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.setrow:hover { background: var(--bg-card); border-color: var(--line); }
.setrow.is-active { border-color: var(--accent-dim); background: rgba(200, 170, 110, .1); }
.setrow.is-active .setrow-name { color: var(--accent); }
.setrow.is-promo { opacity: .6; }
.setrow.is-promo:hover, .setrow.is-promo.is-active { opacity: 1; }
.setrow-name { font-size: 14px; font-weight: 600; }
.setrow-name small { color: var(--text-dim); font-weight: 400; margin-left: 6px; }
.setrow-num { font-size: 13px; color: var(--text-dim); align-self: center; }
.bar {
  grid-column: 1 / -1;
  height: 7px;
  background: var(--bg-card);
  border-radius: 4px;
  overflow: hidden;
}
.setrow:hover .bar { background: var(--bg-raise); }
.bar-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent-dim), var(--accent));
  border-radius: 4px;
  transition: width .25s ease;
}

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

main { padding: 16px 20px 60px; }

.result-count {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--text-dim);
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
  gap: 16px;
}

.card {
  background: var(--bg-card);
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: border-color .15s, transform .15s;
}
.card:hover { transform: translateY(-2px); border-color: var(--line); }
.card.is-owned { border-color: var(--owned); }
.card.is-wish { border-color: var(--wish); }
.card.is-owned.is-wish { border-color: var(--owned); }

.card-img {
  position: relative;
  cursor: pointer;
  aspect-ratio: 5 / 7;
  background: #0a0d12;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.card-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  opacity: .38;
  filter: grayscale(.7);
  transition: opacity .2s, filter .2s;
}
.card.is-owned .card-img img { opacity: 1; filter: none; }

/* Stand-in for cards the sync built from TCGplayer, which publishes no art we
   may link to. Dimmed and brightened on ownership exactly like a real image, so
   a shelf of them still reads as owned or missing at a glance. */
.card-noart {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px;
  text-align: center;
  box-sizing: border-box;
  background: repeating-linear-gradient(
    -45deg, #11161d, #11161d 8px, #0e131a 8px, #0e131a 16px
  );
  border: 1px dashed var(--line);
  opacity: .5;
  transition: opacity .2s;
}
.card.is-owned .card-noart { opacity: 1; }
.noart-name { font-size: 12px; line-height: 1.3; color: var(--text-dim); }
.noart-note {
  font-size: 10px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent-dim);
}

.qty-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  min-width: 24px;
  padding: 2px 7px;
  border-radius: 12px;
  background: var(--owned);
  color: #0d1117;
  font-size: 12px;
  font-weight: 700;
  text-align: center;
}

/* Sits under the count badge: the total already includes foils, so this says
   how many of them are, rather than adding a second competing number. */
.foil-badge {
  position: absolute;
  top: 30px;
  left: 6px;
  padding: 2px 7px;
  border-radius: 12px;
  background: linear-gradient(115deg, #7c5cff, #21c7d6 55%, #ffb347);
  color: #10141a;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  letter-spacing: .02em;
}

.wish-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 50%;
  background: rgba(13, 17, 23, .75);
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.wish-btn:hover { color: var(--wish); }
.wish-btn.on { color: var(--wish); background: rgba(13, 17, 23, .9); }

.card-body { padding: 8px 10px 10px; display: flex; flex-direction: column; gap: 6px; flex: 1; }

/* A button rather than a div, so the detail view is reachable by keyboard —
   stripped back to the text it was, since it still has to read as a caption. */
.card-name {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.card-name:hover { color: var(--accent); }

.card-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--text-dim);
  margin-top: auto;
}
.dots { display: flex; gap: 2px; flex: none; }
.dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.card-meta .num { margin-left: auto; font-variant-numeric: tabular-nums; }

.stepper { display: flex; align-items: center; gap: 6px; }
.stepper button {
  width: 28px;
  height: 26px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--bg-raise);
  color: var(--text-dim);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
}
.stepper button:hover:not(:disabled) { color: var(--text); border-color: var(--accent-dim); }
.stepper button:disabled { opacity: .35; cursor: default; }

/* The foil row is deliberately quieter than the main count — most cards never
   get one, and it shouldn't compete with the number people actually edit. */
.stepper-foil { margin-top: 5px; gap: 5px; }
.stepper-foil button, .stepper-foil input { height: 22px; font-size: 12px; }
.stepper-foil button { width: 24px; }
.stepper-foil input { color: var(--text-dim); }
.card.is-owned .stepper-foil input { color: var(--text); }
.foil-tag {
  font-size: 12px;
  line-height: 1;
  background: linear-gradient(115deg, #7c5cff, #21c7d6 55%, #ffb347);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.stepper input {
  flex: 1;
  min-width: 0;
  height: 26px;
  text-align: center;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 5px;
  outline: none;
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}
.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper input:focus { border-color: var(--accent-dim); }

.empty { text-align: center; color: var(--text-dim); padding: 60px 0; }

/* ---------- prices ---------- */

.card-price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.card-price .price { color: var(--text); font-weight: 600; }
.card-price .price.none { color: var(--text-dim); font-weight: 400; }
.card-price .delta { font-size: 11px; }
.card-price .delta.up { color: var(--owned); }
.card-price .delta.down { color: #e0574a; }
/* The foil market price, shown whenever one exists so the gap against the
   normal price is visible before you own either. */
.card-price .price-foil { font-size: 11px; color: #9d8cff; }
/* Value of the whole stack, pushed right so the unit price stays the anchor. */
.card-price .stack { margin-left: auto; color: var(--text-dim); }

.statline .hint { color: var(--text-dim); font-size: 12px; }

/* Collection worth — the headline number, so it reads as a figure rather than
   as another stat in the row. It doubles as the handle for the detail panel,
   which is what the caret is announcing. */
.stat-value {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 3px 12px 4px;
  border: 1px solid var(--accent-dim);
  border-radius: 8px;
  background: linear-gradient(180deg, rgba(200, 170, 110, .14), rgba(200, 170, 110, .05));
  cursor: pointer;
  font: inherit;
  text-align: left;
}
.stat-value:hover { border-color: var(--accent); background: rgba(200, 170, 110, .2); }
.stat-value[aria-expanded="true"] { border-color: var(--accent); }
.stat-caret { font-size: 10px; color: var(--accent); }

/* No price sync — the chip is just a label, so it shouldn't wear the gold. */
.stat-value.is-bare {
  border-color: var(--line);
  background: var(--bg-raise);
  align-items: center;
  padding: 5px 12px;
}
.stat-value.is-bare:hover { border-color: var(--accent-dim); }
.stat-value.is-bare .stat-caret { color: var(--text-dim); }
.stat-value-label {
  font-size: 11px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.stat-value-num {
  font-size: 19px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

/* Currency picker — sits beside the worth figure and is deliberately quiet, so
   it reads as a unit attached to that number rather than as another filter. */
.sel-cur {
  padding: 4px 9px;
  font-size: 12px;
  color: var(--text-dim);
  letter-spacing: .04em;
}
.sel-cur:hover { color: var(--text); border-color: var(--accent-dim); }

.value-panel {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(180px, 240px) 1fr;
  gap: 8px 28px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
}
.value-head { display: flex; flex-direction: column; gap: 2px; }
.value-label {
  font-size: 11px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.value-big {
  font-size: 34px;
  font-weight: 700;
  color: var(--accent);
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.value-meta { font-size: 11.5px; color: var(--text-dim); line-height: 1.5; margin-top: 2px; }

.value-top h4 {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-dim);
  font-weight: 600;
}
.value-list { list-style: none; margin: 0; padding: 0; }
.value-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 0;
  font-size: 13px;
}
.value-list img {
  width: 22px;
  height: 22px;
  object-fit: cover;
  object-position: top center;
  border-radius: 3px;
  background: var(--bg-card);
  flex: none;
}
.vl-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vl-qty { color: var(--text-dim); font-size: 12px; min-width: 26px; text-align: right; }
.vl-unit { color: var(--text-dim); font-size: 12px; min-width: 56px; text-align: right; font-variant-numeric: tabular-nums; }
.vl-line {
  min-width: 66px;
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ---------- deck modal ---------- */

.btn-primary {
  border-color: var(--accent-dim);
  color: var(--accent);
  font-weight: 600;
}
.btn-primary:hover { background: var(--accent); color: #14181d; border-color: var(--accent); }

.deck-modal {
  width: min(1100px, 94vw);
  max-height: 88vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}
/* Needs the [open] guard — a bare display:flex would defeat dialog's own hiding. */
.deck-modal[open] { display: flex; flex-direction: column; }
.deck-modal::backdrop { background: rgba(5, 8, 12, .72); backdrop-filter: blur(3px); }

.deck-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-raise);
  flex-wrap: wrap;
}
.deck-title {
  margin: 0;
  font-size: 17px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent);
}
.deck-sub {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
}
.deck-head { flex: none; }
.deck-head-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

.deck-body {
  padding: 16px 20px 24px;
  overflow-y: auto;
  overflow-x: hidden;
  flex: 1;
  min-height: 0;
}

.deck-stats {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  font-size: 13px;
  color: var(--text-dim);
  padding-bottom: 14px;
}
.deck-stats b { color: var(--text); font-size: 15px; font-weight: 700; }
.deck-stats .dot { display: inline-block; vertical-align: middle; margin: 0 1px 0 4px; }

.deck-status { margin: 0 0 14px; font-size: 13px; border-radius: 8px; padding: 9px 14px; }
.deck-status.ok {
  color: var(--owned);
  background: rgba(63, 185, 80, .09);
  border: 1px solid rgba(63, 185, 80, .3);
}
.deck-status.warn {
  color: var(--wish);
  background: rgba(217, 164, 65, .09);
  border: 1px solid rgba(217, 164, 65, .3);
  padding-left: 32px;
}
.deck-status.warn li { margin: 2px 0; }

/* Energy curve — bars grow from a fixed-height rail so columns stay aligned. */
.deck-curve {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 116px;
  padding: 0 0 4px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--line-soft);
}
.curve-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  height: 100%;
  gap: 3px;
}
.curve-bar {
  width: 100%;
  max-width: 54px;
  min-height: 2px;
  background: linear-gradient(180deg, var(--accent), var(--accent-dim));
  border-radius: 4px 4px 0 0;
}
.curve-n { font-size: 11px; color: var(--text); font-variant-numeric: tabular-nums; order: -1; }
.curve-k { font-size: 11px; color: var(--text-dim); }

.deck-columns { columns: 2; column-gap: 28px; }
/* Two columns squeeze card names past the point of being readable well before
   the phone breakpoint, so they collapse to one earlier than the rest of the UI. */
@media (max-width: 820px) { .deck-columns { columns: 1; } }
.deck-section { break-inside: avoid; margin-bottom: 18px; }
.deck-section h3 {
  margin: 0 0 6px;
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-dim);
  border-bottom: 1px solid var(--line-soft);
  padding-bottom: 5px;
}
.deck-section h3 span { color: var(--accent); margin-left: 4px; }
.deck-section ul { list-style: none; margin: 0; padding: 0; }

.deck-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
  font-size: 13px;
}
.deck-count {
  min-width: 22px;
  color: var(--accent);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.deck-thumb {
  width: 26px;
  height: 26px;
  object-fit: cover;
  object-position: top center;
  border-radius: 4px;
  background: var(--bg-card);
  flex: none;
}
/* A button, so the detail view is reachable from a decklist by keyboard too. */
.deck-row-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.deck-row-name:hover { color: var(--accent); }

/* What the generator decided the deck is trying to do. The two numbers are the
   halves of the loop — cards that set it up over cards that pay it off. */
.deck-themes {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 16px;
  font-size: 12px;
}
.deck-themes-label {
  letter-spacing: .07em;
  text-transform: uppercase;
  font-size: 10px;
  color: var(--text-dim);
}
.deck-theme {
  border: 1px solid var(--accent-dim);
  border-radius: 20px;
  padding: 3px 11px;
  color: var(--accent);
  background: rgba(200, 170, 110, .08);
}
.deck-theme b { color: var(--text-dim); font-weight: 600; margin-left: 3px; }
.deck-themes-none { margin: 0 0 16px; font-size: 12px; color: var(--text-dim); }
.deck-dots { display: flex; gap: 2px; flex: none; }
.deck-energy { flex: none; width: 22px; text-align: center; }
.deck-energy b {
  display: inline-block;
  min-width: 18px;
  padding: 1px 0;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--bg-raise);
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.deck-row-price {
  color: var(--text-dim);
  font-size: 12px;
  min-width: 52px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.deck-note {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--text-dim);
  border-top: 1px solid var(--line-soft);
  padding-top: 12px;
}
.deck-empty { padding: 32px 0 8px; text-align: center; color: var(--text); font-size: 15px; }
.deck-empty-hint { text-align: center; color: var(--text-dim); font-size: 13px; margin: 0 0 24px; }

/* ---------- card detail ---------- */

.card-modal {
  width: min(880px, 94vw);
  max-height: 92vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}
.card-modal[open] { display: block; }
.card-modal::backdrop { background: rgba(5, 8, 12, .78); backdrop-filter: blur(3px); }

/* Art beside the details on a wide screen, stacked below the header on a
   narrow one. The whole body is the scroller so the art scrolls away with the
   text rather than pinning a 700px image above it. */
.card-modal-body {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
  gap: 20px;
  padding: 20px;
  max-height: 92vh;
  overflow-y: auto;
}

.detail-close { position: absolute; top: 10px; right: 10px; z-index: 1; }

.detail-art { align-self: start; }
.detail-art img {
  width: 100%;
  border-radius: 10px;
  display: block;
  background: #0a0d12;
}
.detail-art .card-noart { aspect-ratio: 5 / 7; border-radius: 10px; opacity: 1; }

.detail-info { min-width: 0; display: flex; flex-direction: column; gap: 12px; }

.detail-name {
  margin: 0;
  /* Clears the close button, which floats over this corner. */
  padding-right: 40px;
  font-size: 19px;
  line-height: 1.25;
  color: var(--accent);
}

.detail-line {
  margin: -6px 0 0;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--text-dim);
}
.detail-sep { color: var(--line); }

.detail-stats { display: flex; gap: 8px; flex-wrap: wrap; }
.detail-stat {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 5px 12px;
  text-align: center;
  min-width: 62px;
  background: var(--bg-raise);
}
.detail-stat b { display: block; font-size: 17px; line-height: 1.2; }
.detail-stat span {
  font-size: 10px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.detail-chips { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.detail-chips-label {
  font-size: 10px;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-right: 2px;
}
.chip {
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 2px 10px;
  font-size: 11px;
  color: var(--text-dim);
  background: var(--bg-raise);
}

/* ---- rules text ---- */

.detail-rules {
  border-left: 2px solid var(--accent-dim);
  padding-left: 12px;
  font-size: 13.5px;
  line-height: 1.55;
}
.detail-rules p { margin: 0 0 7px; }
.detail-rules p:last-child { margin-bottom: 0; }

.rules-kw {
  color: var(--accent);
  font-weight: 600;
  letter-spacing: .02em;
}
.rules-note { color: var(--text-dim); font-style: italic; font-size: 12.5px; }
.rules-arrow { color: var(--accent-dim); padding: 0 2px; }

/* Inline cost and stat symbols. Sized off the surrounding text so they keep
   their place in a line rather than pushing it apart. */
.sym {
  display: inline-block;
  vertical-align: -2px;
  line-height: 1;
  font-size: 11px;
  font-weight: 700;
}
.sym-energy {
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 50%;
  background: var(--line);
  color: var(--text);
  text-align: center;
  line-height: 17px;
}
.sym-rune {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .25);
  vertical-align: -1px;
}
.sym-might { color: var(--wish); font-size: 12px; }
.sym-exhaust { color: var(--f-mind); font-size: 13px; }
.sym-text { color: var(--text-dim); font-weight: 400; }

.detail-flavor {
  margin: 0;
  font-style: italic;
  font-size: 12.5px;
  color: var(--text-dim);
  border-top: 1px solid var(--line-soft);
  padding-top: 10px;
}
.detail-artist { margin: -6px 0 0; font-size: 11px; color: var(--accent-dim); }

.detail-prices { display: flex; gap: 8px; flex-wrap: wrap; }
.detail-price {
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  padding: 5px 12px;
  background: var(--bg-raise);
}
.detail-price b { display: block; font-size: 15px; font-variant-numeric: tabular-nums; }
.detail-price span { font-size: 10px; color: var(--text-dim); }
.detail-price.none { color: var(--text-dim); font-size: 12px; padding: 8px 12px; }

.detail-own { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.detail-wish.on { color: var(--wish); border-color: var(--wish); }

/* Anchors styled as buttons — `color` has to be set explicitly, since the
   element reset only reaches button, input and select. */
.detail-links { display: flex; gap: 8px; flex-wrap: wrap; }
.detail-links .btn {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  color: var(--text);
}
.detail-links .btn-quiet { color: var(--text-dim); }
.detail-links .btn:hover { color: var(--accent); }

/* ---------- pack simulator ---------- */

.btn-pack {
  border-color: var(--accent-dim);
  color: var(--accent);
}
.btn-pack:hover { border-color: var(--accent); background: rgba(200, 170, 110, .1); }

/* Every rarity-tinted piece of the simulator reads its colour from here, so a
   card, its dot in the strip and its row in the odds table always agree. */
.r-common { --glow: var(--r-common); }
.r-uncommon { --glow: var(--r-uncommon); }
.r-rare { --glow: var(--r-rare); }
.r-epic { --glow: var(--r-epic); }
.r-showcase { --glow: var(--r-showcase); }

.pack-modal {
  width: min(880px, 94vw);
  max-height: 92vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}
.pack-modal[open] { display: flex; flex-direction: column; }
.pack-modal::backdrop { background: rgba(4, 6, 10, .84); backdrop-filter: blur(4px); }

.pack-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-raise);
  flex: none;
}
.pack-title { margin: 0; font-size: 15px; font-weight: 600; letter-spacing: .02em; }
.pack-bar-actions { display: flex; gap: 6px; }

.icon-btn {
  padding: 4px 9px;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
  line-height: 1.4;
}
.icon-btn:hover { border-color: var(--accent-dim); }

.pack-stage {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 22px 20px 26px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pack-lede { margin: 0 0 16px; color: var(--text-dim); font-size: 13px; line-height: 1.6; }
.pack-note {
  margin: 12px 0 0;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.6;
}
.pack-hint { margin: 0; font-size: 13px; color: var(--text-dim); }

/* --- choosing a set --- */

.pack-choose { width: 100%; max-width: 560px; }
.pack-picks { display: grid; gap: 10px; }
.pack-pick {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 12px;
  text-align: left;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color .15s, transform .15s;
}
.pack-pick:hover { border-color: var(--accent); transform: translateY(-1px); }
.pack-mini {
  flex: none;
  width: 42px;
  height: 60px;
  border-radius: 5px;
  display: grid;
  place-items: center;
  font-size: 11px;
  letter-spacing: .06em;
  color: #f2e6c8;
  background: linear-gradient(160deg, #1d2748 0%, #2c1e4a 45%, #111827 100%);
  border: 1px solid var(--accent-dim);
}
.pack-pick-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pack-pick-name { font-weight: 600; }
.pack-pick-meta { font-size: 12px; color: var(--text-dim); }
.pack-pick-odds { font-size: 12px; color: var(--accent); }

/* --- the sealed pack --- */

.pack-sealed { display: flex; flex-direction: column; align-items: center; gap: 20px; }

.booster {
  position: relative;
  width: 248px;
  height: 348px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  transition: transform .15s;
}
.booster:hover { transform: translateY(-4px); }
.booster:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; }

/* The wrapper is drawn twice and clipped along one jagged line, so the two
   halves register as a single printed pack until the tear pulls them apart. */
.booster-piece {
  position: absolute;
  inset: 0;
  transition: transform .85s cubic-bezier(.22, .8, .3, 1), opacity .85s ease-in;
}
.booster-piece.top {
  clip-path: polygon(0 0, 100% 0, 100% 20%, 92% 24%, 84% 19%, 76% 24%, 68% 19%,
    60% 24%, 52% 19%, 44% 24%, 36% 19%, 28% 24%, 20% 19%, 12% 24%, 4% 19%, 0 23%);
}
.booster-piece.bottom {
  clip-path: polygon(0 23%, 4% 19%, 12% 24%, 20% 19%, 28% 24%, 36% 19%, 44% 24%,
    52% 19%, 60% 24%, 68% 19%, 76% 24%, 84% 19%, 92% 24%, 100% 20%, 100% 100%, 0 100%);
}

.booster-art {
  position: absolute;
  inset: 0;
  border-radius: 12px;
  border: 1px solid var(--accent-dim);
  background:
    radial-gradient(120% 80% at 50% 0%, rgba(200, 170, 110, .22), transparent 60%),
    linear-gradient(160deg, #1d2748 0%, #2c1e4a 46%, #0f1622 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
}
.booster-brand {
  font-size: 11px;
  letter-spacing: .38em;
  text-transform: uppercase;
  color: var(--accent);
  text-indent: .38em;
}
.booster-set {
  font-size: 21px;
  font-weight: 700;
  text-align: center;
  padding: 0 20px;
  line-height: 1.25;
}
.booster-rune {
  width: 66px;
  height: 66px;
  border: 2px solid var(--accent-dim);
  border-radius: 12px;
  transform: rotate(45deg);
  position: relative;
}
.booster-rune::after {
  content: '';
  position: absolute;
  inset: 11px;
  border: 2px solid var(--accent);
  border-radius: 6px;
}
.booster-foot {
  font-size: 10px;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.booster-shine {
  position: absolute;
  inset: 0;
  border-radius: 12px;
  overflow: hidden;
  pointer-events: none;
  transition: opacity .3s;
}
.booster-shine::after {
  content: '';
  position: absolute;
  inset: -30% -60%;
  background: linear-gradient(100deg, transparent 38%, rgba(255, 255, 255, .16) 50%, transparent 62%);
  animation: sheen 3.6s linear infinite;
}
@keyframes sheen {
  0% { transform: translateX(-60%); }
  100% { transform: translateX(60%); }
}

.booster.is-torn { animation: shake .3s ease-in-out; pointer-events: none; }
.booster.is-torn .top { transform: translate(-7%, -145%) rotate(-15deg); opacity: 0; }
.booster.is-torn .bottom { transform: translateY(12px); }
.booster.is-torn .booster-shine { opacity: 0; }
@keyframes shake {
  20% { transform: translateX(-7px) rotate(-1.2deg); }
  55% { transform: translateX(6px) rotate(1deg); }
  80% { transform: translateX(-3px); }
}

/* Foil confetti off the tear line. */
.shard {
  position: absolute;
  top: 21%;
  left: 50%;
  width: 7px;
  height: 9px;
  border-radius: 1px;
  background: var(--accent);
  opacity: 0;
  pointer-events: none;
}
.is-torn .shard { animation: fly .95s cubic-bezier(.15, .7, .4, 1) forwards; }
@keyframes fly {
  0% { opacity: 1; transform: translate(0, 0) rotate(0); }
  100% { opacity: 0; transform: translate(var(--x), var(--y)) rotate(var(--r)); }
}
.shard.s0  { --x: -104px; --y: -96px;  --r: 260deg; }
.shard.s1  { --x: -74px;  --y: -132px; --r: -210deg; background: #f0e2c0; }
.shard.s2  { --x: -38px;  --y: -108px; --r: 190deg; }
.shard.s3  { --x: -12px;  --y: -146px; --r: -320deg; background: #f0e2c0; }
.shard.s4  { --x: 26px;   --y: -118px; --r: 240deg; }
.shard.s5  { --x: 62px;   --y: -140px; --r: -180deg; }
.shard.s6  { --x: 98px;   --y: -92px;  --r: 300deg; background: #f0e2c0; }
.shard.s7  { --x: -118px; --y: -34px;  --r: -260deg; }
.shard.s8  { --x: 116px;  --y: -28px;  --r: 210deg; }
.shard.s9  { --x: -88px;  --y: 22px;   --r: 160deg; background: #f0e2c0; }
.shard.s10 { --x: 84px;   --y: 30px;   --r: -190deg; }
.shard.s11 { --x: -46px;  --y: 54px;   --r: 220deg; }
.shard.s12 { --x: 44px;   --y: 60px;   --r: -240deg; background: #f0e2c0; }
.shard.s13 { --x: 4px;    --y: 74px;   --r: 280deg; }

/* --- revealing, one card at a time --- */

.pack-reveal {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 100%;
  cursor: pointer;
}
/* Fixed so the stage doesn't resize under the pointer between cards. */
.reveal-slot { height: 408px; display: grid; place-items: center; width: 100%; }

.reveal-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  perspective: 1200px;
}

.reveal-flip {
  position: relative;
  width: 236px;
  height: 330px;
  transform-style: preserve-3d;
  transform: rotateY(180deg);
  transition: transform .55s cubic-bezier(.3, .8, .3, 1), box-shadow .4s .35s;
  border-radius: 11px;
}
.reveal-card.is-open .reveal-flip { transform: rotateY(0deg); }
.reveal-card.is-open.is-hype .reveal-flip {
  box-shadow: 0 0 0 1px var(--glow), 0 0 46px -4px var(--glow);
}

.reveal-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: 11px;
  overflow: hidden;
}
.reveal-face img { width: 100%; height: 100%; object-fit: contain; display: block; }
.reveal-face.back {
  transform: rotateY(180deg);
  display: grid;
  place-items: center;
  border: 1px solid var(--accent-dim);
  background:
    radial-gradient(90% 60% at 50% 40%, rgba(200, 170, 110, .18), transparent 65%),
    linear-gradient(160deg, #1d2748 0%, #2c1e4a 46%, #0f1622 100%);
}
.back-rune {
  width: 62px;
  height: 62px;
  border: 2px solid var(--accent-dim);
  border-radius: 12px;
  transform: rotate(45deg);
  position: relative;
}
.back-rune::after {
  content: '';
  position: absolute;
  inset: 10px;
  border: 2px solid var(--accent);
  border-radius: 6px;
}

.reveal-info { display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center; }
.reveal-rarity {
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--glow);
}
.reveal-name { font-size: 16px; font-weight: 600; }
.reveal-sub { font-size: 12px; color: var(--text-dim); }
.reveal-count {
  font-size: 12px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  min-width: 46px;
}

/* Shockwave, timed to land as the card finishes turning over. */
.burst {
  position: absolute;
  top: 0;
  left: 50%;
  width: 236px;
  height: 330px;
  margin-left: -118px;
  border: 2px solid var(--glow);
  border-radius: 11px;
  opacity: 0;
  pointer-events: none;
}
.is-open .burst { animation: burst .85s .34s ease-out forwards; }
@keyframes burst {
  0% { opacity: .85; transform: scale(.96); }
  100% { opacity: 0; transform: scale(1.55); }
}

.reveal-strip { display: flex; gap: 5px; flex-wrap: wrap; justify-content: center; min-height: 12px; }
.strip-dot { width: 8px; height: 12px; border-radius: 2px; background: var(--glow); opacity: .8; }

.reveal-foot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: center; }

/* --- what came out --- */

.pack-summary { width: 100%; display: flex; flex-direction: column; gap: 18px; }
.sum-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.sum-head h3 { margin: 0; font-size: 16px; font-weight: 600; }
.sum-best {
  padding: 3px 11px;
  border-radius: 99px;
  border: 1px solid var(--glow);
  color: var(--glow);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.sum-value { margin-left: auto; color: var(--accent); font-weight: 600; }

.sum-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(86px, 1fr)); gap: 10px; }
.sum-card { margin: 0; }
.sum-card img {
  width: 100%;
  aspect-ratio: 744 / 1039;
  object-fit: contain;
  border-radius: 6px;
  display: block;
  box-shadow: 0 0 0 1px var(--glow);
}
.sum-card figcaption {
  margin-top: 5px;
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sum-odds h4 { margin: 0 0 8px; font-size: 13px; font-weight: 600; }
.sum-odds table { width: 100%; border-collapse: collapse; font-size: 13px; }
.sum-odds th, .sum-odds td {
  text-align: left;
  padding: 6px 8px;
  border-bottom: 1px solid var(--line-soft);
  font-weight: 400;
}
.sum-odds thead th { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); }
.sum-odds tbody tr { color: var(--text-dim); }
.sum-odds tbody tr.is-hit { color: var(--text); }
.sum-odds tbody th { display: flex; align-items: center; gap: 7px; }
.sum-odds td { font-variant-numeric: tabular-nums; }
.sum-odds .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--glow); }

.sum-actions { display: flex; gap: 8px; flex-wrap: wrap; }

@media (prefers-reduced-motion: reduce) {
  .booster-piece, .reveal-flip { transition-duration: .01ms; }
  .booster-shine::after, .is-torn .shard, .is-open .burst, .booster.is-torn { animation: none; }
  .shard { display: none; }
}

/* ---------- toast ---------- */

.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  padding: 10px 20px;
  background: var(--bg-raise);
  border: 1px solid var(--accent-dim);
  border-radius: 8px;
  z-index: 50;
  font-size: 14px;
}

/* ---------- narrow layout: header collapses to a burger ---------- */

/* Kicks in above the phone breakpoint — the filter row alone needs ~700px
   before it stops wrapping into three lines and eating the first screen. */
@media (max-width: 760px) {
  .topbar { display: block; padding: 8px 12px; }

  .topbar-row {
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .menu-btn { display: grid; }
  .brand span { display: none; }
  .search-wrap { min-width: 0; }

  /* A real dropdown: it floats over the grid rather than pushing it down, so
     the cards behind it keep their position while you set a filter. */
  .topbar-panel {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    padding: 12px;
    /* Opaque, not the header's translucent fill — card art showing through a
       menu that sits on top of the grid is unreadable. */
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 16px 30px rgba(0, 0, 0, .5);
    max-height: calc(100dvh - 56px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .topbar-panel.is-open { display: block; }

  /* Dense packing keeps Import beside Export when the full-width format menu
     unfolds between them, instead of leaving a hole and a stranded button. */
  .topbar-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; grid-auto-flow: dense; }
  .topbar-actions .btn { padding: 9px 14px; text-align: center; }
  /* The two things you'd come here to do get a row each; export/import share one. */
  .topbar-actions .btn-primary,
  .topbar-actions .btn-pack { grid-column: 1 / -1; }

  /* The wrapper steps out of the way so the button keeps its half of the row
     and the menu can claim a full-width row of its own beneath it. */
  .export-wrap { display: contents; }

  /* Inline rather than floating: a panel hanging over the header would bury the
     stat line and filters under it. Open pushes the rest of the menu down and
     the panel scrolls, so everything stays reachable. */
  .export-menu {
    position: static;
    grid-column: 1 / -1;
    width: auto;
    margin-top: -2px;
    box-shadow: none;
    background: var(--bg-raise);
  }
  .export-menu button { padding: 10px 12px; }
  .export-menu b { font-size: 14px; }
  .export-menu span { font-size: 12px; }

  .statline {
    gap: 8px 16px;
    padding: 12px 0;
    margin: 12px 0;
    border-top: 1px solid var(--line-soft);
    border-bottom: 1px solid var(--line-soft);
  }
  /* Worth reads as its own menu row here, with the caret parked on the right. */
  .stat-value { width: 100%; align-items: center; padding: 7px 12px; }
  .stat-value .stat-caret { margin-left: auto; }
  .stat-value-num { font-size: 17px; }
  .sel-cur { padding: 7px 10px; font-size: 13px; }

  .filters { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .filters .sel { width: 100%; padding: 9px 10px; }
  /* The domain select is a grid cell one level down now, so the wrapper is what
     has to fill the column — and the taller control moves the swatch with it. */
  .filters .sel-wrap { width: 100%; }
  .filters .sel-domain { padding-left: 28px; }
  /* Odd one out of the four filter selects, and its labels are the longest. */
  .sel-sort { grid-column: 1 / -1; }
  .segmented { grid-column: 1 / -1; }
  .segmented button { flex: 1; padding: 8px 4px; }
  .chk { padding-left: 2px; }
  #btn-reset { padding: 8px 14px; }

  /* The pack fills a phone screen edge to edge; the card has to leave room for
     the name and counter under it or the reveal scrolls out of view. */
  .pack-modal { width: 100vw; max-width: 100vw; max-height: 100dvh; height: 100dvh; border-radius: 0; }
  .pack-stage { padding: 16px 14px 22px; }
  .booster { width: 208px; height: 292px; }
  .booster-set { font-size: 18px; }
  .reveal-slot { height: 356px; }
  .reveal-flip, .burst { width: 200px; height: 280px; }
  .burst { margin-left: -100px; }
  .sum-cards { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 8px; }
  .sum-card figcaption { display: none; }
  .sum-odds .oi { display: none; }
  .sum-value { margin-left: 0; }
  .sum-actions .btn { flex: 1; text-align: center; }
}

@media (max-width: 600px) {
  /* no Ctrl key to press on a phone */
  .search-hint { display: none; }
  #search { padding-right: 12px; }
  main { padding: 12px 12px 40px; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
  .brand { font-size: 15px; }

  /* inset:0 rather than 100vw — vw includes the page's scrollbar, which pushed
     the dialog wider than the viewport and clipped the right-hand column. */
  .deck-modal {
    inset: 0;
    margin: 0;
    width: auto;
    max-width: none;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
    border: 0;
  }
  .deck-body { padding: 14px; }
  .deck-head { padding: 12px 14px; }
  .deck-head-actions { width: 100%; }
  .deck-head-actions .sel { flex: 1 1 120px; min-width: 0; }
  /* One column — two would truncate every card name on a phone. */
  .deck-columns { columns: 1; }
  .deck-stats { gap: 12px; }

  /* Same treatment as the deck dialog: full screen, and the art moves above
     the details instead of beside them. */
  .card-modal {
    inset: 0;
    margin: 0;
    width: auto;
    max-width: none;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
    border: 0;
  }
  .card-modal-body {
    grid-template-columns: 1fr;
    gap: 16px;
    padding: 16px;
    max-height: 100dvh;
  }
  /* Half width and centred — a phone-wide card image is all you'd see. */
  .detail-art { width: min(220px, 55%); margin: 0 auto; }

  /* Stack the worth headline above the top-cards list rather than beside it. */
  .value-panel { grid-template-columns: 1fr; gap: 14px; }
  .value-big { font-size: 28px; }
  .vl-unit { display: none; }
}

/* ---------------- account ---------------- */

/* A dot rather than a word: sync state matters when it's wrong, and the button
   is already carrying a name. Colour is backed up by the title attribute. */
/* Capped because email local-parts run long — the full address, and the sync
   state the dot encodes, are both on the title attribute. */
.btn-account.is-signed-in {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: 15ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.btn-account.is-signed-in::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--text-dim);
  flex: none;
}
.btn-account[data-sync="ok"]::before { background: #3fb950; }
.btn-account[data-sync="busy"]::before { background: var(--accent); }
.btn-account[data-sync="warn"]::before { background: #d29922; }

.auth-modal {
  width: min(380px, 92vw);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
}
.auth-modal::backdrop { background: rgba(5, 8, 12, .72); backdrop-filter: blur(3px); }

.auth-form,
.auth-signed { padding: 22px; }

.auth-modal h2 { margin: 0 0 6px; font-size: 17px; }
.auth-sub { margin: 0 0 18px; color: var(--text-dim); font-size: 13px; line-height: 1.5; }
.auth-note { margin: 0 0 18px; color: var(--text-dim); font-size: 12px; line-height: 1.5; }

.auth-field { display: block; margin-bottom: 14px; }
.auth-field span {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  color: var(--text-dim);
}
.auth-field input {
  width: 100%;
  padding: 9px 11px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--text);
  font: inherit;
  font-size: 14px;
}
.auth-field input:focus { border-color: var(--accent-dim); outline: none; }

.auth-error {
  margin: 0 0 14px;
  padding: 9px 11px;
  border: 1px solid rgba(210, 153, 34, .4);
  border-radius: 8px;
  background: rgba(210, 153, 34, .08);
  color: #e3b341;
  font-size: 12.5px;
  line-height: 1.45;
}

.auth-actions { display: flex; gap: 8px; }
.auth-actions .btn { flex: 1; text-align: center; }
.auth-actions .btn[disabled] { opacity: .6; cursor: default; }

.auth-switch {
  margin: 16px 0 0;
  font-size: 12.5px;
  color: var(--text-dim);
  text-align: center;
}
.linkish {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.linkish:hover { color: #e0c68c; }

@media (max-width: 760px) {
  /* Sits with Export and Import in the two-column grid; nothing special needed
     beyond matching their centred label. */
  .btn-account.is-signed-in { justify-content: center; }
}

/* ---------------- public profile ---------------- */

.profile-pane {
  margin: 0 0 18px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-raise);
}

.profile-row { display: flex; align-items: flex-start; gap: 14px; }
.profile-copy { flex: 1; min-width: 0; }
.profile-copy b { display: block; font-size: 13.5px; margin-bottom: 3px; }
.profile-copy span {
  display: block;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-dim);
}

/* A switch rather than a checkbox: this one setting decides whether other
   people can see the account at all, and it should look like it does. */
.switch { position: relative; flex: none; width: 42px; height: 24px; cursor: pointer; }
.switch input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.switch-track {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 12px;
  background: var(--bg-card);
  border: 1px solid var(--line);
  transition: background .15s, border-color .15s;
}
.switch-track::after {
  content: '';
  position: absolute;
  top: 4px;
  left: 4px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--text-dim);
  transition: transform .15s, background .15s;
}
.switch input:checked + .switch-track { background: rgba(200, 170, 110, .22); border-color: var(--accent-dim); }
.switch input:checked + .switch-track::after { transform: translateX(18px); background: var(--accent); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--accent-dim); outline-offset: 2px; }
.switch input:disabled { cursor: default; }
.switch input:disabled + .switch-track { opacity: .5; }

.profile-detail { margin-top: 14px; }
.profile-detail .auth-field { margin-bottom: 10px; }
.profile-actions { display: flex; }

.profile-msg {
  margin: 12px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-dim);
}
.profile-msg.is-ok { color: var(--owned); }
.profile-msg.is-warn { color: #e3b341; }

.profile-link {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--text-dim);
}
/* Long enough to wrap on a phone, and it should wrap rather than widen the
   dialog it sits in. */
.profile-link .linkish { word-break: break-all; text-align: left; }

/* ---------------- the collector browser ---------------- */

.btn-collectors {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.collectors-icon { color: var(--accent); font-size: 15px; line-height: 1; }

/* ---------- saved decks ---------- */

.decks-modal {
  width: min(680px, 94vw);
  max-height: min(760px, 90vh);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}
/* Needs the [open] guard — a bare display:flex would defeat dialog's own hiding. */
.decks-modal[open] { display: flex; flex-direction: column; }
.decks-modal::backdrop { background: rgba(5, 8, 12, .72); backdrop-filter: blur(3px); }

.decks-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 18px 18px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.decks-head h2 { margin: 0 0 4px; font-size: 17px; }
.decks-sub { margin: 0; font-size: 12.5px; color: var(--text-dim); }
.decks-head .btn { margin-left: auto; flex: none; }
.decks-head .icon-btn { flex: none; }

.decks-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 14px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ---------- pasting one in ---------- */

.deck-paste {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.deck-paste-label { font-size: 12.5px; color: var(--text-dim); }
.deck-paste textarea {
  width: 100%;
  padding: 10px 11px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--text);
  outline: none;
  resize: vertical;
  font: 12.5px/1.6 ui-monospace, "Cascadia Mono", Consolas, monospace;
}
.deck-paste textarea:focus { border-color: var(--accent-dim); }
.deck-paste-row { display: flex; gap: 8px; flex-wrap: wrap; }
.deck-paste-row input {
  flex: 1 1 180px;
  min-width: 0;
  padding: 7px 11px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--text);
  outline: none;
}
.deck-paste-row input:focus { border-color: var(--accent-dim); }
.deck-paste-note:empty { display: none; }
.deck-paste-note { margin: 0; font-size: 12.5px; color: var(--wish); }

/* ---------- one saved deck ---------- */

.saved-deck {
  padding: 12px 14px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.saved-deck.is-open { border-color: var(--accent-dim); }

.saved-deck-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.saved-deck-name {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.saved-deck-name:hover { color: var(--accent); }
.saved-deck-caret { color: var(--text-dim); font-size: 11px; }
.saved-deck-tools { display: flex; gap: 4px; flex: none; }
.saved-deck-tools .btn { padding: 4px 9px; font-size: 12.5px; }

.saved-deck-meta {
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--text-dim);
}
.saved-deck-meta b { color: var(--text); font-weight: 600; }
.saved-deck-owned {
  margin-left: 4px;
  padding: 1px 7px;
  border: 1px solid var(--line);
  border-radius: 999px;
  white-space: nowrap;
}
/* A deck you can actually field, as opposed to one you're still collecting. */
.saved-deck-owned.ok { border-color: var(--owned); color: var(--owned); }

/* Not an error — a decklist is worth keeping while it's still half-built. */
.saved-deck-issues { margin: 5px 0 0; font-size: 12.5px; color: var(--wish); }

.saved-deck-list {
  margin: 12px 0 0;
  padding: 12px 14px;
  max-height: 340px;
  overflow: auto;
  background: var(--bg);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  font: 12.5px/1.7 ui-monospace, "Cascadia Mono", Consolas, monospace;
  color: var(--text-dim);
  white-space: pre;
}

/* ---------- import review ---------- */

.import-modal {
  width: min(520px, 94vw);
  max-height: min(680px, 88vh);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}
/* Needs the [open] guard — a bare display:flex would defeat dialog's own hiding. */
.import-modal[open] { display: flex; flex-direction: column; }
.import-modal::backdrop { background: rgba(5, 8, 12, .72); backdrop-filter: blur(3px); }

.import-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 18px 18px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.import-head h2 { margin: 0 0 4px; font-size: 17px; }
.import-sub { margin: 0; font-size: 12.5px; color: var(--text-dim); }
.import-head .icon-btn { margin-left: auto; flex: none; }

.import-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px 18px;
}

.import-figs { display: flex; gap: 8px; flex-wrap: wrap; }
.import-fig {
  flex: 1 1 120px;
  padding: 10px 12px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 9px;
}
.import-fig b { display: block; font-size: 20px; line-height: 1.2; color: var(--accent); }
.import-fig span { font-size: 12px; color: var(--text-dim); }

/* What the file couldn't tell us. Deliberately not styled as an error — a few
   unmatched rows is the normal outcome, not a failure. */
.import-note {
  margin: 14px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-dim);
}
.import-note b { color: var(--text); }

.import-choices {
  margin: 16px 0 0;
  padding-left: 18px;
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--text-dim);
}
.import-choices li + li { margin-top: 8px; }
.import-choices b { color: var(--text); }

.import-actions {
  flex: none;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
  padding: 14px 18px;
  border-top: 1px solid var(--line-soft);
}

.collectors-modal {
  width: min(460px, 94vw);
  max-height: min(680px, 88vh);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}
/* Needs the [open] guard — a bare display:flex would defeat dialog's own hiding. */
.collectors-modal[open] { display: flex; flex-direction: column; }
.collectors-modal::backdrop { background: rgba(5, 8, 12, .72); backdrop-filter: blur(3px); }

.collectors-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 18px 18px 12px;
  border-bottom: 1px solid var(--line-soft);
}
.collectors-head h2 { margin: 0 0 4px; font-size: 17px; }
.collectors-sub { margin: 0; font-size: 12.5px; color: var(--text-dim); }
.collectors-head .icon-btn { margin-left: auto; flex: none; }

.collectors-search { padding: 12px 18px 0; }
.collectors-search input {
  width: 100%;
  padding: 8px 11px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: 8px;
  outline: none;
  font-size: 14px;
}
.collectors-search input:focus { border-color: var(--accent-dim); }

.collectors-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.collectors-note {
  margin: 10px 6px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-dim);
}

.collector {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 10px;
  border: 1px solid transparent;
  border-radius: 9px;
  background: none;
  text-align: left;
  cursor: pointer;
}
.collector:hover { background: var(--bg-raise); border-color: var(--line); }
.collector:disabled { opacity: .5; cursor: default; }

/* Two initials in a disc. There are no avatars to upload and nothing to fetch
   from elsewhere, so the handle draws its own. */
.collector-avatar {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--bg-card);
  border: 1px solid var(--line);
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
}

.collector-main { flex: 1; min-width: 0; }
.collector-handle {
  display: block;
  font-size: 14px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.collector-handle em {
  font-style: normal;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--accent);
  border: 1px solid var(--accent-dim);
  border-radius: 4px;
  padding: 1px 5px;
  margin-left: 6px;
  vertical-align: 1px;
}
.collector-stats {
  display: block;
  font-size: 12px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.collector-when {
  flex: none;
  font-size: 11.5px;
  color: var(--text-dim);
}

/* ---------------- visiting someone else's collection ---------------- */

/* Every action in the header speaks about *your* collection — a deck built from
   it, a pack added to it, a file exported from it. None of them mean anything
   while the grid is showing someone else's, so they leave rather than sit there
   quietly lying about whose cards are on screen. */
body.is-viewing #btn-pack,
body.is-viewing #btn-deck,
body.is-viewing #export-wrap,
body.is-viewing #btn-import { display: none; }

.view-bar {
  padding: 14px 20px 12px;
  background: linear-gradient(180deg, rgba(200, 170, 110, .09), rgba(200, 170, 110, .02));
  border-bottom: 1px solid var(--accent-dim);
}

.view-head {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.view-who {
  margin: 0;
  flex: 1;
  min-width: 200px;
  font-size: 14px;
  color: var(--text-dim);
}
.view-who b { color: var(--text); }
.view-eye { color: var(--accent); margin-right: 4px; }
.view-when {
  margin-left: 8px;
  font-size: 12px;
  color: var(--text-dim);
  opacity: .8;
}
.view-exit { flex: none; border-color: var(--accent-dim); color: var(--accent); }

/* auto-fit rather than a fixed count: the row carries four figures without a
   price file and five with one, and neither should leave a gap. */
.view-compare {
  margin-top: 12px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
}
.vc {
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg-raise);
}
.vc-label {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--text-dim);
}
.vc-num {
  display: block;
  margin: 2px 0 1px;
  font-size: 19px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.vc-num small { font-size: 12px; font-weight: 400; color: var(--text-dim); }
/* The comparison, in the accent, because it's the half you came for. */
.vc-vs { display: block; font-size: 11.5px; color: var(--accent); }

.view-note {
  margin: 10px 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-dim);
}

/* Stands in for the two steppers, at their combined height so that opening a
   collection doesn't reshuffle the grid you were already looking at. */
.have {
  min-height: 59px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text);
}
.have b { font-size: 17px; font-variant-numeric: tabular-nums; }
.have.is-none { color: var(--text-dim); font-size: 12px; }
.have-foil {
  color: var(--text-dim);
  font-size: 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
}

/* Their wishlist star, in the corner the toggle button occupies on your own
   cards — same place, no affordance, because it isn't yours to press. */
.wish-mark {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(13, 17, 23, .75);
  color: var(--wish);
  font-size: 15px;
  line-height: 1;
}

.detail-own.is-visiting { gap: 10px; flex-direction: column; align-items: stretch; }
.detail-have {
  padding: 9px 12px;
  border: 1px solid var(--accent-dim);
  border-radius: 8px;
  background: rgba(200, 170, 110, .07);
  font-size: 13px;
  color: var(--text-dim);
}
.detail-have b { color: var(--text); }
/* Your own row is the quieter of the two — you're here to read theirs. */
.detail-have.is-mine { border-color: var(--line); background: var(--bg-raise); }
.detail-have .wish-mark {
  position: static;
  display: inline;
  width: auto;
  height: auto;
  padding: 0;
  background: none;
  border-radius: 0;
}

@media (max-width: 760px) {
  /* The label goes and the disc stays: beside the search box on a phone there's
     room for an icon and not a word, and the title attribute carries the rest. */
  .collectors-label { display: none; }
  .btn-collectors { padding: 8px 11px; }

  .view-bar { padding: 12px 12px 10px; }
  /* Three across rather than two: five figures in a two-column grid is three
     rows of bar before the first card, which is most of a phone screen. */
  .view-compare { grid-template-columns: repeat(3, 1fr); gap: 6px; margin-top: 10px; }
  .vc { padding: 6px 8px; }
  .vc-label { font-size: 9.5px; letter-spacing: .04em; }
  .vc-num { font-size: 15px; }
  .vc-vs { font-size: 10.5px; }
  .view-exit { width: 100%; text-align: center; }

  /* 100% rather than 100vw: a modal dialog is laid out against the viewport
     minus the scrollbar, while `vw` counts the scrollbar in — worth about 15px
     of the right-hand edge sliding off screen. */
  .collectors-modal,
  .import-modal,
  .decks-modal {
    width: 100%;
    max-width: 100%;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
  }
  /* The head wraps on a phone, so the paste button stops being pushed against
     the close button by an auto margin that has nothing left to push with. */
  .decks-head { flex-wrap: wrap; }
  .decks-head .btn { order: 3; margin-left: 0; width: 100%; }
  .decks-head .icon-btn { margin-left: auto; }
  .saved-deck-tools { width: 100%; }
  .saved-deck-tools .btn { flex: 1; }
  /* Three actions won't sit on one phone row, and the safe one shouldn't be the
     easiest to hit by accident — so they stack with Add on top. */
  .import-actions { flex-direction: column-reverse; }
  .import-actions .btn { width: 100%; }
}
