/* ════════════════════════════════════════════════════════════════
   store desktop polish — extracted from the inline critical CSS
   in store.html to keep the raw inline payload under the 202 KB
   budget (see scripts/check-store-budget.js).

   Mobile is the canonical layout. This file adds rules at ≥960px —
   the SAME width the store body flips to its desktop layout (the
   device-class detect in store.html drops .is-tablet above 959px).
   Earlier this started at ≥1280px, which left a 960–1279px "dead
   zone": the body was in desktop mode (no .is-phone/.is-tablet, so
   none of the inline mobile gutters applied) but this desktop polish
   hadn't kicked in either — so every rail lost its side padding and
   the bundles/featured/collections cards fell back to block flow,
   stranding one card on the left with the rest of the row empty. The
   centering-padding rules below are floored with max(--v2-gutter, …)
   so they stay a sane gutter (not negative) below the 1200px column.
   It's preload+swap from the shell so it arrives in parallel with the
   LCP image and applies non-blocking.

   Strategy: a single max-width container (--v2-col, currently 1680px)
   is applied via per-section margin:auto + max-width. The page body
   stays full-bleed so backgrounds (chip strip, bundles' gold wash)
   still extend edge-to-edge, but the content inside each section
   sits inside the centered column — which fills the screen on normal
   monitors and caps + centers on really wide ones.
   ──────────────────────────────────────────────────────────────── */
@media (min-width:960px){
  :root{
    /* Capped-and-centered desktop (June 2026): the store fills the
       viewport on normal monitors but stops growing past --v2-col on
       really wide screens, centering the page instead of stretching the
       hero photo + cards edge-to-edge. Every section keys off this one
       variable, so the cap applies everywhere at once (hero, chip strip,
       rails, menu grid). The math self-floors: when the viewport is
       narrower than --v2-col, max-width never bites and the max(--v2-gutter,
       calc((100% - col)/2 …)) centering rules resolve to a plain side
       gutter — i.e. identical to the old full-bleed look below the cap.
       Above the cap, max-width clamps each section and margin:auto +
       the calc term split the leftover space into equal side gutters. */
    --v2-col:1680px;          /* max content width — centers beyond this */
    --v2-gutter:24px;         /* side padding at the screen edges */
  }

  /* Section width clamp — keep the section's background full-bleed
     (chip strip wash, bundles gold gradient) but constrain the inner
     content to --v2-col, centered. */
  .v2-hero,
  .v2-coll-head, .v2-coll-row,
  .v2-featured-head, .v2-featured-row,
  .v2-fy-head, .v2-fy-row,
  .v2-bundles-head, .v2-bundles-row,
  .v2-menu-head,
  .v2-coll-active,
  .v2-grid,
  .v2-pantry-head, .v2-pantry-grid{
    max-width:var(--v2-col);
    margin-left:auto;margin-right:auto;
    padding-left:var(--v2-gutter);padding-right:var(--v2-gutter);
  }

  /* Pantry section is full-bleed (border-top wash); its inner head + grid
     are centered to the 1200px column above, so zero the wrapper's side
     padding to keep them aligned with every other rail's left edge. */
  .v2-pantry{padding-left:0;padding-right:0;}

  /* Chip strip — full-bleed background, content aligned to the centered
     1200px column. The search button flows inline as the FIRST control at
     the column's left gutter (right before the dietary funnel), so the
     whole filter group reads left-to-right with no gap. The dietary
     control follows, then the category chips scroll to its right. Bar
     padding pushes the flow to the column's left edge so the search button
     lines up with the hero/cards left edge. */
  .v2-chips{
    padding-left:max(var(--v2-gutter), calc((100% - var(--v2-col)) / 2 + var(--v2-gutter)));
    padding-right:max(var(--v2-gutter), calc((100% - var(--v2-col)) / 2 + var(--v2-gutter)));
  }
  .v2-chips-row{
    max-width:none;
    margin-left:0;margin-right:0;
    padding-left:0;
    padding-right:32px; /* room for the right fade mask */
  }
  .v2-search{
    /* In-flow at the column's left edge instead of pinned to the bar's
       far-left. Pinning it absolutely left a wide empty gap between the
       search icon and the rest of the filter controls on wide screens. */
    position:relative;
    margin-left:0;
    z-index:2; /* keep the expanded input above the chips so it's clickable */
  }
  /* When the search input is expanded ([data-search-open="1"]), fade the
     dietary slot + chip pills out so the expanded search has the bar to
     itself. The base inline rules have no opacity transition — add one
     here so the fade is smooth. !important because another cascade rule
     keeps opacity:1; pragmatic given the single-page scope. */
  .v2-chips-row,
  .diet-filter-slot{transition:opacity .18s ease;}
  .v2-chips[data-search-open="1"] .v2-chips-row,
  .v2-chips[data-search-open="1"] .diet-filter-slot{
    opacity:0 !important;
    pointer-events:none;
  }

  /* Dietary control — first option on the left, flowing naturally at the
     column's left edge (no special positioning needed now). The
     active-chips strip stays full-bleed but aligns its chips to the
     column; the dropdown panel drops as a left-aligned card under the
     trigger instead of a full-width sheet. */
  .diet-filter-row{
    padding-left:max(var(--v2-gutter), calc((100% - var(--v2-col)) / 2 + var(--v2-gutter)));
    padding-right:max(var(--v2-gutter), calc((100% - var(--v2-col)) / 2 + var(--v2-gutter)));
  }
  .diet-filter-panel{
    margin-left:max(var(--v2-gutter), calc((100% - var(--v2-col)) / 2 + var(--v2-gutter)));
    margin-right:auto;
    max-width:440px;
  }

  /* Hero — bigger title, no internal top padding. The body's padding-top
     already provides the 8px gap below the chip bar (matching the 8px
     gap above the chip bar — symmetric breathing). If the hero
     re-introduces its own padding-top, the gap below the chip bar
     would grow to (body-pad-bottom-edge − chip-bottom) + hero-pad-top,
     which is the asymmetry that read as "way too much padding". */
  .v2-hero{padding-top:0;padding-bottom:8px;}
  .v2-hero h1{font-size:34px;letter-spacing:-.024em;font-weight:900;}
  .v2-hero p{font-size:15px;margin-top:8px;}

  /* Fulfillment row — full-bleed at mobile; on desktop cap it so the
     "change ›" affordance doesn't drift miles from the icon+label. */
  .v2-hero-control{max-width:640px;}

  /* "this week's picks" featured rail — hidden by default at desktop
     in the inline critical CSS (.v2-featured{display:none}), bring
     it back as a styled horizontal rail. */
  .v2-featured{display:block;background:#fff;padding:18px 0 22px;border-bottom:1px solid var(--line);}
  .v2-featured[data-hide="1"]{display:none;}
  .v2-featured-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-top:0;padding-bottom:10px;}
  .v2-featured-head h2{margin:0;font-size:22px;font-weight:900;letter-spacing:-.018em;color:var(--ink);}
  .v2-featured-head em{font-style:normal;color:var(--accent);}
  /* Collections heading matches the other rail headings on desktop too. */
  .v2-coll-head h2{margin:0;font-size:22px;font-weight:900;letter-spacing:-.018em;color:var(--ink);}
  .v2-coll-head h2 em{font-style:normal;color:var(--accent);}
  .v2-featured-head .v2-featured-sub{display:inline;font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);}
  .v2-featured-row{
    display:flex;gap:14px;
    overflow-x:auto;overflow-y:hidden;
    /* Disable scroll-snap on desktop. With scroll-snap-type:x mandatory
       + first card has scroll-snap-align:start + row padding-left:24,
       the browser auto-scrolls the row by 24px to snap the first card's
       edge to the snap-port left. That pulls the visible first card
       back from x=144 (column inner edge) to x=120 (row outer edge),
       misaligning it from the section headings and hero. Desktop has
       all 4 cards in view at once so snap behavior wasn't useful anyway. */
    scroll-snap-type:none;
    padding-top:4px;padding-bottom:4px;
    scrollbar-width:none;-ms-overflow-style:none;
  }
  .v2-featured-row::-webkit-scrollbar{display:none;}
  .v2-feat-card{flex:0 0 calc((100% - 42px) / 4); /* 4 cards per row, 14px gap × 3 */ max-width:none;scroll-snap-align:start;}
  .v2-feat-thumb{aspect-ratio:1/1 !important;}

  /* For-you rail — cap cards so 3-4 fit per row instead of one
     huge card stretching the column. Specificity bump (.v2-fy-row > …)
     wins over the lower-specificity base rule injected by
     /scripts/foryou.js at runtime. Without the parent selector, the
     cascade tie goes to foryou.js (later in document order via runtime
     <style> append) and the cards stay at mobile flex:0 0 88% width. */
  /* IMPORTANT — keep left/right gutter padding from the shared
     "Section width clamp" rule above (padding-left:var(--v2-gutter)).
     The original `padding:18px 0 8px` shorthand zero'd those out,
     causing the h2 to sit 24px left of where every other section's
     content starts. Explicit padding-top/padding-bottom only. */
  .v2-fy-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-top:18px;padding-bottom:8px;}
  .v2-fy-head h2{margin:0;font-size:22px;font-weight:900;letter-spacing:-.018em;color:var(--ink);}
  .v2-fy-head em{font-style:normal;color:var(--accent);}
  .v2-fy-sub{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);}
  .v2-fy-row{
    display:flex;gap:14px;
    overflow-x:auto;
    padding-top:2px;padding-bottom:14px;
    scrollbar-width:none;-ms-overflow-style:none;
    min-height:108px;
  }
  .v2-fy-row::-webkit-scrollbar{display:none;}
  .v2-fy-row .v2-fy-card,
  .v2-fy-row .v2-fy-skel{flex:0 0 calc((100% - 28px) / 3); /* 3 per row, 14px gap × 2 */ max-width:none;}

  /* Bundles — currently has NO desktop CSS (all .is-phone-prefixed
     in bundles.js), so the row falls back to block display with one
     card stranded on the left. Wire it as a 3-up grid here.
     Specificity-bumped via `.v2-bundles-row` parent — same reason
     as .v2-fy-card above. */
  .v2-bundles{background:linear-gradient(160deg,#FAF6EC 0%,#F4EFE3 55%,#E9DDC4 100%);border-top:1px solid rgba(200,169,110,.30);border-bottom:1px solid rgba(200,169,110,.30);padding:6px 0 22px;}
  .v2-bundles[data-hide="1"]{display:none;}
  /* Same gutter-preserving fix as .v2-fy-head. */
  .v2-bundles-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-top:18px;padding-bottom:10px;}
  .v2-bundles-head h2{margin:0;font-size:22px;font-weight:900;letter-spacing:-.018em;color:var(--ink);}
  .v2-bundles-head em{font-style:normal;color:var(--accent);}
  .v2-bundles-sub{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);}
  .v2-bundles-row{
    display:flex;gap:14px;
    overflow-x:auto;
    padding-top:4px;padding-bottom:6px;
    scrollbar-width:none;-ms-overflow-style:none;
    /* Same scroll-snap disable as .v2-featured-row above — keeps the
       first bundle card aligned to the column inner edge. */
    scroll-snap-type:none;
  }
  .v2-bundles-row::-webkit-scrollbar{display:none;}
  .v2-bundles-row .v2-bundle-card{flex:0 0 calc((100% - 28px) / 3); /* 3 per row */ max-width:none;scroll-snap-align:start;}

  /* Collections rail — the ONE rail that shipped without a desktop pass.
     Its head kept the 15px/brand phone styling (so the "collections."
     title read smaller + a different color than every sibling head), and
     its cards kept the fixed 188–214px phone width — which left the row
     well short of the column's right edge, so the shelf looked narrower /
     misaligned next to bundles + top-picks. Bring it in line: head matches
     the featured/bundles heads (22px/900/ink, accent em, same gutter +
     vertical padding), and the cards fill the 1200px column 4-up (any 5th+
     collection scrolls, with the next card peeking). Mirrors the
     .v2-bundles-row card-sizing pattern above. */
  .v2-coll{padding:6px 0 22px;}
  .v2-coll-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-top:18px;padding-bottom:10px;}
  .v2-coll-head h2{font-size:22px;font-weight:900;letter-spacing:-.018em;color:var(--ink);}
  .v2-coll-head h2 em{color:var(--accent);}
  .v2-coll-sub{display:inline;font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);}
  .v2-coll-row{
    scroll-snap-type:none; /* same reason as .v2-featured-row — keep first card flush to the column edge */
    padding-top:4px;padding-bottom:6px;
  }
  .v2-coll-row .v2-coll-card{flex:0 0 calc((100% - 36px) / 4); /* 4 per row, 12px gap × 3 */ width:auto;height:260px;}

  /* Section header — match the rail head sizing. Same gutter-preserving
     fix as .v2-fy-head. */
  .v2-menu-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding-top:24px;padding-bottom:10px;}
  .v2-menu-head h2{margin:0;font-size:22px;font-weight:900;letter-spacing:-.018em;color:var(--ink);}
  .v2-menu-head em{font-style:normal;color:var(--accent);}
  .v2-menu-sub{font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);}

  /* Main grid — full-bleed, but capped at FOUR meals per row at any width
     (Omar, Jun 2026: "no more than 4 at a time"). Fewer columns when narrow,
     never more than four when wide — so ultra-wide screens get four larger
     cards rather than six small ones. Explicit counts (not auto-fill) are
     what enforce the hard ceiling. */
  /* Column count: 3 minimum, 4 maximum at every desktop width (Omar,
     Jun 2026: "3-4 per row min and 4 max" — 2-up giant cards are out).
     3-up holds even at the narrowest docked window (1200px viewport −
     380px rail − gutters ≈ 772px of grid → ~245px cards, same ballpark
     as the phone card). 4-up from 1480px works docked or not. */
  .v2-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;padding-top:6px;padding-bottom:96px;}
  @media (min-width:1480px){ .v2-grid{grid-template-columns:repeat(4,minmax(0,1fr));} }

  /* Card macros — match the mobile reference exactly: inline
     label-value pairs side by side ("P 40g  C 10g  F 10g  Cal 500"),
     NOT stacked. Each .v2-macro-col is flex-direction:row with the
     label and value on the same baseline. Labels are sentence-case
     (not UPPERCASE) and slightly muted; values are bold dark ink.
     Mirrors .is-phone .v2-card-macros from the inline shell. */
  .v2-card-macros,
  .v2-feat-macros{
    gap:12px;
    margin-top:4px;
    /* One line — never break to a second row. Normal/wide cards keep the
       full sizing below; only narrow cards get compacted (container query
       at the end of this block) so the line still fits without clipping. */
    flex-wrap:nowrap;
  }
  .v2-card-macros .v2-macro-col,
  .v2-feat-macros .v2-macro-col{
    flex-direction:row;
    align-items:baseline;
    gap:4px;
  }
  /* Mobile macro colors/weights as reference (from inline shell):
       label: weight 700, color #B4B6C5
       value: weight 700, color #8084A0
     Desktop matches the same dimmed treatment so the macros read as a
     soft secondary line, not a bold primary one. Sizes are slightly
     bumped (8px→10px label, 10px→13px value) since desktop cards are
     wider — visual weight stays consistent with mobile despite the
     bigger size. */
  .v2-card-macros .v2-macro-lbl,
  .v2-feat-macros .v2-macro-lbl{
    font-size:10px;
    color:#B4B6C5;
    font-weight:700;
    letter-spacing:.02em;
    text-transform:none;
  }
  .v2-card-macros .v2-macro-val,
  .v2-feat-macros .v2-macro-val{
    font-size:13px;
    color:#8084A0;
    font-weight:700;
  }
  /* ── Narrow-card-only macro compaction ──
     On a normal/wide card the full "P 12g · C 2.6g · F 10g · Cal 153" line
     fits with room to spare, so it's left untouched. But at high display
     scaling / browser zoom the grid hands out much narrower cards, and the
     one line would run off the rounded edge and clip ("Cal 15…"). Make each
     card a container and, ONLY when the card itself is narrow, tighten the
     gaps + drop the value size a hair so the line still fits on one row.
     Wide cards never see these rules. */
  .v2-card,
  .v2-feat-card{ container-type:inline-size; }
  @container (max-width: 250px){
    .v2-card-macros,
    .v2-feat-macros{ gap:6px; }
    .v2-card-macros .v2-macro-col,
    .v2-feat-macros .v2-macro-col{ gap:3px; }
    .v2-card-macros .v2-macro-val,
    .v2-feat-macros .v2-macro-val{ font-size:12px; }
  }

  /* Sticky checkout pill — constrain to the column so it doesn't
     span 1920px on big monitors. Keep position:fixed; just clamp
     width and recenter horizontally.

     IMPORTANT — combined translate. The base .v2-pill rule uses
     transform:translateY(120%) for the hidden state and
     transform:translateY(0) for [data-on="1"] (the slide-up
     entrance). If we only set translateX(-50%) here, the
     [data-on="1"] rule replaces our transform entirely and the
     pill un-centers when it becomes visible. Combine both axes
     in a single transform so the show animation preserves
     horizontal centering. */
  /* Pill width: size to content but with a min-width so the three
     chunks (count/total · tier nudge · checkout) have room to breathe
     instead of crowding each other. Min 640 / max 760 at desktop.
     Height bumped 56 → 64 for vertical breathing room. */
  .v2-pill{
    left:50%;right:auto;
    transform:translate(-50%, 120%);
    width:auto;
    min-width:min(640px, calc(100vw - 32px));
    max-width:min(760px, calc(100vw - 32px));
    height:64px;
    border-radius:36px;
    padding:0 10px 0 28px;
    gap:16px;
  }
  .v2-pill[data-on="1"]{transform:translate(-50%, 0);}

  /* Tier-nudge chunk inside the pill — fills the space between the
     count/total and the checkout button. Desktop-only (@media
     min-width:1280px wraps it). White-on-navy. */
  .v2-pill-tier{
    /* Two-line stack: current rate on top, next-tier nudge below.
       Vertical flex column with the dot separator hidden. */
    display:flex;flex-direction:column;align-items:center;justify-content:center;
    flex:1 1 auto;
    text-align:center;
    color:rgba(255,255,255,.78);
    font-size:11.5px;font-weight:600;letter-spacing:-.005em;
    line-height:1.15;
    padding:0 14px;
    min-width:0;
    white-space:nowrap;overflow:hidden;
    pointer-events:none;
  }
  /* Re-color the nested tier-text spans so they're visible against navy. */
  .v2-pill-tier .v2-hero-tier-cur{color:rgba(255,255,255,.72);font-weight:700;}
  /* Hide the inline separator in the stacked layout — the two lines
     are visually paired by proximity, no dot needed. */
  .v2-pill-tier .v2-hero-tier-sep{display:none;}
  .v2-pill-tier .v2-hero-tier-next{color:#fff;font-weight:700;font-size:11.5px;}
  .v2-pill-tier .v2-hero-tier-next b{color:#E8C87A;font-weight:900;}
  .v2-pill-tier .v2-hero-tier-arrow{color:#E8C87A;font-weight:900;}

  /* Nav-hide on scroll-down — on desktop the VISIBLE nav is actually
     `.nav-desktop` (the 60px cream editorial bar created by
     /scripts/nav-drawer.js at ≥960px). The floating pill `.nav` is
     hidden via `display:none` on desktop. /scripts/nav-drawer.js
     adds `.hidden` to `#mainNav` (=.nav) on scroll-down at every
     viewport, but the matching translate rule lives only inside
     @media(max-width:720px), so on desktop the class flips with no
     visual effect.

     Piggyback on the existing class-toggle: use the body:has
     selector to translate `.nav-desktop` off-screen whenever
     `#mainNav.hidden` is set. When the nav slides off, the chip
     bar simultaneously slides up to top:0 (the page's existing
     inline `body:has(#mainNav.hidden) .v2-chips{top:0}` rule
     handles this — no override needed) so the filter strip
     glues to the top of the viewport, filling the space the nav
     just vacated. */
  body:has(#mainNav.hidden) .nav-desktop{
    transform:translateY(-100%);
    transition:transform .25s cubic-bezier(.22,1,.36,1);
  }
  .nav-desktop{transition:transform .25s cubic-bezier(.22,1,.36,1);}

  /* Chip filter bar — flush against the .nav-desktop bar above
     AND flush against the hero below. Both 0px gaps so no body
     background leaks through. When the nav slides off-screen
     (body:has(#mainNav.hidden)), the page's inline rule animates
     the chip to top:safe-area-top — i.e. glued to the top of the
     viewport.
     Slim internal chip-row vertical padding (5/5) so the bar
     reads as a filter strip, not a hero band. Fully opaque
     background so page content scrolling behind it can't show
     through. */
  .v2-chips{
    top:calc(60px + env(safe-area-inset-top, 0px));
    background:rgba(248,249,255,.985);
  }
  .v2-chips-row{padding-top:5px;padding-bottom:5px;}

  /* Body padding-top — chip-top 60 + chip-bar height ~53 =
     chip-bottom 113. No gap below the bar either; the hero's own
     line-height + the body-level zero gap mean the h1 sits flush
     under the chip bar with no empty body background showing. */
  body{padding-top:calc(113px + env(safe-area-inset-top, 0px));}
}

/* Mid-range nudge — 1280-1439 viewports keep a slightly tighter gap
   (full-bleed now, so no narrower column override needed). */
@media (min-width:1280px) and (max-width:1439px){
  .v2-grid{gap:14px;}
}

/* Very-wide nudge — full-bleed layout. The main grid is capped at 4 columns
   above (so it does NOT keep adding columns); wider gutters keep the edges
   breathing on big monitors, and the horizontal rails fit more cards. */
@media (min-width:1680px){
  :root{--v2-gutter:40px;}
  .v2-feat-card{flex:0 0 calc((100% - 56px) / 5); /* 5 cards per row */}
  .v2-bundles-row .v2-bundle-card{flex:0 0 calc((100% - 42px) / 4); /* 4 bundle cards on big screens */}
  .v2-fy-row .v2-fy-card,.v2-fy-row .v2-fy-skel{flex:0 0 calc((100% - 42px) / 4); /* 4 fy cards */}
}

/* ── Visible, draggable scrollbar on the card rails (mouse/desktop) ──
   The rails hide their scrollbars by default, so with a mouse there's no
   hint the row scrolls sideways — and macOS hides the overlay scrollbar
   until you're already scrolling. On precise-pointer devices, show a slim
   on-brand bar at EVERY width so it's obvious there's more to the right
   and there's a thumb to drag; touch devices (coarse pointer) keep the
   clean swipe view. Styling the WebKit scrollbar also opts Chrome out of
   the auto-hiding overlay, so the bar stays visible at rest. This block is
   top-level (not inside the ≥960px wrapper) and !important so it beats the
   non-important scrollbar-hiding rules in BOTH store.html (the mobile
   layout, <960px) and the ≥960px block above, regardless of load order.
   overflow-x:auto means the bar only appears when the rail actually
   overflows, so a short rail still shows nothing. */
@media (hover:hover) and (pointer:fine){
  .v2-featured-row, .v2-coll-row, .v2-bundles-row, .v2-fy-row{
    scrollbar-width:thin !important;
    scrollbar-color:rgba(27,26,107,.40) transparent;
    padding-bottom:12px;
  }
  .v2-featured-row::-webkit-scrollbar,
  .v2-coll-row::-webkit-scrollbar,
  .v2-bundles-row::-webkit-scrollbar,
  .v2-fy-row::-webkit-scrollbar{ display:block !important; height:8px; }
  .v2-featured-row::-webkit-scrollbar-track,
  .v2-coll-row::-webkit-scrollbar-track,
  .v2-bundles-row::-webkit-scrollbar-track,
  .v2-fy-row::-webkit-scrollbar-track{ background:transparent; }
  .v2-featured-row::-webkit-scrollbar-thumb,
  .v2-coll-row::-webkit-scrollbar-thumb,
  .v2-bundles-row::-webkit-scrollbar-thumb,
  .v2-fy-row::-webkit-scrollbar-thumb{ background:rgba(27,26,107,.34); border-radius:99px; }
  .v2-featured-row::-webkit-scrollbar-thumb:hover,
  .v2-coll-row::-webkit-scrollbar-thumb:hover,
  .v2-bundles-row::-webkit-scrollbar-thumb:hover,
  .v2-fy-row::-webkit-scrollbar-thumb:hover{ background:rgba(27,26,107,.55); }
}

/* ── Hover arrows on the card rails (mouse/desktop) ──────────────────
   Since the wheel no longer slides the rails (see store.html), mouse
   users need an obvious control AND a clear "there's more →" cue — the
   rails fill the column exactly 4-up, so a 5th card sits fully off-screen
   with nothing peeking. The script in store.html wraps each rail in a
   .v2-rail-wrap and injects round prev/next buttons; this styles them.
   They fade in only while the cursor is over the rail, hide at whichever
   edge you've reached, and disappear entirely when the rail doesn't
   overflow. Coarse-pointer (touch) devices never get them — they keep
   the clean swipe view. */
@media (hover:hover) and (pointer:fine){
  .v2-rail-wrap{ position:relative; }
  .v2-rail-arrow{
    position:absolute; top:50%; transform:translateY(calc(-50% - 6px));
    z-index:6; width:40px; height:40px; border-radius:50%;
    display:flex; align-items:center; justify-content:center;
    border:1px solid rgba(27,26,107,.12);
    background:rgba(255,255,255,.94); color:var(--ink,#1B1A6B);
    box-shadow:0 4px 14px rgba(27,26,107,.18);
    cursor:pointer; opacity:0;
    transition:opacity .14s ease, background .14s ease, box-shadow .14s ease;
    -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  }
  .v2-rail-arrow.prev{ left:8px; }
  .v2-rail-arrow.next{ right:8px; }
  .v2-rail-wrap:hover .v2-rail-arrow{ opacity:1; }
  .v2-rail-arrow:hover{ background:#fff; box-shadow:0 6px 18px rgba(27,26,107,.26); }
  .v2-rail-arrow:active{ transform:translateY(calc(-50% - 6px)) scale(.92); }
  .v2-rail-wrap[data-at-start] .v2-rail-arrow.prev,
  .v2-rail-wrap[data-at-end] .v2-rail-arrow.next,
  .v2-rail-wrap[data-noscroll] .v2-rail-arrow{ display:none; }
}

/* ── Wide two-column meal detail modal (June 2026) ──────────────────
   Mirrors the legacy store's wide modal (and the MightyMeals layout):
   photo fills the LEFT column edge-to-edge, all the content — name,
   description, macros, ingredients, reviews — scrolls in the RIGHT
   column. Below 1024px the sheet keeps its stacked photo-on-top
   layout from the inline CSS. Pure CSS — the sheet markup
   (grip/close/scroll>hero+body, absolute CTA bar) is untouched. */
@media (min-width:1024px){
  .v2-sheet{
    width:min(1200px, calc(100vw - 48px));
    height:min(720px, calc(100svh - 40px));
    max-height:none;
  }
  /* The scroller becomes a fixed 2-col frame; only the BODY scrolls.
     Photo column stays the larger half (56%) — wider than the detail panel
     but not so wide it starves the description/ingredients column. */
  .v2-sheet-scroll{
    display:grid;
    grid-template-columns:minmax(0,56%) minmax(0,1fr);
    grid-template-rows:100%;
    overflow:hidden;
    padding-bottom:0;
  }
  .v2-sheet-hero{
    aspect-ratio:auto;   /* fill the full column height, not 16:10 */
    height:100%;
    background:#FAF8F3;   /* cream — matches the base hero + transparent-webp photos */
  }
  /* cover => the photo fills the full, wider column edge-to-edge (it expands
     left↔right). Base rule is already cover, so no override needed here. */
  .v2-sheet-body{
    min-height:0;        /* allow the grid cell to shrink-and-scroll */
    overflow-y:auto;
    overscroll-behavior:contain;
    padding:28px 30px calc(96px + var(--safe-bot, 0px));
  }
  /* Pin the add-to-cart bar under the right column only, so it never
     covers the photo. */
  .v2-sheet-cta{left:56%;}
}

/* ── Hero photo carousel (meals with >1 photo) ──────────────────────
   Markup is injected by scripts/store-secondary.js (window._v2sec.heroCarousel)
   when a multi-photo meal sheet opens; the slide <img>s inherit the
   .v2-sheet-hero img sizing from store.html (object-fit:cover). Lives here
   (not inline) to keep store.html under its speed budget. Loaded on all
   viewports — works for the mobile sheet's swipe too. */
.v2-hero-gallery{position:absolute;inset:0;overflow:hidden;}
.v2-hero-track{display:flex;height:100%;width:100%;transition:transform .32s cubic-bezier(.2,.7,.2,1);}
.v2-hero-slide{flex:0 0 100%;height:100%;position:relative;background:#FAF8F3;}
/* Centered with margin (NOT transform) so the :active press-scale can't
   knock the button off-center. SVG chevrons center cleanly via flexbox. */
.v2-hero-nav{
  position:absolute;top:50%;margin-top:-18px;z-index:3;
  width:36px;height:36px;border-radius:50%;border:0;cursor:pointer;padding:0;
  background:rgba(255,255,255,.9);color:var(--ink,#16162e);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 2px 8px rgba(15,16,32,.18);
  transition:transform .12s ease, background .12s ease;
}
.v2-hero-prev{left:12px;}
.v2-hero-next{right:12px;}
.v2-hero-nav svg{width:18px;height:18px;display:block;}
.v2-hero-nav:hover{background:#fff;}
.v2-hero-nav:active{transform:scale(.9);}
.v2-hero-dots{position:absolute;bottom:12px;left:0;right:0;z-index:3;display:flex;justify-content:center;gap:6px;pointer-events:none;}
.v2-hero-dots span{
  width:7px;height:7px;border-radius:50%;background:rgba(255,255,255,.5);
  box-shadow:0 1px 2px rgba(15,16,32,.25);cursor:pointer;pointer-events:auto;
  transition:background .2s, transform .2s;
}
.v2-hero-dots span.is-on{background:#fff;transform:scale(1.15);}

/* ════════════════════════════════════════════════════════════════
   DOCKED DESKTOP CART  (store page, ≥1200px)
   ────────────────────────────────────────────────────────────────
   The existing slide-up cart drawer (built/owned by scripts/cart-drawer.js
   and reparented to <body>) is pinned open as a permanent right rail. JS
   (scripts/store-secondary.js → window.tandocoDockCart) adds
   body.tdco-cart-docked + .docked on the drawer; everything visual is here,
   so no extra logic is shipped. Below 1200px the class is removed and the
   cart reverts to the slide-up drawer untouched. Mobile is never affected.

   Layering: the docked rail sits at z-index 60 — above the chip bar (30)
   and page content, but BELOW the meal-detail modal (backdrop 400 / sheet
   401) so opening a meal still dims and covers the cart, and below the
   floating nav pill (315), which we re-center into the space left of the
   cart so the two don't overlap.
   ──────────────────────────────────────────────────────────────── */
@media (min-width:1200px){
  body.tdco-cart-docked{ --cart-w:380px; padding-right:var(--cart-w); }

  /* Pin the drawer as a right rail that starts BELOW the 60px editorial
     nav bar (.nav-desktop, fixed at top:0). Anchoring it at top:0 tucked
     the cart's header + first rows under the opaque nav bar as you scrolled
     — Omar: "when you scroll the cart it goes behind the nav bar, I don't
     love that." Starting at top:60 lines the cart's top up with the filter
     bar on the left, so the nav reads as one clean bar across the whole top
     and nothing scrolls underneath it. Height is implied by top + bottom:0
     (not a fixed 100vh, which would overflow past the bottom). Only `top`
     transitions, so the nav-hide follow below animates smoothly without
     re-introducing the bottom-sheet slide. */
  body.tdco-cart-docked #tdcoCartDrawer.docked{
    position:fixed; top:calc(60px + env(safe-area-inset-top, 0px)); right:0; bottom:0; left:auto;
    width:var(--cart-w); max-width:none;
    height:auto; max-height:none; margin:0;
    border-radius:0;
    transform:none !important;
    box-shadow:-10px 0 34px rgba(27,26,107,.08);
    z-index:60;
    transition:top .25s cubic-bezier(.22,1,.36,1);
  }
  /* When the nav slides off on scroll-down (#mainNav.hidden), the filter
     bar glues to the top of the viewport — bring the cart's top up with it
     so the cart and the filter bar stay aligned and no page background
     shows in the 60px gap the nav just vacated. */
  body:has(#mainNav.hidden).tdco-cart-docked #tdcoCartDrawer.docked{
    top:env(safe-area-inset-top, 0px);
  }
  /* No dimming backdrop for a permanent rail; the page stays interactive. */
  body.tdco-cart-docked #tdcoCartOverlay{ display:none !important; }
  /* Modal-only chrome the rail doesn't need. */
  body.tdco-cart-docked #tdcoCartDrawer.docked .tdco-cd-close,
  body.tdco-cart-docked #tdcoCartDrawer.docked .tdco-cd-grip{ display:none !important; }

  /* Keep the fixed top bars out from under the rail. */
  body.tdco-cart-docked .v2-chips{ right:var(--cart-w); }
  body.tdco-cart-docked .diet-filter-dock{ right:var(--cart-w); }
  /* Re-center the floating nav pill within the content area (left of the
     rail) instead of the full viewport, so its right edge can't slide
     under the cart on mid-width screens. */
  body.tdco-cart-docked .nav{ left:calc(50% - (var(--cart-w) / 2)); }

  /* The floating mobile-style checkout pill is redundant when the cart is
     always visible — Omar: "get rid of the floating checkout pill." */
  body.tdco-cart-docked .v2-pill{ display:none !important; }

  /* Checkout sheet — match the docked cart rail so the cart→checkout
     transition reads as the SAME panel flipping to its next page, not a
     new popup arriving (Omar: "doesn't feel very uniform to the new
     design"). The sheet's own ≥1100px rules (cart-checkout.js, injected
     <style>) already slide it in from the right but as a 520px, top:0,
     WHITE panel over a dimmed page — wider than the 380px rail, covering
     the nav, and a different color, so it visibly jolts. Override (these
     selectors out-specify the injected #tdcoCheckoutSheet rules, so
     source order vs the runtime <style> doesn't matter):
       · top edge under the 60px nav, exactly like the docked rail
       · width eases 380 → 460 (checkout form was tuned for ~520; 460
         keeps fields comfortable while staying close to the rail)
       · cream background + the rail's leftward shadow
     The slide-in transform from the injected rules is kept. */
  body.tdco-cart-docked #tdcoCheckoutSheet{
    top:calc(60px + env(safe-area-inset-top, 0px));
    height:auto;
    width:460px; max-width:460px;
    background:var(--cd-cream, #FBF8F2);
    /* EXACT same shadow as the docked rail — a darker variant here cast
       a visible smudge up onto the nav that the cart doesn't have. */
    box-shadow:-10px 0 34px rgba(27,26,107,.08);
  }
  /* Follow the nav-hide, same as the docked rail above. */
  body:has(#mainNav.hidden).tdco-cart-docked #tdcoCheckoutSheet{
    top:env(safe-area-inset-top, 0px);
  }
  /* (No overlay/dim rules needed: at ≥1100px cart-checkout.js already
     hides #tdcoCheckoutSheetOverlay entirely and handles click-outside-
     to-close with a document listener — the undimmed page is exactly
     the non-modal feel the docked design wants.) */

  /* Header parity with the docked cart. The sheet's own head centers
     "CHECKOUT" between a back arrow and ✕ (a mobile bottom-sheet
     pattern); the rail's head is a left-aligned title + deadline line
     ("YOUR ORDER · orders close thursday…"). Same font specs already —
     just left-align the block and match the rail's padding so the two
     panels' top edges read as the same component. ✕ stays (it's how
     you get back to the cart). */
  body.tdco-cart-docked #tdcoCheckoutSheet .tdco-cs-head{padding:18px 22px 14px;gap:12px;}
  body.tdco-cart-docked #tdcoCheckoutSheet .tdco-cs-title-block{text-align:left;align-items:flex-start;}
  body.tdco-cart-docked #tdcoCheckoutSheet .tdco-cs-subtitle{font-size:11px;}

  /* (No docked grid override: an earlier docked-shifted column scheme
     (2-up until 1500px docked) produced the giant 2-up cards Omar
     rejected — superseded by the base 3-min/4-max rule above, whose
     comment shows the math holds at the narrowest docked window.) */
}
