/* ──────────────────────────────────────────────────────────────────────────
 * chonky.cards · Codex redesign — MOBILE PATTERNS (adapted to real app)
 * ──────────────────────────────────────────────────────────────────────────
 * Adapted from design_handoff_mobile/codex-mobile.css. The handoff targeted
 * the prototype's class names; this file maps every pattern onto the live
 * app's real selectors (#cardsContainer, .filters.codex-rail, #cardModal,
 * #ordersDashboard, #statsView, .home-*, .binder-* …).
 *
 * Loaded AFTER mobile.css + responsive.css so it wins below the breakpoints.
 * Nothing changes ≥1100px. Below 900 the filter rail goes off-canvas; below
 * 768 the layout flattens, a slim header + bottom tab bar + drawer take over;
 * below 480 the grid drops to 2 columns and modals go full-screen.
 *
 * BREAKPOINTS  ≤1100 tablet-landscape · ≤900 tablet-portrait ·
 *              ≤768 mobile (tabbar + drawer) · ≤480 phone portrait
 * ────────────────────────────────────────────────────────────────────────── */

:root {
  --tap-min: 44px;
  --tabbar-h: 56px;
  --mobile-header-h: 52px;
  --drawer-w: min(290px, 82vw);
  --sheet-max: 88vh;
}

/* New mobile-only chrome is hidden by default (desktop). */
.mobile-hamburger,
.mobile-header-actions,
.mobile-tabbar,
.codex-nav-drawer,
.codex-nav-drawer-backdrop {
  display: none;
}

/* Touch feedback (desktop hover doesn't fire on touch). */
@media (hover: none) {
  button:active,
  a:active,
  .card:active { opacity: 0.7; transition: opacity 0.05s; }
  #cardsContainer .card:hover { transform: none; }
}

/* ════════════════════════════════════════════════════════════════════════
 * ≤ 1100px — TABLET LANDSCAPE: narrower filter rail + tighter modal
 * ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1100px) {
  .codex-cards-layout .filters.codex-rail { flex-basis: 240px; }
  #cardModal .modal-content { max-width: 96vw; max-height: 94vh; }
}

/* ════════════════════════════════════════════════════════════════════════
 * ≤ 900px — TABLET PORTRAIT: filter rail goes off-canvas (drawer); the
 * cards-view stats strip scrolls; the card modal stacks vertically.
 * ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
  /* The rail leaves the flow (fixed, off-canvas) so the cards area can
     take the full width. Without min-width:0 the grid's intrinsic width
     keeps the flex item from shrinking → horizontal overflow. */
  .codex-cards-layout { display: block; }
  .codex-cards-main { min-width: 0; width: 100%; }

  /* Count info bar + toolbar rows wrap instead of overflowing. */
  #cardCountInfo,
  #cardCountInfo .display-counts-center,
  #cardCountInfo .display-controls-right {
    flex-wrap: wrap;
  }
  /* The search field must stay ONE row — wrapping split the magnifier icon
     onto its own line and clipped the input. Let it span full width and let
     the input shrink (min-width:0) instead of enforcing the desktop 196px. */
  #cardCountInfo .codex-countbar-search,
  .filter-search-row {
    flex-wrap: nowrap;
    width: 100%;
    min-width: 0;
    max-width: none;
  }
  #cardCountInfo .codex-countbar-search .search-box,
  .filter-search-row .search-box { min-width: 0; }

  /* Filter rail → off-canvas drawer from the left. */
  .codex-cards-layout .filters.codex-rail {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 100%;
    max-width: var(--drawer-w);
    flex-basis: auto;
    z-index: 1200;
    transform: translateX(-100%);
    transition: transform 0.22s ease-out;
    box-shadow: 0 0 40px rgba(0, 0, 0, 0.45);
    overflow-y: auto;
  }
  .codex-cards-layout .filters.codex-rail[data-open='true'] {
    transform: translateX(0);
  }
  /* Dim backdrop when the rail is open. */
  body[data-rail-open='true']::after {
    content: '';
    position: fixed;
    inset: 0;
    background: rgba(6, 8, 12, 0.6);
    z-index: 1150;
  }

  /* Stats summary strip (cards view) — single horizontal scroll row.
     The ID selector overrides responsive.css's `.stats-summary-bar
     { flex-direction: column }`, which otherwise stacked every KPI onto its
     own row (~430px tall → no card tiles above the fold) and left the
     per-item ::before separators floating as orphan ticks. */
  #statsSummaryBar {
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  #statsSummaryBar::-webkit-scrollbar { display: none; }

  /* Card detail modal — stack the two panels vertically. */
  #cardModal .card-modal-body {
    flex-direction: column;
  }
  #cardModal .card-modal-left {
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
}

/* ════════════════════════════════════════════════════════════════════════
 * ≤ 768px — MOBILE: slim header + bottom tab bar + drawer; full-screen
 * modals; single-column body; binder single-page; orders 1-per-row.
 * ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  /* Reserve space for the fixed bottom tab bar. */
  .container {
    padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 8px);
  }

  /* ── HEADER: slim mode ─────────────────────────────────────────────── */
  .codex-header {
    /* Override the legacy binders.css `.compact-header { flex-direction:column }`
       rule (the header carries both classes); without this the slim header
       stacks into 3 rows on mobile. base.css centers <header> text, so reset. */
    flex-direction: row;
    text-align: left;
    min-height: var(--mobile-header-h);
    padding: 0 10px;
    gap: 8px;
    align-items: center;
  }
  /* Hide the two-row tabs/search/utilities — replaced by tab bar + drawer. */
  .codex-header .codex-header-rows,
  .codex-header .codex-header-divider {
    display: none !important;
  }
  .codex-header .codex-logo { flex: 1; min-width: 0; }
  .codex-header .codex-logo-text { font-size: 15px; }

  .mobile-hamburger {
    display: inline-grid;
    place-items: center;
    width: var(--tap-min);
    height: var(--tap-min);
    margin-left: -8px;
    background: transparent;
    border: 0;
    color: var(--text);
    cursor: pointer;
    flex: 0 0 auto;
  }
  .mobile-header-actions {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
  }
  .mobile-header-icon {
    display: inline-grid;
    place-items: center;
    width: var(--tap-min);
    height: var(--tap-min);
    background: transparent;
    border: 0;
    color: var(--text-dim);
    cursor: pointer;
  }
  .mobile-header-icon:active { color: var(--accent); }

  /* ── NAV DRAWER (left) ─────────────────────────────────────────────── */
  .codex-nav-drawer {
    display: flex;
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: var(--drawer-w);
    background: var(--surface);
    border-right: 1px solid var(--border-hi);
    z-index: 2100;
    transform: translateX(-100%);
    transition: transform 0.22s ease-out;
    flex-direction: column;
    padding-top: env(safe-area-inset-top);
    overflow-y: auto;
  }
  .codex-nav-drawer[data-open='true'] { transform: translateX(0); }
  .codex-nav-drawer-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(6, 8, 12, 0.6);
    z-index: 2050;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
  }
  .codex-nav-drawer-backdrop[data-open='true'] {
    opacity: 1;
    pointer-events: auto;
  }
  .nav-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 16px 12px;
    border-bottom: 1px solid var(--border);
  }
  .nav-drawer-brand {
    font-family: var(--font-mono);
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
  }
  .nav-drawer-close {
    background: transparent;
    border: 0;
    color: var(--text-dim);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    width: 36px;
    height: 36px;
  }
  .nav-drawer-list {
    display: flex;
    flex-direction: column;
    padding: 8px;
    gap: 1px;
  }
  .nav-drawer-list button {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 11px 12px;
    background: transparent;
    border: 0;
    border-radius: 7px;
    color: var(--text);
    font-family: var(--font-sans);
    font-size: 14px;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
  }
  .nav-drawer-list button:active { background: var(--surface2); }
  .nav-drawer-list button[data-active='true'],
  body[data-view='home'] .nav-drawer-list button[data-drawer-nav='home'],
  body[data-view='cards'] .nav-drawer-list button[data-drawer-nav='cards'],
  body[data-view='binders'] .nav-drawer-list button[data-drawer-nav='binders'],
  body[data-view='orders'] .nav-drawer-list button[data-drawer-nav='orders'],
  body[data-view='stats'] .nav-drawer-list button[data-drawer-nav='stats'],
  body[data-view='history'] .nav-drawer-list button[data-drawer-nav='history'],
  body[data-view='trivia'] .nav-drawer-list button[data-drawer-nav='trivia'],
  body[data-view='help'] .nav-drawer-list button[data-drawer-nav='help'] {
    background: var(--surface3);
    color: var(--accent);
  }
  body[data-view='home'] .nav-drawer-list button[data-drawer-nav='home'] .ndrawer-ic,
  body[data-view='cards'] .nav-drawer-list button[data-drawer-nav='cards'] .ndrawer-ic,
  body[data-view='binders'] .nav-drawer-list button[data-drawer-nav='binders'] .ndrawer-ic,
  body[data-view='orders'] .nav-drawer-list button[data-drawer-nav='orders'] .ndrawer-ic,
  body[data-view='stats'] .nav-drawer-list button[data-drawer-nav='stats'] .ndrawer-ic {
    color: var(--accent);
  }
  .nav-drawer-list .ndrawer-ic {
    width: 20px;
    text-align: center;
    color: var(--text-dim);
    font-family: var(--font-mono);
    flex: 0 0 auto;
  }
  .nav-drawer-list button[data-active='true'] .ndrawer-ic { color: var(--accent); }
  .nav-drawer-sep {
    height: 1px;
    background: var(--border);
    margin: 8px 4px;
  }

  /* ── BOTTOM TAB BAR (5 destinations) ───────────────────────────────── */
  .mobile-tabbar {
    display: flex;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
    padding-bottom: env(safe-area-inset-bottom);
    background: color-mix(in srgb, var(--bg) 92%, transparent);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--border);
    z-index: 1100;
  }
  .mobile-tabbar a {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 6px 2px;
    color: var(--text-dim);
    text-decoration: none;
    font-family: var(--font-sans);
    font-size: 10px;
    font-weight: 500;
    cursor: pointer;
  }
  .mobile-tabbar a[data-active='true'] { color: var(--accent); }
  /* Active state driven by the router's body[data-view] attribute —
     fires on every navigation (pushState included), unlike hashchange. */
  body[data-view='home'] .mobile-tabbar a[data-tab='home'],
  body[data-view='cards'] .mobile-tabbar a[data-tab='cards'],
  body[data-view='binders'] .mobile-tabbar a[data-tab='binders'],
  body[data-view='orders'] .mobile-tabbar a[data-tab='orders'],
  body[data-view='stats'] .mobile-tabbar a[data-tab='stats'] {
    color: var(--accent);
  }
  .mobile-tabbar a .mtab-icon {
    font-size: 19px;
    line-height: 1;
    font-family: var(--font-mono);
  }

  /* ── CARD MODAL → full-screen ──────────────────────────────────────── */
  #cardModal.modal-overlay {
    padding: 0;
    background: var(--bg);
  }
  /* Match codex-modal.css's `.modal-content.card-modal-redesign` specificity
     (1,0,2,0) — the plain `.modal-content` selector lost to it, so the modal
     stayed a centered 1280px/90vh rounded panel instead of going full-screen. */
  #cardModal .modal-content.card-modal-redesign {
    max-width: 100%;
    max-height: 100%;
    width: 100%;
    height: 100%;
    margin: 0;
    border-radius: 0;
    border: 0;
    box-shadow: none;
  }
  /* Header: stack the title over the language/PSA link strip so the title
     isn't crushed to zero width, and keep the close button clear + tappable. */
  #cardModal .modal-header {
    align-items: flex-start;
    gap: 8px;
    overflow-x: hidden;
  }
  #cardModal .modal-header-left { flex-wrap: wrap; min-width: 0; }
  #cardModal .modal-name-row { flex: 1 1 100%; min-width: 0; }
  #cardModal .modal-header-links { flex-wrap: wrap; flex-shrink: 1; }
  #cardModal .modal-close {
    flex-shrink: 0;
    width: var(--tap-min);
    height: var(--tap-min);
    background: var(--surface);
    z-index: 2;
  }
  /* Stack the two panels: image + actions on top, details below. The
     left panel keeps its own column flow (image then full-width
     actions) — forcing it into a row cramps the action buttons. */
  #cardModal .card-modal-body { flex-direction: column; }
  #cardModal .card-modal-left {
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }
  #cardModal .card-modal-left .modal-image { max-width: 220px; margin: 0 auto; }
  #cardModal .modal-nav-controls,
  #cardModal .card-modal-nav { display: none; } /* prev/next — use back instead */

  /* Full-screen modals sit above the tab bar; hide the tab bar + drawer
     chrome while any modal is open so they don't bleed through. */
  body:has(.modal-overlay.active) .mobile-tabbar,
  body:has(#cardModal.active) .mobile-tabbar {
    display: none;
  }
  .modal-overlay.active { z-index: 1300; }

  /* ── ORDERS → 1 per row ────────────────────────────────────────────── */
  #ordersDashboard .orders-list { grid-template-columns: 1fr !important; }
  /* Stats strip is a responsive grid now (see codex-orders.css); the old
     horizontal-scroll hack is no longer needed. */
  #orderDetailModal .modal-content,
  #orderDetailModal .order-detail-modal {
    max-width: 100%;
    max-height: 100%;
    width: 100%;
    height: 100%;
    border-radius: 0;
  }

  /* ── STATS → stacked; nav becomes a horizontal chip strip ──────────── */
  /* align-items:stretch overrides codex-stats.css's flex-start so stacked
     children fill the width instead of keeping their intrinsic (wide) size,
     which pushed the right KPI column offscreen and gave the page a
     horizontal scrollbar. canvas guard stops Chart.js from forcing width. */
  #statsView {
    flex-direction: column !important;
    align-items: stretch;
  }
  #statsView canvas { max-width: 100%; }
  #statsView .stats-nav {
    position: static;
    flex: 0 0 auto;
    width: 100%;
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 6px;
    padding: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: 12px;
    scrollbar-width: none;
  }
  #statsView .stats-nav::-webkit-scrollbar { display: none; }
  #statsView .stats-nav::before { display: none; }
  #statsView .stats-nav-link {
    flex: 0 0 auto;
    white-space: nowrap;
    border-left: 0;
    border-radius: var(--radius-full);
  }
  #statsView .stats-nav-value { display: none; }
  /* minmax(0, 1fr) lets the two KPI tracks shrink below their content width
     (values already ellipsize) — plain 1fr kept the grid wider than the
     viewport. */
  #statsView .stats-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* ── BINDER → single page; rail/tray become a bottom sheet ─────────── */
  #binderDetailView .binder-spread-layout { flex-direction: column; }
  /* In spread mode, hide the right page so a single page fills the width.
     JS also forces viewMode=single on mobile; this is a CSS safety net. */
  #binderDetailView .page-spread-grid:not(.page-spread-grid--single) .page-spine,
  #binderDetailView .page-spread-grid:not(.page-spread-grid--single) .page-spread-half:last-child {
    display: none;
  }
  #binderDetailView .page-spread-grid {
    grid-template-columns: 1fr !important;
  }
  #binderDetailView .binder-rail {
    flex: 0 0 auto;
    width: 100%;
    position: static;
    max-height: none;
  }
  /* Binder header tools wrap on small screens. */
  #binderDetailView .binder-header-tools { flex-wrap: wrap; }

  /* ── HOME → single-column stack ────────────────────────────────────── */
  .home-intro { grid-template-columns: 1fr !important; gap: 20px; }
  .home-jumbo-explainer,
  .home-jumbo-content { grid-template-columns: 1fr !important; }
  .home-features-grid { grid-template-columns: 1fr !important; }
  .home-explore-grid { grid-template-columns: 1fr !important; }
  .home-stats-strip { flex-direction: column; gap: 14px; }
  /* Showcase + size cards scroll horizontally instead of cramming. */
  .home-intro-right { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .home-type-showcase {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    grid-auto-flow: column;
    grid-auto-columns: minmax(150px, 1fr);
  }

  /* ── EDITORIAL → single column ─────────────────────────────────────── */
  #triviaView .trivia-grid {
    grid-template-columns: 1fr !important;
  }

  /* ── FOOTER pages → tighter padding ────────────────────────────────── */
  #footerPageView { padding: 0 12px; }

  /* ── COLLECTION MANAGER → full-screen, rail becomes a top chip strip ─ */
  #collectionManagerModal .cm-modal {
    max-width: 100%;
    max-height: 100%;
    width: 100%;
    height: 100%;
    border-radius: 0;
    flex-direction: column;
  }
  #collectionManagerModal .cm-sidebar {
    width: 100%;
    align-self: auto;
    border-right: 0;
    border-bottom: 1px solid var(--border);
  }
  #collectionManagerModal .cm-nav {
    flex-direction: row;
    overflow-x: auto;
    padding: 8px;
    scrollbar-width: none;
  }
  #collectionManagerModal .cm-nav::-webkit-scrollbar { display: none; }
  #collectionManagerModal .cm-nav-item {
    flex: 0 0 auto;
    white-space: nowrap;
    padding: 8px 12px;
  }
  #collectionManagerModal .cm-rail-status { display: none; }

  /* Generic sub-modals → full-screen. */
  #binderSettingsModal .modal-content,
  #pageManagerModal .modal-content,
  #ownedEditModal .modal-content,
  #orderedEditModal .modal-content,
  #batchAddOwnedModal .modal-content,
  #cardSearchModal .modal-content,
  #contactModal .modal-content {
    max-width: 100% !important;
    max-height: 100% !important;
    width: 100%;
    height: 100%;
    border-radius: 0;
  }
}

/* ════════════════════════════════════════════════════════════════════════
 * ≤ 480px — PHONE PORTRAIT: 2-column card grid, tighter chrome.
 * ════════════════════════════════════════════════════════════════════════ */
@media (max-width: 480px) {
  /* CARDS GRID — force 2 columns regardless of the XL/L/S grid-size class;
     XS (cols-8) drops to 3 so the densest setting stays denser. */
  #cardsContainer.cards-grid.cols-2,
  #cardsContainer.cards-grid.cols-4,
  #cardsContainer.cards-grid.cols-6 {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 8px;
  }
  #cardsContainer.cards-grid.cols-8 {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }

  /* Count info bar — wrap; hide grid-size + CSV + reorder (live in the
     filter sheet / drawer instead). */
  #cardCountInfo {
    flex-wrap: wrap;
    gap: 6px 10px;
  }
  #cardCountInfo .grid-size-control,
  #cardCountInfo .grid-size-segmented,
  #cardCountInfo .export-csv-btn,
  #cardCountInfo .reorder-btn {
    display: none;
  }

  /* Card tile — hide the market trend % to save width. */
  #cardsContainer .card .card-price-trend { display: none; }

  /* Form grids collapse to one column. */
  .form-grid-3,
  .form-grid-2,
  #binderSettingsModal .color-picker { grid-template-columns: 1fr; }

  /* Binders list → 1 column. */
  #binderListView .binder-cards-container { grid-template-columns: 1fr; }

  /* Slightly smaller headings. */
  #footerPageView h1,
  .home-section-title { font-size: 24px; }
}

/* ════════════════════════════════════════════════════════════════════════
 * GESTURES — live-follow during a touch drag (transition suspended so the
 * panel/modal tracks the finger 1:1; snaps back on release).
 * ════════════════════════════════════════════════════════════════════════ */
.codex-nav-drawer.gesture-dragging,
.filters.codex-rail.gesture-dragging,
.modal-overlay.active .modal-content.gesture-dragging {
  transition: none !important;
}

/* Swipe-down grabber on full-screen mobile modals — a centered pill that
   signals the top region is draggable to dismiss. */
@media (max-width: 768px) {
  .modal-overlay.active .modal-content::before {
    content: '';
    position: absolute;
    top: 6px;
    left: 50%;
    transform: translateX(-50%);
    width: 36px;
    height: 4px;
    border-radius: 2px;
    background: var(--text-mute);
    opacity: 0.4;
    z-index: 5;
    pointer-events: none;
  }
}

/* ════════════════════════════════════════════════════════════════════════
 * ANIMATIONS
 * ════════════════════════════════════════════════════════════════════════ */
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }

/* ════════════════════════════════════════════════════════════════════════
 * PRINT — hide mobile chrome
 * ════════════════════════════════════════════════════════════════════════ */
@media print {
  .mobile-tabbar,
  .mobile-hamburger,
  .mobile-header-actions,
  .codex-nav-drawer,
  .codex-nav-drawer-backdrop { display: none !important; }
}
