/* =====================================================================
   ARBITRAGE OBSIDIAN — design system (Midnight Amber palette)
   =====================================================================
   Every selector name below is unchanged from the previous stylesheet —
   ~130 PHP templates reference these classes directly, so the token
   system is applied *underneath* the existing contract rather than by
   renaming anything. New utility classes (.num, .badge-solid, the
   theme toggle, the Bento/Panel dashboard system) are additive;
   nothing already in use had to change to pick up the new system.

   System goals: every pixel serves a function, zero decorative
   elements, low visual fatigue over long sessions, instant scannability
   via consistent alignment. This is a trading terminal, not a
   marketing page — judged first on "can I read profit/loss fast."
   ===================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600;700;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap');

/* ---------------------------------------------------------------------
   TOKENS — dark is the default (:root), light overrides via
   [data-theme="light"] on <html>. Nothing below this block should ever
   reference a raw hex color again — everything reads from these.

   Palette: "Midnight Amber" — warm near-black surfaces with a single
   amber/gold accent carrying primary + pending (a pending item is a
   "not-yet-decided" state, visually related to the brand accent rather
   than a distinct hue), green for gains, warm red for losses.
   --------------------------------------------------------------------- */
:root {
    /* Surfaces */
    --bg-main: #14110F;
    --bg-elevated: #1E1A16;
    --bg-zebra: #211C18;
    --bg-hover: #2C251E;
    --bg-input: #14110F;

    /* Text */
    --text-primary: #F5EFE6;
    --text-secondary: #A99C8C;
    --text-tertiary: #786B5C;

    /* Structure */
    --border-subtle: #3A322A;
    --radius: 8px;
    --radius-lg: 12px;
    --radius-pill: 20px;

    /* Semantic color — same four roles in both themes, different
       exact hue so each stays correctly balanced against its background */
    --color-primary: #E0A458;
    --color-success: #7EC488;
    --color-alert: #E2664F;
    --color-pending: #E0A458;

    /* Tinted backgrounds derived from the semantic colors — used for
       chip active-fill, flash messages, badge outlines. Computed, not
       hand-picked, so dark/light stay in sync automatically. */
    --color-primary-tint: color-mix(in srgb, var(--color-primary) 16%, transparent);
    --color-success-tint: color-mix(in srgb, var(--color-success) 16%, transparent);
    --color-alert-tint: color-mix(in srgb, var(--color-alert) 16%, transparent);
    --color-pending-tint: color-mix(in srgb, var(--color-pending) 16%, transparent);

    /* Typography — display face for headings/labels (identity), sans
       for body/UI text, mono+tabular-nums for anything numeric. */
    --font-display: 'Space Grotesk', 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

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

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

    --border-subtle: #E4D9C7;

    --color-primary: #B5762A;
    --color-success: #3E8B54;
    --color-alert: #C1503B;
    --color-pending: #B5762A;
}

/* ---------------------------------------------------------------------
   BASE
   --------------------------------------------------------------------- */
* { box-sizing: border-box; }

body {
    font-family: var(--font-sans);
    background: var(--bg-main);
    color: var(--text-primary);
    margin: 0;
    padding: 0;
    -webkit-font-smoothing: antialiased;
    transition: background 0.15s, color 0.15s;
}

/* Numeric data utility — apply to any element whose content is a
   number (price, percentage, count). Monospace + tabular-nums forces
   digit widths to align in columns, which is the whole point of a
   scannable numbers table: your eye can compare magnitude by column
   position, not just by reading each value individually. */
.num {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

header {
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--border-subtle);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

header h1 {
    font-family: var(--font-display);
    font-size: 1.25rem;
    margin: 0;
    font-weight: 700;
    letter-spacing: -0.01em;
}

/* Base nav rules — still used by the admin chrome, which has a short
   enough menu to sit on one line without grouping. */
nav a {
    color: var(--text-secondary);
    text-decoration: none;
    margin-left: 1rem;
    padding: 0.35rem 0.75rem;
    border-radius: 6px;
    font-size: 0.9rem;
}

nav a.active, nav a:hover {
    color: var(--color-primary);
    background: var(--bg-hover);
}

main {
    padding: 1.5rem;
    max-width: 1000px;
    margin: 0 auto;
}

/* Bento / dashboard pages need more horizontal room than a reading
   column. Opt in with <main class="wide">. */
main.wide {
    max-width: 1200px;
}

/* ---------------------------------------------------------------------
   SITE HEADER + GROUPED PRIMARY NAV (public pages)
   ---------------------------------------------------------------------
   The public side has ~19 destinations. A single flat row of links wrapped
   into an unreadable slab and, worse, each page had drifted to its own
   hand-maintained subset of the links. This nav is defined once in
   _page_header.php and grouped by intent, so it stays scannable at any
   width and every page shows the same thing.
   --------------------------------------------------------------------- */
.site-header {
    padding: 1rem 1.5rem 0.85rem;
    border-bottom: none;
}

.brand {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.brand-mark {
    font-family: var(--font-display);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--color-primary);
}

.site-header h1 {
    font-size: 1.4rem;
    line-height: 1.15;
}

.mainnav {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.35rem 1.5rem;
    padding: 0 1.5rem 0.9rem;
    border-bottom: 1px solid var(--border-subtle);
    margin-bottom: 0.25rem;
}

.nav-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.15rem;
}

.nav-group-label {
    font-family: var(--font-display);
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-tertiary);
    margin-right: 0.35rem;
    white-space: nowrap;
}

.mainnav a {
    color: var(--text-secondary);
    text-decoration: none;
    margin-left: 0;
    padding: 0.25rem 0.55rem;
    border-radius: 6px;
    font-size: 0.8rem;
    white-space: nowrap;
}

.mainnav a:hover {
    color: var(--text-primary);
    background: var(--bg-hover);
}

.mainnav a.active {
    color: var(--color-primary);
    background: var(--color-primary-tint);
    font-weight: 600;
}

.empty-state {
    color: var(--text-secondary);
    text-align: center;
    padding: 3rem 1rem;
}

/* ---------------------------------------------------------------------
   DATA TABLES — left-align identity columns, right-align every
   numeric column (apply .num to the <td>), zebra striping mandatory,
   tight 8px/12px padding per spec.
   --------------------------------------------------------------------- */
.deals-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.deals-table th {
    text-align: left;
    color: var(--text-secondary);
    font-weight: 500;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border-subtle);
}

/* Right-align numeric column headers automatically when the header
   itself carries .num, so header and cell alignment always match
   without having to remember to align both independently. */
.deals-table th.num {
    text-align: right;
}

.deals-table td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--border-subtle);
    overflow-wrap: break-word;
    word-break: break-word;
}

.deals-table td.num {
    text-align: right;
}

/* Zebra striping — mandatory per spec. Skips row-best (the highlighted
   "this is the top result" row) so that row's own highlight isn't
   fought by the stripe. */
.deals-table tbody tr:nth-child(even):not(.row-best) {
    background: var(--bg-zebra);
}

.deals-table .set {
    display: block;
    color: var(--text-tertiary);
    font-size: 0.78rem;
    overflow-wrap: break-word;
    word-break: break-word;
}

/* Magnitude styling: color signals direction, weight signals size —
   the two are independent per spec, so a reader glancing at boldness
   alone (colorblind-safe) still gets the "this one's big" signal. */
.positive { color: var(--color-success); font-weight: 700; }
.negative { color: var(--color-alert); font-weight: 700; }
.margin { color: var(--color-success); font-weight: 700; }

.deals-table a {
    color: var(--color-primary);
    text-decoration: none;
    font-size: 0.85rem;
}

.row-best { background: var(--color-success-tint); }

/* ---------------------------------------------------------------------
   FORMS
   --------------------------------------------------------------------- */
.add-form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
    background: var(--bg-elevated);
    padding: 1rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-subtle);
}

.add-form input, .add-form select {
    background: var(--bg-input);
    border: 1px solid var(--border-subtle);
    color: var(--text-primary);
    padding: 0.5rem 0.65rem;
    border-radius: 6px;
    font-size: 0.85rem;
    font-family: var(--font-sans);
}

.add-form button {
    background: var(--color-primary);
    border: none;
    color: var(--bg-main);
    font-weight: 700;
    padding: 0.5rem 1rem;
    border-radius: 6px;
    cursor: pointer;
}

.flash {
    background: var(--color-success-tint);
    color: var(--color-success);
    padding: 0.6rem 1rem;
    border-radius: var(--radius);
    margin-bottom: 1rem;
    font-size: 0.9rem;
    border: 1px solid var(--color-success);
}

/* ---------------------------------------------------------------------
   SET BROWSER
   --------------------------------------------------------------------- */
.set-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.75rem;
}

.set-card {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: 0.85rem;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s;
}

.set-card:hover {
    border-color: var(--color-primary);
}

.set-symbol {
    width: 32px;
    height: 32px;
    object-fit: contain;
    flex-shrink: 0;
}

.set-name {
    font-weight: 600;
    font-size: 0.95rem;
}

.set-meta {
    color: var(--text-secondary);
    font-size: 0.78rem;
    margin-top: 0.15rem;
}

.set-subtitle {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin-bottom: 1rem;
}

.set-subtitle a {
    color: var(--color-primary);
    text-decoration: none;
}

/* ---------------------------------------------------------------------
   CARD CHECKLIST GRID
   --------------------------------------------------------------------- */
.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 0.75rem;
}

.card-tile {
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
}

.card-tile.status-want { border-color: var(--color-pending); }
.card-tile.status-watching { border-color: var(--color-primary); }
.card-tile.status-owned { border-color: var(--color-success); }

.card-tile-body {
    padding: 0.6rem;
}

.card-tile-name {
    font-weight: 600;
    font-size: 0.85rem;
    line-height: 1.2;
    overflow-wrap: break-word;
    word-break: break-word;
}

.card-tile-name a {
    color: inherit;
    text-decoration: none;
}

.card-tile-name a:hover {
    color: var(--color-success);
}

.card-tile-meta {
    color: var(--text-secondary);
    font-size: 0.72rem;
    margin: 0.15rem 0 0.5rem;
}

.card-tile-set {
    display: block;
    color: var(--text-tertiary);
    font-size: 0.68rem;
    margin-top: 0.1rem;
}

/* Watchlist indicator — a ring, not a shadow. Per spec: flat design,
   no drop shadows. This is a 1px functional outline (border-based),
   not decorative elevation. */
.card-tile.is-watched {
    border-color: var(--color-success);
    outline: 1px solid var(--color-success);
    outline-offset: -1px;
}

/* Reserves the image's footprint at a fixed trading-card aspect ratio
   (5:7) whether or not an image ever loads. Without this, a card with
   no image_small (very common for sports cards — image enrichment
   lags well behind Pokemon/TCG imports) collapsed this box to zero
   height, and the absolutely-positioned watchlist checkbox — meant to
   float over the image — landed directly on top of the card name text
   below it instead. That was the "card fronts are overlapping" bug.
   The onerror handler on the <img> (see set.php/search.php) adds
   .no-image for a broken URL too, so a 404 gets the same treatment as
   a genuinely missing one. */
.card-tile-img {
    display: block;
    position: relative;
    aspect-ratio: 5 / 7;
    background: var(--bg-main);
    border-bottom: 1px solid var(--border-subtle);
    overflow: hidden;
}

.card-tile-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.card-tile-img.no-image {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0.5rem;
    color: var(--text-tertiary);
    font-size: 0.68rem;
    line-height: 1.3;
}

.card-check-wrap {
    position: absolute;
    top: 6px;
    left: 6px;
    z-index: 3;
    background: color-mix(in srgb, var(--bg-main) 85%, transparent);
    border-radius: 5px;
    padding: 3px 4px;
    line-height: 0;
    cursor: pointer;
}

.card-check {
    width: 17px;
    height: 17px;
    accent-color: var(--color-success);
    cursor: pointer;
    margin: 0;
}

.search-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-bottom: 0.5rem;
}

.search-links a {
    font-size: 0.7rem;
    color: var(--color-primary);
    background: var(--bg-input);
    border: 1px solid var(--border-subtle);
    padding: 0.2rem 0.45rem;
    border-radius: 5px;
    text-decoration: none;
}

.status-form select {
    width: 100%;
    background: var(--bg-input);
    border: 1px solid var(--border-subtle);
    color: var(--text-primary);
    padding: 0.3rem;
    border-radius: 6px;
    font-size: 0.75rem;
    font-family: var(--font-sans);
}

.history-chart {
    width: 100%;
    height: 200px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    margin-bottom: 1rem;
}

/* ---------------------------------------------------------------------
   STAT CARDS — flat, 1px border, no shadow. Layout is fixed per spec:
   Label (secondary, small caps, display face) / Huge Number (monospace,
   primary, heavy weight) / Delta (semantic color, weight signals
   magnitude).
   --------------------------------------------------------------------- */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}

.stat-card {
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: 1rem;
}

.stat-label {
    color: var(--text-secondary);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
    font-family: var(--font-display);
}

.stat-value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 1.5rem;
    font-weight: 700;
    margin-top: 0.35rem;
    overflow-wrap: break-word;
    color: var(--text-primary);
}

.stat-note {
    color: var(--text-tertiary);
    font-size: 0.72rem;
    margin-top: 0.35rem;
    line-height: 1.35;
}

.warning-note {
    background: var(--color-pending-tint);
    color: var(--color-pending);
    border: 1px solid var(--color-pending);
    padding: 0.75rem 1rem;
    border-radius: var(--radius);
    font-size: 0.85rem;
    margin-bottom: 1.5rem;
}

.collapsible {
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: 0.85rem 1rem;
    margin-bottom: 1rem;
}

.collapsible summary {
    cursor: pointer;
    font-weight: 600;
    font-size: 0.9rem;
}

.collapsible .add-form {
    margin-top: 0.85rem;
    margin-bottom: 0;
    background: transparent;
    border: none;
    padding: 0;
}

main h2 {
    font-family: var(--font-display);
    font-size: 1.05rem;
    margin: 1.75rem 0 0.75rem;
    font-weight: 600;
}

main h3 {
    font-family: var(--font-display);
    font-size: 0.95rem;
    margin: 1.5rem 0 0.6rem;
    color: var(--text-primary);
    font-weight: 600;
}

code {
    background: var(--bg-input);
    border: 1px solid var(--border-subtle);
    padding: 0.1rem 0.35rem;
    border-radius: 4px;
    font-size: 0.85em;
    font-family: var(--font-mono);
}

/* ---------------------------------------------------------------------
   SCAN / REFRESH CONTROLS
   --------------------------------------------------------------------- */
.scan-bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.scan-btn {
    background: var(--color-primary);
    color: var(--bg-main);
    border: none;
    font-weight: 700;
    font-size: 0.85rem;
    padding: 0.5rem 1rem;
    border-radius: 6px;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
}

.scan-btn:disabled {
    background: var(--bg-hover);
    color: var(--text-secondary);
    cursor: default;
}

.scan-hint {
    color: var(--text-tertiary);
    font-size: 0.75rem;
    max-width: 42ch;
    line-height: 1.35;
}

.scan-panel {
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: 0.9rem 1rem;
    margin-bottom: 1.25rem;
}

.scan-progress {
    height: 6px;
    background: var(--bg-main);
    border-radius: 3px;
    overflow: hidden;
    margin-bottom: 0.6rem;
}

.scan-progress-fill {
    height: 100%;
    width: 0%;
    background: var(--color-primary);
    transition: width 0.3s ease;
}

.scan-status {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.85rem;
    font-weight: 500;
}

.scan-cancel {
    background: transparent;
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    font-size: 0.72rem;
    padding: 0.2rem 0.6rem;
    border-radius: 5px;
    cursor: pointer;
}

.scan-detail {
    color: var(--text-tertiary);
    font-size: 0.75rem;
    margin-top: 0.35rem;
    min-height: 1em;
}

/* ---------------------------------------------------------------------
   CARD DETAIL
   --------------------------------------------------------------------- */
.card-detail {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 1.5rem;
    align-items: start;
}

@media (max-width: 720px) {
    .card-detail { grid-template-columns: 1fr; }
}

.card-detail-image img {
    width: 100%;
    border-radius: var(--radius-lg);
    background: var(--bg-main);
    display: block;
}

/* ---------------------------------------------------------------------
   BADGES — solid+white text for critical statuses (grade labels like
   "PSA 10"), subtle 1px outline for generic tags (watching/owned).
   Existing templates use .badge-owned/.badge-want as generic tags
   already, which now render outlined per spec. .badge-solid is new —
   apply alongside a semantic modifier for grade/critical labels.
   --------------------------------------------------------------------- */
.badge {
    display: inline-block;
    font-size: 0.62rem;
    font-weight: 600;
    padding: 1px 5px;
    border-radius: 4px;
    margin-left: 3px;
    vertical-align: middle;
    border: 1px solid transparent;
}

/* Generic tags — outlined, transparent background */
.badge-owned { background: transparent; color: var(--color-success); border-color: var(--color-success); }
.badge-want  { background: transparent; color: var(--color-pending); border-color: var(--color-pending); }

/* Critical statuses (grade labels, PSA 10, etc.) — solid fill, always
   white text regardless of theme, since these need to read instantly
   as "this one matters" against either light or dark surfaces. */
.badge-solid { color: #FFFFFF; border-color: transparent; }
.badge-solid.badge-success { background: var(--color-success); }
.badge-solid.badge-alert { background: var(--color-alert); }
.badge-solid.badge-pending { background: var(--color-pending); }
.badge-solid.badge-primary { background: var(--color-primary); }

/* ---------------------------------------------------------------------
   FILTER CHIPS — pill-shaped. Active state: primary color border +
   text + 20% opacity background fill, per spec.
   --------------------------------------------------------------------- */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    margin-bottom: 1rem;
}

.filter-label {
    color: var(--text-tertiary);
    font-size: 0.75rem;
    margin-right: 0.15rem;
}

.chip {
    font-size: 0.75rem;
    color: var(--text-secondary);
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    padding: 0.22rem 0.55rem;
    border-radius: var(--radius-pill);
    text-decoration: none;
    white-space: nowrap;
    display: inline-block;
}
.chip:hover { border-color: var(--color-primary); color: var(--text-primary); }
.chip-on {
    background: color-mix(in srgb, var(--color-primary) 20%, transparent);
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.chip-n { opacity: 0.55; margin-left: 2px; }

/* ---------------------------------------------------------------------
   SELECTION TOOLBAR
   --------------------------------------------------------------------- */
.select-bar {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius);
    padding: 0.55rem 0.85rem;
    margin-bottom: 1rem;
    position: sticky;
    top: 0;
    z-index: 5;
}

.select-all {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
    color: var(--text-secondary);
    cursor: pointer;
}
.select-all input { accent-color: var(--color-success); width: 16px; height: 16px; }

.bulk-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.bulk-count {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 0.78rem;
    color: var(--color-success);
    font-weight: 700;
}

.chip-btn {
    font-size: 0.74rem;
    background: var(--bg-input);
    border: 1px solid var(--border-subtle);
    color: var(--text-primary);
    padding: 0.25rem 0.6rem;
    border-radius: 6px;
    cursor: pointer;
}
.chip-btn:hover { border-color: var(--color-success); color: var(--color-success); }
.chip-btn-danger:hover { border-color: var(--color-alert); color: var(--color-alert); }

/* ---------------------------------------------------------------------
   DESTRUCTIVE ACTIONS + INLINE UTILITIES
   ---------------------------------------------------------------------
   Several admin pages had these baked in as inline hex — background:#c33
   on delete buttons, color:#7aa2f7 on "Edit" toggles, color:#8b93a1 on
   confirm labels. Hardcoded hex ignores the theme entirely, so those
   elements stayed dark-theme colored on a light background (and vice
   versa). Same visuals, but reading from tokens so both themes work.
   --------------------------------------------------------------------- */
.btn-danger {
    background: var(--color-alert);
    color: #FFFFFF;
    border: none;
    font-weight: 600;
    padding: 0.4rem 0.85rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.8rem;
    font-family: var(--font-sans);
}
.btn-danger:hover { filter: brightness(1.08); }

/* Inline confirm/consent label sitting beside a destructive button. */
.confirm-label {
    font-size: 0.8rem;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

/* A <summary> that should read as a link rather than a heading —
   used for the per-row "Edit" disclosure in the admin card table. */
.summary-link {
    cursor: pointer;
    font-size: 0.8rem;
    color: var(--color-primary);
}
.summary-link:hover { text-decoration: underline; }

/* ---------------------------------------------------------------------
   LOGIN
   ---------------------------------------------------------------------
   Standalone page — no site nav, since you can't navigate anywhere until
   you're through it. Centred card rather than the full-width app shell.
   --------------------------------------------------------------------- */
.login-shell {
    max-width: 400px;
    margin: 0 auto;
    min-height: 100vh;
    display: flex;
    align-items: center;
    padding: 2rem 1.25rem;
}

.login-card {
    width: 100%;
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: 1.75rem 1.5rem;
}

.login-card .brand-mark {
    display: block;
    margin-bottom: 0.5rem;
}

.login-card h1 {
    font-family: var(--font-display);
    font-size: 1.3rem;
    margin: 0 0 1.25rem;
    font-weight: 700;
}

/* Stack the fields; each one full width. Overrides .add-form's row
   layout without needing per-input inline styles. */
.login-form {
    flex-direction: column;
    align-items: stretch;
    background: transparent;
    border: none;
    padding: 0;
    margin-bottom: 0;
}
.login-form input,
.login-form button { width: 100%; }

.totp-input {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 1.3rem;
    letter-spacing: 0.3em;
    text-align: center;
}

/* Set name under a Quick Add autocomplete suggestion. Lives here rather
   than as an inline style because the markup is built inside a JS
   template literal — the hardcoded hex it used to carry ignored the
   theme and stayed dark-grey on the light background. */
.qa-suggestion-set {
    color: var(--text-secondary);
    font-size: 0.82rem;
}

/* A secret / key shown for manual entry — monospace and loosely tracked
   so characters are unambiguous when typing them into another app. */
.secret-value {
    font-size: 1rem;
    font-family: var(--font-mono);
    letter-spacing: 0.1em;
    word-break: break-all;
}

/* Long URI displayed for copy/paste — must wrap or it blows out the
   page width on mobile. */
.uri-block {
    word-break: break-all;
    font-size: 0.75rem;
    display: inline-block;
    max-width: 100%;
}

/* Row of controls that should sit inline with a small gap. */
.inline-form {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 0.75rem;
}

/* ---------------------------------------------------------------------
   RARITY BULK GRID
   --------------------------------------------------------------------- */
.rarity-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 0.35rem;
    margin-top: 0.75rem;
}

.rarity-opt {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
    background: var(--bg-input);
    border: 1px solid var(--border-subtle);
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
    cursor: pointer;
}
.rarity-opt input { accent-color: var(--color-success); }
.rarity-opt span:first-of-type { flex: 1; }
.rarity-count {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--text-tertiary);
    font-size: 0.72rem;
}

#rarityStatus {
    background: var(--bg-input);
    border: 1px solid var(--border-subtle);
    color: var(--text-primary);
    padding: 0.45rem 0.6rem;
    border-radius: 6px;
    font-size: 0.82rem;
}

/* ---------------------------------------------------------------------
   TOAST
   --------------------------------------------------------------------- */
.toast {
    position: fixed;
    bottom: 18px;
    left: 50%;
    transform: translateX(-50%) translateY(20px);
    background: var(--bg-elevated);
    color: var(--color-success);
    border: 1px solid var(--color-success);
    padding: 0.55rem 1.1rem;
    border-radius: var(--radius);
    font-size: 0.82rem;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s, transform 0.2s;
    z-index: 50;
}
.toast-show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast-error { color: var(--color-alert); border-color: var(--color-alert); }

/* ---------------------------------------------------------------------
   CLICKABLE PRICES / VERIFICATION LINKS
   --------------------------------------------------------------------- */
.price-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dotted currentColor;
    padding-bottom: 1px;
}
.price-link:hover {
    color: var(--color-primary);
    border-bottom-style: solid;
}

.no-data {
    color: var(--text-tertiary);
    cursor: help;
}

.verify-links {
    white-space: nowrap;
}
.verify-links a {
    font-size: 0.68rem;
    color: var(--color-primary);
    background: var(--bg-input);
    border: 1px solid var(--border-subtle);
    padding: 0.14rem 0.4rem;
    border-radius: 4px;
    text-decoration: none;
    margin-right: 0.2rem;
}
.verify-links a:hover { border-color: var(--color-primary); }

/* ---------------------------------------------------------------------
   THEME TOGGLE — small button, no external dependency. Add
   <button id="themeToggle" class="theme-toggle">Theme</button>
   anywhere in a page's <nav>, then include assets/theme.js once
   before </body>. Defaults to dark; respects a saved choice.
   --------------------------------------------------------------------- */
.theme-toggle {
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    color: var(--text-secondary);
    font-size: 0.75rem;
    padding: 0.3rem 0.65rem;
    border-radius: var(--radius-pill);
    cursor: pointer;
    margin-left: 1rem;
}
.theme-toggle:hover { border-color: var(--color-primary); color: var(--text-primary); }

/* ---------------------------------------------------------------------
   BENTO / PANEL DASHBOARD SYSTEM — "Terminal Grid" layout. Opt-in:
   wrap a set of .panel elements in a .bento container and size each
   with a .span-N (out of 12 columns) to lay a dashboard out as
   several independent at-a-glance panels rather than one long
   scrolling column. Built for dashboard.php / index.php-style
   overview pages; anything already using .stat-grid / .deals-table
   works unchanged and doesn't need this.

   <div class="bento">
     <div class="panel span-3"><div class="panel-body">...</div></div>
     <div class="panel span-8">
       <div class="panel-head">
         <div class="panel-title"><span class="dot"></span>Title</div>
         <div class="panel-sub">context</div>
       </div>
       <div class="panel-body">...</div>
     </div>
   </div>
   --------------------------------------------------------------------- */
.bento {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 0.75rem;
    grid-auto-rows: min-content;
    margin-bottom: 1.5rem;
}

.span-3 { grid-column: span 3; }
.span-4 { grid-column: span 4; }
.span-5 { grid-column: span 5; }
.span-6 { grid-column: span 6; }
.span-7 { grid-column: span 7; }
.span-8 { grid-column: span 8; }
.span-9 { grid-column: span 9; }
.span-12 { grid-column: span 12; }

.panel {
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.55rem 0.8rem;
    border-bottom: 1px solid var(--border-subtle);
}

.panel-title {
    font-family: var(--font-display);
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
}

.panel-title .dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-success);
    margin-right: 0.4rem;
    flex-shrink: 0;
}

.panel-sub {
    color: var(--text-tertiary);
    font-size: 0.68rem;
    font-family: var(--font-mono);
    white-space: nowrap;
}

.panel-body {
    padding: 0.8rem;
    flex: 1;
}

/* A stat-card placed directly inside a bento panel loses its own
   border/background since the panel already provides both — this
   keeps .stat-card reusable inside or outside a .panel without
   double-chrome. */
.panel > .panel-body > .stat-label,
.panel > .stat-label { margin-top: 0; }
.panel-body .stat-card {
    background: transparent;
    border: none;
    padding: 0;
}

/* ---------------------------------------------------------------------
   RESPONSIVE
   --------------------------------------------------------------------- */
@media (max-width: 1100px) {
    .span-3, .span-4, .span-5, .span-6, .span-7, .span-8, .span-9 {
        grid-column: span 12;
    }
}

@media (max-width: 780px) {
    .deals-table {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .deals-table thead, .deals-table tbody {
        display: table;
        width: 100%;
        min-width: 480px;
    }
    .deals-table td, .deals-table th {
        overflow-wrap: break-word;
        word-break: break-word;
    }

    main { padding: 1rem 0.85rem; }
    header { padding: 1rem; }
    header h1 { font-size: 1.1rem; }
    nav a { font-size: 0.82rem; padding: 0.4rem 0.6rem; margin-left: 0.35rem; }

    /* Stack the nav groups vertically on narrow screens — side by side
       they'd each wrap internally and the group labels would stop
       lining up with the links they label. */
    .site-header { padding: 0.9rem 1rem 0.75rem; }
    .site-header h1 { font-size: 1.2rem; }
    .mainnav {
        flex-direction: column;
        gap: 0.5rem;
        padding: 0 1rem 0.85rem;
    }
    .nav-group { gap: 0.2rem; }
    .mainnav a { padding: 0.35rem 0.6rem; font-size: 0.82rem; }

    .stat-grid { grid-template-columns: repeat(2, 1fr); }
    .card-grid { grid-template-columns: repeat(2, 1fr); }
    .rarity-grid { grid-template-columns: 1fr; }

    .chip, .chip-btn, .scan-btn { padding: 0.45rem 0.75rem; }
    .card-check { width: 22px; height: 22px; }

    .add-form { flex-direction: column; align-items: stretch; }
    .add-form input, .add-form select, .add-form button { width: 100%; }
}

@media (max-width: 480px) {
    .stat-grid { grid-template-columns: 1fr 1fr; }
    .card-grid { grid-template-columns: repeat(2, 1fr); gap: 0.5rem; }
}
