/* =============================================================
   responsive.css — the device pass, loaded LAST on every page so
   it can correct anything the earlier sheets set.

   theme.css / store.css / admin.css already carry the layout
   breakpoints they own. This file handles what they don't:

     · phones under 560px, where dashboard tables stop working
       as tables and become stacked cards
     · tablets between 720 and 1000px, previously an awkward gap
     · touch targets, which need 44px whatever the screen size
     · notches and home indicators (safe-area insets)
     · landscape phones, where vertical space is the scarce thing
     · very large screens, where the layout used to strand itself
       in the middle of the page

   Breakpoints used throughout, so they stay memorable:
     1440  large desktop      1200  desktop
     1024  small laptop       900   tablet landscape
     720   tablet portrait    560   large phone
     420   small phone
   ============================================================= */

/* ------------------------------------------------------------------
   1. Fluid foundations
   Type and rhythm scale with the viewport instead of stepping at
   each breakpoint, so there are no sizes that only look right at
   exactly 768px.
------------------------------------------------------------------- */
:root {
  --tap: 44px;                 /* minimum comfortable touch target */
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
}

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* Nothing should ever force a horizontal scrollbar. Individual wide
   things (tables, carousels) opt back in with their own overflow. */
html, body { max-width: 100%; overflow-x: hidden; }

img, video, svg, canvas { max-width: 100%; height: auto; }
/* …except where a fixed box is the point, e.g. avatars and thumbnails. */
.tbl-thumb, .img-chip img, .v-photo img, .avatar img, .pcard-media img,
.order-line img, .cart-row img, .pin-item img { height: 100%; }

/* Long product names, order codes and emails used to push layouts
   sideways on narrow screens. */
body { overflow-wrap: break-word; }
.pcard-title, .tbl-prod strong, .order-head strong { overflow-wrap: anywhere; }

/* iOS zooms the whole page in when a focused input is under 16px.
   Keeping form text at 16px on touch devices avoids that jump. */
@media (hover: none) and (pointer: coarse) {
  .input, .field, input, select, textarea { font-size: 16px; }
}

/* ------------------------------------------------------------------
   2. Touch targets
   Anything tappable gets to 44px on touch devices. Kept behind the
   pointer query so mouse users keep the tighter, denser layout.
------------------------------------------------------------------- */
@media (hover: none) and (pointer: coarse) {
  .btn, .icon-btn, .chip, .side-item, .tabs button,
  .qty button, .gallery-thumbs button, .pagination button,
  .campaign-arrows button, .campaign-dots button {
    min-height: var(--tap);
  }
  .icon-btn, .qty button { min-width: var(--tap); }
  .campaign-dots button { min-height: 22px; }   /* a bar, not a button shape */
  .wish-btn { width: var(--tap); height: var(--tap); }
  /* Hover-reveal never fires on touch, so show the card actions outright. */
  .pcard-add { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------
   3. Large screens
   The 1200px wrap left a lot of empty margin on wide monitors while
   product grids stayed at four across.
------------------------------------------------------------------- */
@media (min-width: 1440px) {
  :root { --wrap: 1340px; --gutter: 32px; }
  .product-grid--compact { grid-template-columns: repeat(5, 1fr); }
}
@media (min-width: 1800px) {
  :root { --wrap: 1480px; }
}

/* ------------------------------------------------------------------
   4. Small laptops and tablets — 1024px and down
------------------------------------------------------------------- */
@media (max-width: 1024px) {
  :root { --gutter: 20px; }

  .pdp { gap: 28px; }
  .kpi-grid { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; }
  .kpi { padding: 16px 18px; }
  .kpi b { font-size: 1.6rem; }

  .dash-main { padding: 22px 24px 60px; }
}

/* The dashboard sidebar is fixed-width; give the content the rest.
   Scoped above 900px on purpose: below that admin.css turns the sidebar
   into an off-canvas drawer, and a two-column grid here would reserve
   210px for a sidebar that is no longer in the flow — squeezing the
   content into a narrow strip on every phone. */
@media (min-width: 901px) and (max-width: 1024px) {
  .dash { grid-template-columns: 210px 1fr; }
}

/* ------------------------------------------------------------------
   5. Tablet portrait — 900px and down
   admin.css already turns the sidebar into a drawer at 900px. What
   it doesn't do is dim the page behind it or let you tap away to
   close, which made the drawer feel stuck.
------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* Re-asserted here so no earlier max-width block can reinstate a
     sidebar column after the drawer takes over. */
  .dash { grid-template-columns: 1fr; }
  .side {
    box-shadow: var(--shadow-lg);
    padding-top: calc(22px + var(--safe-t));
  }
  /* Backdrop behind the open dashboard drawer. Purely visual — the
     close tap is wired up in admin/superadmin page scripts. */
  .side.open::after {
    content: ''; position: fixed; inset: 0 0 0 250px;
    background: rgba(0,0,0,.45); z-index: -1;
  }

  .dash-head { margin-bottom: 20px; }
  .dash-head h1 { font-size: 1.4rem; }
  /* The burger sits first, the title next, actions wrap to their own
     line rather than squeezing the heading. */
  .dash-head #head-actions { width: 100%; display: flex; gap: 8px; flex-wrap: wrap; }
  .dash-head .spacer { display: none; }

  .vendor-facts { gap: 18px; }
  .shop-layout, .cart-layout { gap: 26px; }
}

/* ------------------------------------------------------------------
   6. Tablet portrait and large phones — 720px and down
------------------------------------------------------------------- */
@media (max-width: 720px) {
  .page-head h1 { font-size: clamp(1.5rem, 6vw, 2rem); }
  .section { padding: 42px 0; }

  /* Tabs scroll sideways instead of wrapping into a ragged block. */
  .tabs {
    overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none;
    -webkit-overflow-scrolling: touch; margin-top: 40px;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs button { white-space: nowrap; flex-shrink: 0; }

  /* Category chips on a shop page, same treatment. */
  .vendor-tags {
    display: flex; flex-wrap: nowrap; overflow-x: auto;
    scrollbar-width: none; padding-bottom: 4px;
  }
  .vendor-tags::-webkit-scrollbar { display: none; }
  .vendor-tags .chip { flex-shrink: 0; }

  .shop-toolbar { flex-direction: column; align-items: stretch; gap: 10px; }
  .shop-toolbar .field { width: 100%; }

  .order-head { gap: 8px; }
  .order-line { flex-wrap: wrap; }
  .order-line .btn { margin-left: auto; }

  .summary { padding: 18px; }
  .modal-foot .btn, .pdp-actions .btn { flex: 1; }

  /* Filters become a collapsible block above the results rather than
     a column that pushes the products off the first screen. */
  .filters { padding: 16px; }
}

/* ------------------------------------------------------------------
   7. Dashboard tables become cards — 720px and down

   A six-column table inside a horizontal scroller is technically
   readable and practically useless on a phone: you scroll right,
   lose the product name, and can't tell which row you're editing.

   Below 720px each row restacks into a card, and every cell grows a
   label from its data-label attribute. The page scripts set that
   attribute; any table cell without one simply shows its value,
   which is the right fallback for a single-column table.
------------------------------------------------------------------- */
@media (max-width: 720px) {
  .table-scroll { overflow-x: visible; }

  table.tbl, table.tbl tbody, table.tbl tr, table.tbl td { display: block; width: 100%; }
  table.tbl thead { display: none; }

  table.tbl tr {
    border: 1px solid var(--line); border-radius: var(--r-md);
    background: var(--surface); padding: 14px; margin: 0 0 12px;
  }
  table.tbl tr:last-child { margin-bottom: 0; }
  table.tbl tbody tr:hover { background: var(--surface); }

  table.tbl td {
    border: none; padding: 7px 0;
    display: grid; grid-template-columns: 40% 1fr; gap: 12px; align-items: center;
  }
  table.tbl td::before {
    content: attr(data-label);
    font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
    color: var(--muted); font-weight: 600;
  }
  /* A cell with no label — the product cell and the actions cell —
     spans the full width instead of leaving a dead 40% column. */
  table.tbl td:not([data-label]) { grid-template-columns: 1fr; }
  table.tbl td:not([data-label])::before { display: none; }

  /* The first cell is the row's heading: full width, a little breathing
     room under it, and a rule to separate it from its own details. */
  table.tbl td:first-child {
    grid-template-columns: 1fr; padding-top: 0; padding-bottom: 12px;
    margin-bottom: 6px; border-bottom: 1px solid var(--line);
  }
  table.tbl td:first-child::before { display: none; }

  table.tbl td:last-child { padding-bottom: 0; padding-top: 12px; }
  .row-actions { justify-content: stretch; }
  .row-actions .btn { flex: 1; }
  .select-sm, .input-sm { width: 100%; }

  /* The variant grid is the one table that stays a table — its columns
     are short numbers, and stacking 60 combinations would be endless.
     It keeps the horizontal scroller instead. */
  .var-tbl, .var-tbl tbody, .var-tbl tr, .var-tbl td { display: revert; width: auto; }
  .var-tbl thead { display: revert; }
  .var-tbl tr { border: none; border-radius: 0; padding: 0; margin: 0; }
  .var-tbl td {
    display: table-cell; border-bottom: 1px solid var(--line);
    padding: 8px 10px;
  }
  .var-tbl td::before { display: none; }
  .var-tbl td:first-child {
    border-bottom: 1px solid var(--line); margin: 0; padding: 8px 10px;
  }
  #var-wrap .table-scroll { overflow-x: auto; }
  .var-tbl { min-width: 620px; }
}

/* ------------------------------------------------------------------
   8. The product modal goes full-screen — 720px and down
   A centred dialog with 20px of scrim around it wastes a third of a
   phone screen on a form this long.
------------------------------------------------------------------- */
@media (max-width: 720px) {
  .modal-scrim { padding: 0; place-items: stretch; }
  .modal {
    width: 100%; max-width: none; max-height: none; min-height: 100dvh;
    border-radius: 0; border: none;
  }
  .modal-head {
    padding: calc(16px + var(--safe-t)) 18px 16px;
    position: sticky; top: 0; z-index: 2; background: var(--surface);
  }
  .modal-head h3 { font-size: 1.1rem; }
  .modal-body { padding: 18px; }
  /* The save button stays reachable at the foot of a long form. */
  .modal-foot {
    position: sticky; bottom: 0; background: var(--surface);
    padding: 14px 18px calc(14px + var(--safe-b));
  }
  .form-section { padding: 14px; }
  .dim-row { grid-template-columns: repeat(2, 1fr); }
  .toggle-grid { grid-template-columns: 1fr; }
  .pin-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
}

/* ------------------------------------------------------------------
   9. Large phones — 560px and down
------------------------------------------------------------------- */
@media (max-width: 560px) {
  .dash-main { padding: 16px 14px calc(50px + var(--safe-b)); }
  .panel-body { padding: 16px; }
  .panel-head { padding: 14px 16px; }
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .kpi { padding: 14px; }
  .kpi b { font-size: 1.4rem; }
  .kpi span { font-size: .68rem; }

  /* Best-sellers bar: the name and the figure stack over the bar
     rather than crushing it to nothing. */
  .bar-row { flex-wrap: wrap; }
  .bar-row .bar-name { width: 100%; }
  .bar-track { flex: 1 1 100%; order: 3; }

  .gallery-thumbs { gap: 8px; }
  .pdp-meta { grid-template-columns: 1fr; }
  .pdp-actions { gap: 8px; }
  .pdp-actions .qty { flex: 0 0 auto; }

  .footer-grid { gap: 26px; }
  .footer-bottom { flex-direction: column; gap: 6px; text-align: center; }

  .crumbs { font-size: .78rem; }
  .review-head { flex-wrap: wrap; }

  /* Anything fixed to the bottom clears the home indicator. */
  .toast-stack { bottom: calc(16px + var(--safe-b)); }
  .back-to-top { bottom: calc(18px + var(--safe-b)); }
  body.has-mobile-buy-bar .back-to-top { bottom: calc(96px + var(--safe-b)); }

  .drawer { width: min(300px, 86vw); padding-top: calc(18px + var(--safe-t)); }
}

/* ------------------------------------------------------------------
   10. Small phones — 420px and down
   Two-across product cards stop being legible here, so the grid
   drops to one and the cards get their full width back.
------------------------------------------------------------------- */
@media (max-width: 420px) {
  :root { --gutter: 14px; --r-lg: 16px; --r-md: 11px; }

  .product-grid, .product-grid--3, .cat-grid { grid-template-columns: 1fr; }
  /* Compact stays two-across on purpose — it's the layout a seller
     picks when they want a dense catalogue. */
  .product-grid--compact { grid-template-columns: repeat(2, 1fr); }

  .stat-grid { grid-template-columns: 1fr; gap: 22px; }
  .kpi-grid { grid-template-columns: 1fr; }

  .cart-row { grid-template-columns: 60px 1fr; gap: 10px; }
  .cart-row img { width: 60px; height: 60px; }

  .vendor-id { flex-direction: column; align-items: flex-start; gap: 12px; }
  .vendor-logo { width: 62px; height: 62px; }

  .tabs button { padding: 12px 14px; font-size: .88rem; }
  .modal-foot { flex-direction: column-reverse; }
  .modal-foot .btn { width: 100%; }
}

/* ------------------------------------------------------------------
   11. Landscape phones
   Height is the constraint, not width. Trim the vertical padding so
   something other than the header is on screen.
------------------------------------------------------------------- */
@media (max-height: 480px) and (orientation: landscape) {
  .section { padding: 28px 0; }
  .page-head { padding: 20px 0 10px; }
  .campaign { min-height: 0; }
  .drawer { overflow-y: auto; }
  .modal { min-height: 100dvh; }
  .modal-body { padding-block: 12px; }
}

/* ------------------------------------------------------------------
   12. Print
   Someone will print an order or a product page. Drop the chrome.
------------------------------------------------------------------- */
@media print {
  .site-header, .site-footer, .drawer, .scrim, .back-to-top,
  .mobile-buy-bar, .toast-stack, .side, .dash-head #head-actions,
  .pcard-add, .wish-btn, .pagination { display: none !important; }
  .dash { grid-template-columns: 1fr; }
  .dash-main { padding: 0; background: #fff; }
  body { background: #fff; color: #000; }
  .panel, .order-card { border-color: #ccc; break-inside: avoid; }
}

/* ------------------------------------------------------------------
   13. Late corrections
   These sit at the end so they win against the earlier blocks in this
   file as well as the ones in theme.css / store.css / admin.css.
------------------------------------------------------------------- */

/* 13a. Dashboard height.
   100vh on a phone means "viewport including the space the URL bar is
   currently covering", so the sidebar and main column both run past the
   bottom of the screen and the page gains a phantom scroll. dvh tracks
   the visible area instead. Kept behind @supports so older browsers
   keep the 100vh they understand. */
@supports (height: 100dvh) {
  .dash { min-height: 100dvh; }
  .side { height: 100dvh; }
  .dash-main { min-height: 100dvh; }
}

/* 13b. Header overflow on phones.
   Four icon buttons, a burger and a "Create account" button do not fit
   inside the header pill on a narrow screen — the button hangs off the
   right edge. Registering is already the second item in the drawer, so
   nothing is lost by dropping it from the bar itself. */
@media (max-width: 700px) {
  .header-actions { gap: 2px; margin-left: auto; }
  .header-actions .btn { display: none; }
  .header-inner { gap: 8px; min-width: 0; }
  .header-inner .logo { flex-shrink: 0; }
}
@media (max-width: 380px) {
  /* Wishlist lives in the drawer too; the cart is the one that has to
     stay reachable from every page. */
  .header-actions a[href="/wishlist"] { display: none; }
}

/* 13c. Two-column form rows.
   store.css collapses .form-row at 560px, but the product modal goes
   full-screen at 720px — so between those widths a long form kept two
   cramped columns inside a full-width sheet. */
@media (max-width: 720px) {
  .form-row { grid-template-columns: 1fr; }
}

/* 13d. Nothing in a dashboard panel should be able to push the page
   sideways; wide tables scroll inside their own container. */
@media (max-width: 900px) {
  .dash-main, .panel, .panel-body, .kpi-grid { min-width: 0; max-width: 100%; }
  .panel-head { row-gap: 8px; }
}
