/* ---------------------------------------------------------------------
   HobbyOne design tokens — "Vault Violet"
   Deep violet-navy chrome (the vault) against violet-tinted paper (the
   collection itself), with one deliberately restrained signature
   accent: a rainbow-prizm foil gradient (--foil-prizm), used in exactly
   two places in the whole app - the logo's front card, and the
   autograph/memorabilia corner ribbon on a card tile. Everything else
   stays disciplined so those two moments actually stand out.

   Kept exactly as before, on purpose, NOT reinterpreted for the new
   palette: grading badges (PSA/BGS/SGC - real third-party brand colors,
   not ours to redesign), the eBay-sourced price badge's lettering, and
   green-for-gain / red-for-loss - that's universal financial
   convention, not a HobbyOne color choice, and changing it would hurt
   usability for no visual gain.

   Fonts: Bricolage Grotesque for display/headline text (the wordmark,
   card player names, big numbers), loaded via Google Fonts with
   font-display:swap - falls back to the system stack instantly if
   offline or slow, so the original "installed PWA still renders
   correctly offline" principle holds: the app is never blocked on the
   web font loading, it just looks a little more distinctive once it
   has a connection. Body text stays on the system stack entirely,
   unchanged from before - only display/headline text opts into the
   custom font.
--------------------------------------------------------------------- */
@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@600;700;800&family=Outfit:wght@700;800&display=swap');

:root {
  --cream: #F4F1FC;
  --cream-dim: #E9E2F7;
  --paper: #ffffff;
  --line: #E4DCFA;

  --forest: #7B5CFA;        /* primary accent - kept the variable name "forest" throughout the CSS/JS to avoid a much larger rename; it's violet now, not green */
  --forest-deep: #0E0B1F;   /* header/stats-bar chrome */
  --forest-soft: #161129;   /* card tiles on dark surfaces */

  --gold: #B7A6FF;          /* was warm gold, now the violet-soft accent used the same way (secondary highlight, badges) */
  --gold-soft: #F0EAFF;
  --gold-bright: #9B82FF;
  --ribbon-yellow: #FFD27F; /* kept for the favorite-banner ribbon, now sampled from the foil gradient's warm end rather than an unrelated yellow */
  --ribbon-yellow-deep: #E8A24F;

  --clay: #6b5ba0;
  --danger: #b3382a;        /* unchanged - errors/delete stay red regardless of palette */
  --ok: #3f8a5c;             /* unchanged - success stays green */
  --price: #2f6b46;          /* unchanged - gain stays green, universal financial convention */

  --psa-red: #d0202c;        /* unchanged - real third-party brand colors */
  --bgs-black: #1a1a1a;
  --sgc-navy: #1e3a6e;

  --ink: #1c1730;
  --ink-dim: #5a5470;
  --ink-faint: #948fb8;

  /* The one signature element - see the big comment above. Use as
     background: var(--foil-prizm) for a fill, exactly as-is; there's no
     "foil text" token because -webkit-background-clip:text needs the
     gradient inlined at the point of use, not through a CSS variable
     (Safari-specific limitation), so that pattern is written out
     directly wherever the gradient wordmark text appears instead. */
  --foil-prizm: linear-gradient(135deg, #7CFFCB, #7FD1FF 30%, #B98CFF 55%, #FF8CD9 75%, #FFD27F);
  /* Same colors, flatter angle - a steep diagonal compresses into mostly
     one or two colors when stretched across a short, wide bounding box
     like the word "One", since the diagonal's visible span concentrates
     around whichever colors sit at its middle for a wide-short aspect
     ratio. 90deg (straight horizontal) spreads the full range evenly
     across normal reading direction instead - use this one for
     background-clip:text on short words, --foil-prizm for shapes/icons. */
  --foil-prizm-text: linear-gradient(90deg, #7CFFCB, #7FD1FF 25%, #B98CFF 50%, #FF8CD9 75%, #FFD27F);

  --font-display: 'Bricolage Grotesque', -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-wordmark: 'Outfit', -apple-system, "Segoe UI", Roboto, sans-serif; /* the cardloadr logo/wordmark specifically - kept separate from --font-display (used broadly for player names, prices, etc.) so this brand-specific font choice doesn't silently restyle unrelated UI text */
  --font-body: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Roboto Mono", Menlo, Consolas, monospace;

  --radius-lg: 10px;
  --radius-md: 7px;
  --radius-sm: 5px;
  --shadow-card: none; /* removed per explicit request - shadows on card tiles were reading as unprofessional. See .card-tile for the thin-border replacement that keeps tiles visually defined against the background. The multi-quantity "stack" visual effect that also used shadows was later removed entirely per a separate explicit request - see the qty-badge (×N label) for how quantity is now shown instead. */
  --shadow-raised: 0 8px 24px rgba(14, 11, 31, 0.16); /* kept - this is for genuine overlay/modal depth (sheets, dialogs), a different and still-legitimate use of shadow than flat card tiles */
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
}

body { min-height: 100vh; padding-bottom: 32px; }

button { font-family: inherit; cursor: pointer; }

input, select, textarea {
  font-family: inherit;
  font-size: 16px; /* prevents iOS/Android zoom-on-focus */
}

:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

button, .card-tile, .toggle-chip, .filter-chip { transition: transform 0.1s ease, opacity 0.1s ease, background-color 0.15s ease, border-color 0.15s ease; }
button:active, .card-tile:active { transform: scale(0.97); }

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------------------------------------------------------------------
   App bar
--------------------------------------------------------------------- */
.app-bar {
  background: linear-gradient(165deg, var(--forest) 0%, var(--forest-deep) 100%);
  padding: 22px 20px 20px;
  border-radius: 0 0 26px 26px;
  box-shadow: var(--shadow-raised);
  position: relative;
}

.app-bar::after {
  content: "";
  position: absolute;
  left: 20px;
  right: 20px;
  bottom: -1px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold) 50%, transparent);
  opacity: 0.7;
}

.app-bar .wordmark {
  font-family: var(--font-wordmark);
  font-weight: 800;
  font-size: 26px;
  letter-spacing: -0.01em;
  color: #fbf8f0;
  margin: 0;
}

.app-bar .brand {
  display: flex;
  align-items: center;
  gap: 12px;
}

.app-bar .logomark {
  width: 44px;
  height: 39px;
  flex: 0 0 auto;
  filter: drop-shadow(0 3px 6px rgba(0,0,0,0.25));
}

.app-bar .wordmark span {
  background: var(--foil-prizm-text);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--gold-bright); /* fallback for browsers without background-clip:text support - still reads correctly, just solid instead of gradient */
}

.app-bar .tagline {
  font-size: 11px;
  font-weight: 600;
  color: #a9c2b6;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin-top: 2px;
}

/* ---------------------------------------------------------------------
   Top tabs
--------------------------------------------------------------------- */
.tab-row {
  display: flex;
  gap: 6px;
  max-width: 640px;
  margin: 16px auto 0;
  padding: 0 16px;
}

.tab-row button {
  background: none;
  border: none;
  padding: 10px 18px 12px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border-bottom: 3px solid transparent;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.tab-row button.active {
  color: var(--ink);
  border-bottom-color: var(--clay);
}

.tab-row button:not(.active):hover { color: var(--ink-dim); background: var(--cream-dim); }

/* ---------------------------------------------------------------------
   Tabs / panels
--------------------------------------------------------------------- */
.tab-panel { display: none; padding: 20px 16px 32px; max-width: 640px; margin: 0 auto; }
.tab-panel.active { display: block; animation: fadeUp 0.22s ease; }

/* ---------------------------------------------------------------------
   Scan tab — the "card slot"
--------------------------------------------------------------------- */
.scan-slot {
  position: relative;
  border: 2px dashed var(--line);
  border-radius: var(--radius-lg);
  padding: 44px 20px;
  text-align: center;
  background: var(--cream-dim);
  color: var(--gold);
}

.scan-slot.has-photo {
  border-style: solid;
  border-color: var(--gold);
  padding: 0;
  overflow: hidden;
  background: var(--paper);
  box-shadow: var(--shadow-card);
}

.scan-slot input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

.scan-slot .slot-icon { width: 40px; height: 40px; margin: 0 auto 12px; }
.scan-slot .slot-icon svg { width: 100%; height: 100%; }
.scan-slot .slot-title { font-weight: 700; font-size: 15px; color: var(--ink); margin-bottom: 4px; }
.scan-slot .slot-hint { font-size: 13px; color: var(--ink-dim); }

.scan-slot img.preview {
  display: block;
  width: 100%;
  max-height: 380px;
  object-fit: contain;
  background: var(--forest-deep);
}

.scan-status {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  font-size: 14px;
  color: var(--ink-dim);
  padding: 0 2px;
}

.scan-status.error { color: var(--danger); }

.spinner {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 2px solid var(--line);
  border-top-color: var(--gold);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------------
   Review / edit card
--------------------------------------------------------------------- */
.card-form {
  margin-top: 18px;
  background: var(--paper);
  color: var(--ink);
  border-radius: var(--radius-lg);
  padding: 20px 18px 22px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
}

.card-form .form-header {
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--ink-dim);
  padding-bottom: 10px;
  margin-bottom: 16px;
  border-bottom: 2px solid var(--gold-soft);
}

.card-form .ai-note {
  font-size: 12.5px;
  font-style: italic;
  color: var(--ink-dim);
  background: var(--cream-dim);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  margin: -6px 0 14px;
}

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.field-row.single { grid-template-columns: 1fr; }

.field label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
  margin-bottom: 5px;
}

.field input[type="text"],
.field input[type="number"],
.field select {
  width: 100%;
  padding: 10px 12px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--ink);
}

.field input:focus, .field select:focus {
  border-color: var(--gold);
}

.field input.mono { font-family: var(--font-mono); }

.toggle-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0; }

.toggle-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background: var(--paper);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-dim);
}

.toggle-chip input { accent-color: var(--forest); }
.toggle-chip.on { border-color: var(--forest); color: var(--forest); background: #eaf1ec; }

.grading-fields { display: none; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.grading-fields.show { display: grid; animation: fadeUp 0.15s ease; }
.numbered-fields { display: none; margin-bottom: 12px; }
.numbered-fields.show { display: block; animation: fadeUp 0.15s ease; }

.form-actions { display: flex; gap: 10px; margin-top: 18px; }

.btn {
  flex: 1;
  padding: 13px 16px;
  border-radius: 999px;
  border: none;
  font-weight: 700;
  font-size: 14px;
}

.btn-primary { background: var(--forest); color: #fbf8f0; }
.btn-primary:disabled { opacity: 0.6; }
.btn-secondary { background: transparent; color: var(--ink-dim); border: 1.5px solid var(--line); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-block { width: 100%; }

/* ---------------------------------------------------------------------
   Collection tab
--------------------------------------------------------------------- */
/* ---------------------------------------------------------------------
   Collection view toggle - switches between the default gallery grid
   (.card-grid) and a dense list view (.card-list), based on the "Pure
   data" concept from earlier design exploration - the user specifically
   picked this one to become a real, selectable view rather than stay
   a reference mockup.
--------------------------------------------------------------------- */
.collection-view-toggle {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-bottom: 12px;
}
.view-toggle-btn {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--ink-dim);
}
.view-toggle-btn svg { width: 17px; height: 17px; }
.view-toggle-btn.active {
  background: var(--forest);
  border-color: var(--forest);
  color: #fff;
}

.stats-bar { display: flex; gap: 10px; margin-bottom: 18px; }

.stats-bar .stat {
  flex: 1;
  min-width: 0;
  background: linear-gradient(165deg, var(--forest) 0%, var(--forest-deep) 100%);
  border-radius: var(--radius-md);
  padding: 14px 10px;
  text-align: center;
  box-shadow: var(--shadow-card);
}

.stats-bar .stat-value {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 21px;
  color: #fbf8f0;
  white-space: nowrap;
}

.stats-bar .stat-value--positive { color: #8fd9a8; }
.stats-bar .stat-value--negative { color: #f2a48f; }

.stats-bar .stat-change {
  font-size: 11px;
  font-weight: 700;
  margin-top: 2px;
}
.stats-bar .stat-change--up { color: #8fd9a8; }
.stats-bar .stat-change--down { color: #f2a48f; }

.stats-bar .stat-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--gold-soft);
  margin-top: 3px;
  font-weight: 600;
}

.perf-divider {
  height: 1px;
  margin: 16px 0;
  background-image: linear-gradient(to right, var(--line) 50%, transparent 50%);
  background-size: 8px 1px;
  background-repeat: repeat-x;
}

.filter-bar {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  margin-bottom: 10px;
  scrollbar-width: none;
}
.filter-bar::-webkit-scrollbar { display: none; }

.filter-chip {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background: var(--paper);
  color: var(--ink-dim);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}
.filter-chip.active { border-color: var(--forest); background: var(--forest); color: #fbf8f0; }

.filter-selects {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 4px;
}

.filter-selects select {
  width: 100%;
  padding: 9px 30px 9px 14px;
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background-color: var(--paper);
  color: var(--ink);
  font-size: 13px;
  font-weight: 500;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'><path d='M6 8l4 4 4-4' stroke='%237a7360' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
}

.empty-state { text-align: center; padding: 56px 20px; color: var(--ink-faint); }
.empty-state .icon { width: 44px; height: 44px; margin: 0 auto 12px; color: var(--ink-faint); }
.empty-state .icon svg { width: 100%; height: 100%; }

.card-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }

/* List view - dense table-row layout, an alternate to the gallery grid
   above. Same underlying card data, just laid out for scanning many
   cards quickly rather than browsing photos. */
.card-list {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.card-list-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--line);
  background: var(--cream-dim);
}
.card-list-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
  border-left: none;
  border-right: none;
  border-top: none;
  width: 100%;
  text-align: left;
  cursor: pointer;
}
.card-list-row:last-child { border-bottom: none; }
.card-list-row:active { background: var(--cream-dim); }

.card-list-thumb {
  width: 30px;
  height: 40px;
  flex-shrink: 0;
  border-radius: 3px;
  overflow: hidden;
  background: var(--cream-dim);
  border: 1px solid var(--line);
}
.card-list-thumb img { width: 100%; height: 100%; object-fit: cover; }
.card-list-thumb.placeholder { display: flex; align-items: center; justify-content: center; color: var(--ink-faint); }
.card-list-thumb.placeholder svg { width: 14px; height: 14px; }

.card-list-main { flex: 1; min-width: 0; }
.card-list-name {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  align-items: center;
  gap: 5px;
}
.card-list-name .fav-star { color: var(--ribbon-yellow-deep); font-size: 11px; flex-shrink: 0; }
.card-list-meta {
  font-size: 10.5px;
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
}

.card-list-badges { display: flex; gap: 4px; flex-shrink: 0; }

.card-list-price {
  flex-shrink: 0;
  text-align: right;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  color: var(--price);
  min-width: 56px;
}
.card-list-qty {
  flex-shrink: 0;
  font-size: 10px;
  font-weight: 700;
  color: var(--ink-faint);
  min-width: 20px;
  text-align: right;
}


.qty-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 2;
  background: rgba(20, 20, 15, 0.72);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  padding: 3px 8px;
  border-radius: 999px;
  backdrop-filter: blur(2px);
}

.card-tile {
  position: relative;
  background: var(--paper);
  color: var(--ink);
  border-radius: var(--radius-md);
  overflow: hidden;
  text-align: left;
  border: 1px solid var(--line);
  padding: 0;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-card);
}

.card-tile .tile-photo {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--cream-dim);
  display: block;
}
.card-tile img.tile-photo { opacity: 0; transition: opacity 0.35s ease; }
.card-tile img.tile-photo.loaded { opacity: 1; }

.card-tile .tile-photo.placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-faint);
}
.card-tile .tile-photo.placeholder svg { width: 34px; height: 34px; }

.card-tile .fav-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 5px 8px;
  background: linear-gradient(90deg, var(--ribbon-yellow-deep), var(--ribbon-yellow));
  color: var(--forest-deep);
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.card-tile .tile-body { padding: 9px 10px 11px; }
.card-tile .tile-player { font-weight: 700; font-size: 13px; line-height: 1.25; overflow-wrap: break-word; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; min-height: 32.5px; }
.card-tile .tile-meta { font-size: 11.5px; color: var(--ink-dim); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; min-height: 28px; }

.card-tile .tile-footer {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 6px;
  margin-top: 7px;
}

.card-tile .tile-value { font-weight: 800; font-size: 13px; color: var(--price); }

.tile-badges { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; min-height: 48px; justify-content: flex-start; }

.grade-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 3px;
  padding: 3px 7px;
  border-radius: 5px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.02em;
  line-height: 1.4;
  color: #fff;
  white-space: nowrap;
}
.grade-badge .co { font-size: 10.5px; }
.grade-badge .grade { font-size: 10.5px; }
.grade-badge.psa { background: var(--psa-red); }
.grade-badge.bgs { background: var(--bgs-black); border: 1px solid var(--gold); }
.grade-badge.sgc { background: var(--sgc-navy); }
.grade-badge.other { background: var(--forest); }

.serial-chip {
  display: inline-flex;
  align-items: baseline;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1.4;
  letter-spacing: 0.02em;
  color: var(--forest-deep);
  background: linear-gradient(135deg, var(--gold-bright), var(--gold));
  padding: 3px 7px;
  border-radius: 5px;
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(30, 20, 0, 0.2);
}

/* signature element: foil corner ribbon on special (autograph / memorabilia) cards */
.card-tile .foil-corner {
  position: absolute;
  top: 0;
  right: 0;
  width: 48px;
  height: 48px;
  clip-path: polygon(100% 0, 100% 100%, 0 0);
  background: var(--foil-prizm);
}
.card-tile .foil-corner::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  width: 12px;
  height: 12px;
  clip-path: polygon(100% 0, 100% 100%, 0 0);
  background: rgba(255,255,255,0.55);
}
.card-tile .foil-corner .mark {
  position: absolute;
  top: 4px;
  right: 4px;
  font-size: 12px;
  font-weight: 800;
  color: #1c1730;
  text-shadow: 0 1px 1px rgba(255,255,255,0.35);
}

/* ---------------------------------------------------------------------
   Edit overlay (tap a saved card)
--------------------------------------------------------------------- */
.overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 18, 14, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 28px 18px;
  z-index: 30;
}
.overlay.open { display: flex; }

.overlay .sheet {
  width: 100%;
  max-width: 380px;
  max-height: 92vh;
  overflow-y: auto;
  background: var(--cream);
  border-radius: var(--radius-lg);
  padding: 14px 16px calc(20px + env(safe-area-inset-bottom, 0px));
  box-shadow: var(--shadow-raised);
}

.sheet-handle { display: none; }

/* ---------------------------------------------------------------------
   Sheet header (edit/delete icon actions)
--------------------------------------------------------------------- */
.sheet-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}

.sheet-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}

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

.icon-btn {
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background: var(--paper);
  color: var(--ink-dim);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.icon-btn svg { width: 17px; height: 17px; }
.icon-btn:hover { border-color: var(--forest); color: var(--forest); }
.icon-btn.danger:hover { border-color: var(--danger); color: var(--danger); }

/* ---------------------------------------------------------------------
   Card detail view (view-mode inside the sheet)
--------------------------------------------------------------------- */
.detail-photo-wrap {
  margin-top: 12px;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--cream-dim);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
}

.detail-photo {
  width: 100%;
  max-height: 240px;
  object-fit: contain;
  display: block;
  background: var(--cream-dim);
}
img.detail-photo { opacity: 0; transition: opacity 0.35s ease; }
img.detail-photo.loaded { opacity: 1; }

.detail-photo.placeholder {
  aspect-ratio: 3 / 4;
  max-height: 240px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-faint);
  background: var(--cream-dim);
}
.detail-photo.placeholder svg { width: 48px; height: 48px; }

.detail-heading { margin-top: 16px; }
.detail-player { font-family: var(--font-display); font-weight: 800; font-size: 20px; color: var(--ink); }
.detail-meta { font-size: 13.5px; color: var(--ink-dim); margin-top: 3px; }

.detail-price {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 22px;
  color: var(--price);
  margin-top: 10px;
}

.detail-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }

.detail-gain {
  font-size: 13px;
  font-weight: 700;
  margin-top: 4px;
}
.detail-gain--up { color: var(--price); }
.detail-gain--down { color: var(--danger); }

.price-history-section {
  margin-top: 16px;
  padding: 14px;
  background: var(--paper);
  border-radius: var(--radius-md);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
}

.price-history-label {
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--ink-faint);
  margin-bottom: 8px;
}

.price-history-empty {
  font-size: 12.5px;
  color: var(--ink-dim);
  line-height: 1.45;
}

.price-history-chart {
  width: 100%;
  height: 80px;
  display: block;
}

.price-history-range {
  display: flex;
  justify-content: space-between;
  font-size: 10.5px;
  color: var(--ink-faint);
  margin-top: 4px;
}

.price-history-stats {
  display: flex;
  justify-content: space-around;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.price-history-stats div { text-align: center; font-weight: 700; font-size: 13px; color: var(--ink); }
.price-history-stats .label {
  display: block;
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  margin-bottom: 2px;
}

.detail-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--cream-dim);
  border: 1px solid var(--line);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-dim);
}
.detail-chip.grading { color: #fff; border: none; }
.detail-chip.grading.psa { background: var(--psa-red); }
.detail-chip.grading.bgs { background: var(--bgs-black); }
.detail-chip.grading.sgc { background: var(--sgc-navy); }
.detail-chip.grading.other { background: var(--forest); }

.detail-notes {
  margin-top: 16px;
  padding: 12px 14px;
  background: var(--paper);
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  color: var(--ink-dim);
  line-height: 1.5;
}
.detail-notes .label {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  margin-bottom: 4px;
}

/* ---------------------------------------------------------------------
   Typeahead suggestion panel
--------------------------------------------------------------------- */
.field { position: relative; }

.typeahead-panel {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 40;
  background: var(--paper);
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-raised);
  max-height: 220px;
  overflow-y: auto;
  padding: 6px;
}
.typeahead-panel.open { display: block; }

.typeahead-group-label {
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  padding: 6px 8px 4px;
}

.typeahead-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 9px;
  border: none;
  background: none;
  border-radius: 8px;
  font-size: 13.5px;
  color: var(--ink);
}
.typeahead-item:hover, .typeahead-item:active { background: var(--cream-dim); }

/* favorite icon toggle state */
.icon-btn.fav-active { border-color: var(--ribbon-yellow-deep); background: linear-gradient(135deg, var(--ribbon-yellow), var(--ribbon-yellow-deep)); color: var(--forest-deep); }
.icon-btn.fav-active:hover { border-color: var(--ribbon-yellow-deep); color: var(--forest-deep); }
.icon-btn.fav-active svg path { fill: currentColor; }

/* favorite banner inside the detail sheet view */
.detail-fav-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--ribbon-yellow-deep), var(--ribbon-yellow));
  color: var(--forest-deep);
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-top: 12px;
}

/* ---------------------------------------------------------------------
   Sold comps — a single icon button in the sheet header (see
   #comps-refresh-btn in index.html, styled via the shared .icon-btn
   rules above). Results surface through the price/badge/tooltip rather
   than a separate panel, so this needs almost no CSS of its own.
--------------------------------------------------------------------- */
.icon-btn.spinning svg { animation: spin 0.9s linear infinite; }
/* ---------------------------------------------------------------------
   eBay-sourced price badge — shown next to a price whenever it reflects
   the eBay comps average rather than a manually-typed value. Plain text,
   colored per letter, as a nominative reference to the data source - not
   a reproduction of eBay's actual logo artwork or typeface.
--------------------------------------------------------------------- */
.ebay-badge {
  display: inline-flex;
  align-items: baseline;
  vertical-align: middle;
  font-weight: 800;
}
.ebay-badge .e { color: #E53238; }
.ebay-badge .b { color: #0064D2; }
.ebay-badge .a { color: #F5AF02; }
.ebay-badge .y { color: #86B817; }

.ebay-badge--sm { margin-left: 5px; font-size: 11px; }
.ebay-badge--lg { margin-left: 7px; font-size: 14px; }

/* diagnostic detail shown under a "no results" state - low emphasis,
   but visible, so a genuinely empty search vs. a parsing problem is
   distinguishable at a glance instead of a dead end */
.comps-diagnostic {
  margin-top: 6px;
  padding: 8px 10px;
  background: var(--cream-dim);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
  line-height: 1.5;
}

/* ---------------------------------------------------------------------
   Auth screen (login/signup) — shown instead of the app shell until a
   session is confirmed
--------------------------------------------------------------------- */
.auth-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  background: var(--cream);
}

.auth-card {
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.auth-card .logomark { margin-bottom: 14px; width: 60px; height: 53px; }
.auth-card .wordmark {
  font-family: var(--font-wordmark);
  font-weight: 800;
  font-size: 26px;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}
.auth-card .wordmark span {
  background: var(--foil-prizm-text);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--gold); /* fallback for browsers without background-clip:text support */
}
.auth-subtitle { font-size: 13.5px; color: var(--ink-dim); margin: 6px 0 24px; }

.btn-google {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: 999px;
  border: 1.5px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  font-weight: 700;
  font-size: 14px;
}
.btn-google:hover { border-color: var(--ink-faint); }

.auth-divider {
  display: flex;
  align-items: center;
  width: 100%;
  margin: 18px 0;
  color: var(--ink-faint);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.auth-divider::before, .auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}
.auth-divider span { padding: 0 12px; }

#auth-form { width: 100%; text-align: left; }
#auth-form .field { margin-bottom: 12px; }
#auth-form label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
  margin-bottom: 5px;
}
#auth-form input {
  width: 100%;
  padding: 11px 12px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--paper);
  color: var(--ink);
}
#auth-form input:focus { border-color: var(--gold); }

.auth-error {
  background: #fdecea;
  color: var(--danger);
  border-radius: var(--radius-sm);
  padding: 9px 11px;
  font-size: 13px;
  margin-bottom: 12px;
  text-align: left;
}
.auth-info {
  background: var(--cream-dim);
  color: var(--ink-dim);
  border-radius: var(--radius-sm);
  padding: 9px 11px;
  font-size: 13px;
  margin-bottom: 12px;
  text-align: left;
}

.auth-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
}
.link-btn {
  background: none;
  border: none;
  color: var(--forest);
  font-size: 13px;
  font-weight: 600;
  padding: 4px;
}

.header-icon-btn {
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: 1.5px solid rgba(255,255,255,0.25);
  background: rgba(255,255,255,0.08);
  color: #e6ece9;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex: 0 0 auto;
}
.header-icon-btn svg { width: 17px; height: 17px; }
.header-icon-btn:hover { background: rgba(255,255,255,0.15); }

.app-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 640px;
  margin: 0 auto;
}
/* Only the FIRST element in the "pushed right" group gets the auto
   margin - giving every one of them their own margin-left:auto (an
   earlier mistake) splits the leftover flex space EVENLY between
   however many elements have it, landing things near the horizontal
   center of the bar instead of flush together on the right. One auto
   margin on the first element (the tier badge, when shown) pushes the
   whole group right as a unit; the small gap on .app-bar keeps them a
   natural distance apart after that. */
.header-right-group {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.tier-badge {
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  white-space: nowrap;
  border: 1px solid rgba(255,255,255,0.25);
}
.tier-badge--free { background: rgba(255,255,255,0.08); color: #d8e0da; }
.tier-badge--basic { background: rgba(120,170,255,0.18); color: #bcd4ff; border-color: rgba(120,170,255,0.4); }
.tier-badge--premium { background: rgba(217,140,61,0.2); color: var(--gold-soft); border-color: rgba(217,140,61,0.45); }
.tier-badge--platinum { background: linear-gradient(100deg, rgba(230,230,240,0.25), rgba(180,200,220,0.2)); color: #f2f4f8; border-color: rgba(230,230,240,0.5); }

/* ---------------------------------------------------------------------
   Profile screen
--------------------------------------------------------------------- */
#profile-overlay .sheet { max-height: 92vh; overflow-y: auto; }
.sheet--compact { max-width: 340px; }

.profile-avatar-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 2px 0 12px;
}

.profile-avatar-wrap { position: relative; width: 68px; height: 68px; }

.profile-avatar {
  width: 68px;
  height: 68px;
  border-radius: 999px;
  object-fit: cover;
  background: var(--cream-dim);
  border: 2px solid var(--line);
}
.profile-avatar-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-faint);
}
.profile-avatar-placeholder svg { width: 30px; height: 30px; }

.profile-avatar-edit-btn {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  background: var(--forest);
  color: #fff;
  border: 2px solid var(--cream);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.profile-avatar-edit-btn svg { width: 12px; height: 12px; }

.profile-avatar-status {
  font-size: 11px;
  color: var(--ink-faint);
  margin-top: 5px;
  min-height: 13px;
}

.profile-section {
  margin-top: 9px;
  padding-top: 9px;
  border-top: 1px dashed var(--line);
}
.profile-section:first-of-type { border-top: none; margin-top: 4px; padding-top: 0; }
.profile-section--danger { padding-bottom: 2px; }

.profile-row-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 4px;
  border: none;
  border-bottom: 1px solid var(--line);
  background: none;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  text-align: left;
}
.profile-row-btn:last-child { border-bottom: none; }
.profile-row-btn-value {
  font-weight: 500;
  color: var(--ink-faint);
  font-size: 12.5px;
}

.profile-tier-picker {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.profile-tier-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  border: 1.5px solid var(--line);
  background: var(--paper);
  cursor: pointer;
}
.profile-tier-option.active {
  border-color: var(--gold);
  background: linear-gradient(165deg, #fff8ea 0%, var(--paper) 100%);
  box-shadow: 0 0 0 1px var(--gold) inset;
}

.profile-tier-option-main { display: flex; flex-direction: column; }
.profile-tier-option-name { font-weight: 800; font-size: 12.5px; color: var(--ink); }
.profile-tier-option-detail { font-size: 10px; color: var(--ink-dim); margin-top: 1px; }
.profile-tier-option-price { font-weight: 700; font-size: 11.5px; color: var(--forest); white-space: nowrap; }

.profile-tier-note {
  font-size: 10.5px;
  color: var(--ink-faint);
  margin-top: 6px;
  text-align: center;
}

/* ---------------------------------------------------------------------
   Free-tier upgrade banner - discreet, not a loud ad unit
--------------------------------------------------------------------- */
.upgrade-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 14px;
  border-radius: var(--radius-md);
  background: linear-gradient(100deg, #F3EEFF 0%, #EBE1FF 100%);
  border: 1px solid #D8C4FF;
}

.upgrade-banner-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.upgrade-banner-text strong {
  font-size: 12.5px;
  font-weight: 800;
  color: #4A2E8A;
  line-height: 1.3;
}
.upgrade-banner-text span {
  font-size: 11px;
  color: #6b5ba0;
  margin-top: 1px;
}

.upgrade-banner-btn {
  flex: 0 0 auto;
  padding: 7px 14px;
  border-radius: 999px;
  border: 1.5px solid var(--forest);
  background: var(--paper);
  color: #4A2E8A;
  font-size: 11.5px;
  font-weight: 800;
  white-space: nowrap;
}

.stat-count-limit {
  font-size: 13px;
  font-weight: 600;
  color: var(--gold-soft);
  opacity: 0.85;
}

/* ---------------------------------------------------------------------
   Locked-feature golden badge (comps button on a free-tier account)
--------------------------------------------------------------------- */
.icon-btn.locked { position: relative; }
.icon-btn.locked::after {
  content: "";
  position: absolute;
  top: -3px;
  right: -3px;
  width: 15px;
  height: 15px;
  border-radius: 999px;
  background: var(--gold);
  border: 2px solid var(--cream);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M7 10V7a5 5 0 0 1 10 0v3M6 10h12a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1Z' stroke='%23fff' stroke-width='2.4' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-size: 9px 9px;
  background-repeat: no-repeat;
  background-position: center;
}

/* ---------------------------------------------------------------------
   Bulk import
--------------------------------------------------------------------- */
.bulk-import-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 10px;
  padding: 11px 14px;
  border-radius: var(--radius-md);
  border: 1.5px dashed var(--line);
  background: var(--paper);
  color: var(--ink-dim);
  font-size: 13px;
  font-weight: 700;
}
.bulk-import-btn svg { width: 16px; height: 16px; }

.bulk-camera-overlay {
  position: fixed;
  inset: 0;
  background: #000;
  z-index: 50;
  display: flex;
  flex-direction: column;
}

/* Fixed-ratio video stage - the core of a more robust fix than reactive
   orientation-correction: rather than stretching the video to fill
   whatever shape the screen happens to be (which is what made every
   previous fix dependent on correctly guessing the stream's actual
   delivered orientation, itself an unreliable cross-browser/cross-
   device thing - confirmed via real Firefox/WebKit bug reports of the
   exact same instability going back over a decade), the video always
   renders into a CONTAINER with a fixed, known 3:4 portrait aspect
   ratio (matching a real trading card's proportions). object-fit:cover
   still crops a little on whichever axis doesn't perfectly match, but
   that's now a small, predictable, completely ordinary crop - not a
   wild ~65%-style crop from a genuine orientation mismatch. */
.camera-stage {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #000;
}
.camera-stage-inner {
  position: relative;
  width: 100%;
  max-width: 480px;
  aspect-ratio: 3 / 4;
  max-height: 100%;
  overflow: hidden;
  border-radius: 6px;
}
#bulk-camera-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}

/* The auto-capture overlay's internal layout is entirely absolutely-
   positioned (guide frame, identify overlay, topbar) on top of the
   fixed-ratio .camera-stage-inner box above, rather than a flex column
   like the bulk-import camera. */
#auto-camera-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000;
}

.bulk-camera-error {
  position: absolute;
  top: 50%;
  left: 20px;
  right: 20px;
  z-index: 10;
  transform: translateY(-50%);
  background: rgba(20, 20, 15, 0.9);
  color: #fff;
  padding: 16px;
  border-radius: var(--radius-md);
  font-size: 13.5px;
  text-align: center;
  line-height: 1.5;
}

.bulk-camera-topbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(14px + env(safe-area-inset-top, 0px)) 14px 14px;
  background: linear-gradient(rgba(0,0,0,0.55), transparent);
}

.bulk-camera-icon-btn {
  width: 38px;
  height: 38px;
  border-radius: 999px;
  background: rgba(255,255,255,0.15);
  color: #fff;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.bulk-camera-icon-btn svg { width: 18px; height: 18px; }

.bulk-camera-count {
  color: #fff;
  font-weight: 700;
  font-size: 13.5px;
  background: rgba(0,0,0,0.35);
  padding: 6px 12px;
  border-radius: 999px;
}

.bulk-camera-filmstrip {
  position: absolute;
  bottom: 118px;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  gap: 8px;
  padding: 0 14px;
  overflow-x: auto;
}
.bulk-camera-filmstrip img {
  width: 48px;
  height: 64px;
  object-fit: cover;
  border-radius: 8px;
  border: 2px solid rgba(255,255,255,0.6);
  flex: 0 0 auto;
}

.bulk-camera-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 20px 20px calc(28px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(transparent, rgba(0,0,0,0.55));
}

.bulk-camera-shutter-btn {
  width: 68px;
  height: 68px;
  border-radius: 999px;
  background: rgba(255,255,255,0.15);
  border: 3px solid #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.bulk-camera-shutter-btn span {
  width: 54px;
  height: 54px;
  border-radius: 999px;
  background: #fff;
}
.bulk-camera-shutter-btn:active span { background: var(--gold); }

/* ---------------------------------------------------------------------
   Auto-capture camera
--------------------------------------------------------------------- */
.auto-camera-hint {
  color: #fff;
  font-weight: 700;
  font-size: 13.5px;
  background: rgba(0,0,0,0.4);
  padding: 8px 16px;
  border-radius: 999px;
  margin: 0 auto;
}

/* Card-shaped guide frame, centered in the viewport. A standard trading
   card is ~2.5:3.5 (5:7) - the frame uses that ratio so what the user
   sees lines up with what the detection heuristic actually analyzes
   (see AUTO_CAPTURE_ANALYSIS_SIZE in app.js, same aspect ratio). */
.auto-camera-guide {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 88%;
  aspect-ratio: 5 / 7;
  cursor: pointer;
}
/* Dims everything outside the guide frame - moved to its own pseudo-
   element since the box-shadow-based dimming trick needs a plain
   bordered box, which the SVG guide (below) no longer is. */
.auto-camera-guide::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 6px;
  box-shadow: 0 0 0 2000px rgba(0,0,0,0.35);
  pointer-events: none;
}

.auto-camera-guide-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
/* The progress rect's stroke-dasharray/dashoffset are set entirely via
   JS (computed from the SVG rect's own real perimeter at runtime, see
   initGuideProgressRing in app.js) - CSS only handles the smooth
   transition between values, not the values themselves. */
#auto-camera-guide-progress,
#bulk-camera-guide-progress {
  transition: stroke-dashoffset 0.1s linear;
  filter: drop-shadow(0 0 6px rgba(52,211,153,0.7));
}

.auto-camera-frozen-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 5; /* above the (now-stopped) video and the guide frame */
}

.auto-camera-identify-overlay {
  position: absolute;
  inset: 0;
  z-index: 6;
  background: rgba(14, 11, 31, 0.72);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
}

.identify-fan {
  position: relative;
  width: 90px;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.identify-card {
  position: absolute;
  filter: drop-shadow(0 3px 8px rgba(0,0,0,0.35));
}

/* Each card animates from a tight pile (centered, no offset, no
   rotation) out to its fanned position and back, looping continuously.
   The three use the SAME keyframe shape but different transform end
   points and slightly staggered delays, so they visibly separate like
   spreading cards in your hand rather than all moving identically. */
.identify-card--1 { animation: identify-fan-1 1.8s ease-in-out infinite; }
.identify-card--2 { animation: identify-fan-2 1.8s ease-in-out infinite; animation-delay: 0.06s; }
.identify-card--3 { animation: identify-fan-3 1.8s ease-in-out infinite; animation-delay: 0.12s; }

@keyframes identify-fan-1 {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  45%, 65% { transform: translate(-22px, 4px) rotate(-16deg); }
}
@keyframes identify-fan-2 {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  45%, 65% { transform: translate(0, -6px) rotate(0deg); }
}
@keyframes identify-fan-3 {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  45%, 65% { transform: translate(22px, 4px) rotate(16deg); }
}

.auto-camera-identify-text {
  color: #fff;
  font-weight: 700;
  font-size: 14.5px;
}

.bulk-capture-flash {
  position: absolute;
  inset: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
  z-index: 4;
}
.bulk-capture-flash.flash-active {
  animation: bulk-capture-flash-anim 0.25s ease-out;
}
@keyframes bulk-capture-flash-anim {
  0% { opacity: 0.7; }
  100% { opacity: 0; }
}

.scan-slot-trigger {
  width: 100%;
  border: none;
  background: none;
  padding: 0;
  display: block;
  text-align: inherit;
}

.bulk-progress-banner {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 14px;
  margin-bottom: 12px;
  border-radius: var(--radius-md);
  background: var(--forest);
  color: #fff;
  font-size: 12.5px;
  font-weight: 700;
}
.bulk-progress-banner .link-btn { color: var(--gold-soft); font-weight: 800; }
