/* ---------- EXTRAS: loaded after styles.css, only adds/overrides ---------- */

/* Global horizontal-overflow guard. The per-element fixes below (shipping
   tables, cadence chart) contain their OWN overflow correctly, but any
   other element that's even slightly wider than the viewport — a stray
   fixed-width child, a flex/grid item that won't shrink below its content
   size — pushes the entire <body> wider than the screen, dragging the nav
   bar and everything else sideways with it. That's a page-level symptom,
   not a single-section one, so it needs a page-level backstop rather than
   chasing every possible source individually.

   overflow-x:hidden on <body> already reliably contains this, including
   the fixed-position elements (sticky CTA bar, back-to-top, cookie banner)
   that sit as direct <body> children after </footer> — overflow:hidden on
   an ancestor clips position:fixed descendants too in every current
   browser, this isn't a known gap. What's added here is a second, newer
   property (overflow-x:clip, stricter — it also blocks programmatic
   scrollLeft, not just visual scroll) alongside the original as
   reinforcement, plus repeating the same guard on header/main/footer
   individually so a future overflow source inside any one section is
   caught at that section's own boundary rather than relying solely on
   the root catching everything. */
html, body, header.site-nav, main, footer{ overflow-x:hidden; overflow-x:clip; max-width:100%; }

/* Header social icons (Instagram/TikTok). Desktop: sit in the nav-actions
   row alongside the existing icon buttons, where there's ample horizontal
   room. Mobile: hidden there and shown instead inside the hamburger
   dropdown (.mobile-social-row, appended to nav.primary-links) — adding
   two more 40px circles to an already-tight mobile header row is exactly
   the kind of horizontal-overflow risk fixed above, so they move into the
   dropdown's full-width vertical layout instead, where they fit safely at
   any screen width and are still one tap away. Icon-only, no text label,
   in a small single row — matches the minimal look of the rest of the nav
   rather than adding a bulky stacked block under the menu links. */
.mobile-social-row{ display:none; }
@media (max-width:680px){
  .nav-actions .social-icon-btn{ display:none; }
  .mobile-social-row{
    display:flex; flex-direction:row; flex-wrap:nowrap; align-items:center;
    gap:14px; margin-top:12px;
  }
  nav.primary-links .mobile-social-row a{
    display:inline-flex; align-items:center; justify-content:center;
    width:36px; height:36px; padding:0; border-radius:50%; border:1px solid var(--line-light);
    color:rgba(255,255,255,0.8); flex-shrink:0;
  }
}

/* 12. Skip to content */
.skip-link{
  position:absolute; top:-48px; left:8px; z-index:200;
  background:var(--ink); color:#fff; padding:12px 18px; border-radius:4px;
  text-decoration:none; font-weight:700; font-size:14px; transition:top 0.2s ease;
}
.skip-link:focus{ top:8px; }

/* 8. Scroll progress bar */
#scrollProgress{
  position:fixed; top:0; left:0; height:3px; width:0%; z-index:120;
  background:var(--gold); transition:width 0.1s linear;
}

/* 1. Dark mode toggle button + theme */
#darkModeToggle{ font-size:16px; }
html.dark{
  --paper:#14131F; --paper-raised:#1C1A2B; --text:#EEEDE7;
  --line: rgba(255,255,255,0.12); --line-light: rgba(255,255,255,0.18);
}
html.dark body{ background:var(--paper); color:var(--text); }
html.dark .product-card, html.dark .value-card, html.dark .setguide-card,
html.dark .archive-year, html.dark .archive-year-toggle{
  background:var(--paper-raised); border-color:var(--line);
}
html.dark .section-head p, html.dark .product-meta, html.dark .value-card p{ color:#B9B6CC; }
html.dark .glossary-chip, html.dark .weight-chip, html.dark .market-disclaimer,
html.dark .sg-market{ background:#201E30; color:#EEEDE7; }
html.dark .field input, html.dark .field select, html.dark .modal-panel{
  background:#201E30; color:#EEEDE7; border-color:var(--line);
}

/* 3. Site search */
.site-search{
  display:flex; align-items:center; gap:8px; margin:0 0 24px;
  background:var(--paper-raised); border:1px solid var(--line); border-radius:4px;
  padding:10px 14px; max-width:340px;
}
.site-search input{
  border:none; background:transparent; font-size:14px; width:100%; font-family:inherit;
  color:inherit;
}
.site-search input:focus-visible{ outline:none; }

/* 4. Back to top */
#backToTop{
  position:fixed; right:20px; bottom:20px; z-index:80;
  width:44px; height:44px; border-radius:50%; border:none;
  background:var(--ink); color:#fff; font-size:18px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  opacity:0; pointer-events:none; transform:translateY(8px);
  transition:opacity 0.2s ease, transform 0.2s ease;
  box-shadow:0 8px 20px rgba(0,0,0,0.25);
}
#backToTop.visible{ opacity:1; pointer-events:auto; transform:translateY(0); }
#backToTop:hover{ background:var(--red); }

/* 20. Floating contact button */
#floatingContact{
  position:fixed; right:20px; bottom:76px; z-index:80;
  width:44px; height:44px; border-radius:50%; border:none;
  background:var(--gold); color:var(--ink); font-size:18px; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 8px 20px rgba(0,0,0,0.25);
}
#floatingContactPanel{
  position:fixed; right:20px; bottom:130px; z-index:81;
  background:#fff; border:1px solid var(--line); border-radius:6px;
  padding:16px; width:240px; box-shadow:0 16px 40px rgba(0,0,0,0.25);
  display:none;
}
#floatingContactPanel.open{ display:block; }
#floatingContactPanel p{ margin:0 0 10px; font-size:13.5px; }
.copy-btn{
  background:var(--paper); border:1px solid var(--line); border-radius:4px;
  padding:7px 10px; font-size:12.5px; font-weight:700; cursor:pointer; width:100%;
}
.copy-btn:hover{ border-color:var(--ink); }

/* 2. Cookie banner */
#cookieBanner{
  display:none; position:fixed; left:0; right:0; bottom:0; z-index:150;
  background:var(--ink); color:#fff; padding:16px 20px;
  align-items:center; justify-content:center; gap:16px; flex-wrap:wrap;
  box-shadow:0 -4px 20px rgba(0,0,0,0.25);
}
#cookieBanner p{ margin:0; font-size:13px; max-width:60ch; color:rgba(255,255,255,0.85); }
#cookieBanner button{
  background:var(--gold); color:var(--ink); border:none; padding:9px 18px;
  border-radius:2px; font-weight:700; font-size:13px; cursor:pointer; white-space:nowrap;
}

/* 19. FAQ accordion */
.faq-item{ border-bottom:1px solid var(--line); }
.faq-question{
  width:100%; text-align:left; background:none; border:none; cursor:pointer;
  padding:16px 4px; display:flex; justify-content:space-between; align-items:center;
  font-family:inherit; font-size:15.5px; font-weight:700; color:inherit;
}
.faq-question .faq-chev{ transition:transform 0.2s ease; font-size:13px; flex-shrink:0; margin-left:12px; }
.faq-item.open .faq-chev{ transform:rotate(180deg); }
.faq-answer{ display:none; padding:0 4px 16px; font-size:14px; color:#4A4763; line-height:1.6; }
.faq-item.open .faq-answer{ display:block; }
html.dark .faq-answer{ color:#B9B6CC; }

/* 6. Loading skeleton for product grid while live fetch resolves */
.product-grid.is-loading{ position:relative; min-height:190px; }
.product-grid.is-loading::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,0.35), transparent);
  background-size:200% 100%; animation:skeletonSheen 1.2s ease-in-out infinite;
  pointer-events:none;
}
@keyframes skeletonSheen{ 0%{background-position:200% 0;} 100%{background-position:-200% 0;} }

/* 18. Last updated date */
.last-updated{ font-size:12px; color:rgba(255,255,255,0.4); margin-top:6px; }

/* 10. Print stylesheet */
@media print{
  header.site-nav, .hero-ctas, .btn, .icon-btn, .nav-actions, #backToTop,
  #floatingContact, #floatingContactPanel, #cookieBanner, .cart-count,
  .footer-admin-row, .drawer, .modal, .overlay, .site-search, #darkModeToggle,
  .hero-bg-parallax, .hero-scrim, .skip-link, #stickyMobileCta{
    display:none !important;
  }
  body{ background:#fff !important; color:#000 !important; }
  a{ color:#000 !important; text-decoration:underline; }
  .hero{ background:#fff !important; color:#000 !important; padding:20px 0; }
  section{ padding:24px 0; }
}

/* Sticky mobile CTA — pinned "Shop" button on narrow screens only. Reads
   "View cart (N)" instead once there's something in the cart, mirroring the
   existing #cartCount badge rather than tracking cart state separately. */
#stickyMobileCta{
  display:none;
  position:fixed; left:0; right:0; bottom:0; z-index:90;
  background:var(--ink); border-top:1px solid rgba(255,255,255,0.08);
  padding:10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
  box-shadow:0 -6px 20px rgba(0,0,0,0.25);
}
#stickyMobileCta button{
  width:100%; display:flex; align-items:center; justify-content:center; gap:8px;
  background:var(--gold); color:var(--ink); border:none; border-radius:4px;
  padding:13px 16px; font-size:14.5px; font-weight:800; cursor:pointer;
}
.sticky-cta-count{
  background:var(--ink); color:#fff; border-radius:50%; min-width:20px; height:20px; padding:0 5px;
  display:inline-flex; align-items:center; justify-content:center; font-size:11.5px;
}
@media (max-width:680px){
  #stickyMobileCta.visible{ display:block; }
  /* lift the other fixed mobile buttons clear of the sticky bar */
  #backToTop{ bottom:78px; }
  #floatingContact{ bottom:134px; }
  #floatingContactPanel{ bottom:188px; }
}

/* ---------------- MOBILE POLISH ----------------
   The base stylesheet (styles.css) uses the same 84px section padding,
   32px modal padding, and 48px newsletter padding at every viewport width
   — reasonable on desktop, but on a phone that's a lot of dead scrolling
   and cramped forms/tables. These tighten spacing and fix a real overflow
   risk (the 4-5 column shipping tables) specifically under 680px, without
   touching the desktop layout at all. */
@media (max-width:680px){
  section{ padding:52px 0; }

  .hero{ padding:40px 0 56px; }
  .hero-inner{ gap:32px; }
  .hero h1{ font-size:32px; }
  .hero p.lede{ font-size:15.5px; margin-top:16px; }
  .hero-tagline{ font-size:17px; }
  .hero-ctas{ margin-top:26px; }
  .hero-showcase-item{ height:170px; }

  /* On desktop the heading and "view more" / link sit side by side with
     justify-content:space-between — on a narrow phone that squeezes both
     into half-width columns. Stacking them keeps each readable at full
     width instead. */
  .section-head{ flex-direction:column; align-items:flex-start; gap:10px; margin-bottom:26px; }
  .section-head h2{ font-size:24px; }
  .section-head p{ font-size:14px; }

  .product-grid{ gap:18px; }
  .values-grid{ gap:16px; }
  .value-card{ padding:20px 18px; }
  .cat-card{ padding:20px 18px; min-height:110px; }

  .newsletter{ padding:28px 22px; text-align:left; }
  .newsletter h2{ font-size:22px; }

  .modal-panel{ padding:22px 18px; }
  .modal-panel h2{ font-size:20px; }

  /* Shipping tables have 4-5 columns — too many to fit a ~340px content
     width without either shrinking text unreadably or overflowing the
     page. Scrolling the table itself sideways (inside its own wrapper,
     see .table-scroll below) keeps every column legible instead of
     forcing the whole page to scroll horizontally. */
  .table-scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; margin:0 0 22px; }
  .table-scroll .shipping-table{ margin:0; min-width:480px; }

  .setguide-card{ padding:18px; }
  .archive-intro{ font-size:13px; }

  /* The release-cadence bar chart renders one column per year (~18 of
     them) via flex:1 columns with no minimum width — on a narrow screen
     that squeezes every column below its label's own content width and
     pushes the chart past the edge of the page instead of wrapping.
     Giving each column a fixed width and letting the chart itself scroll
     sideways (same pattern as the shipping tables above) keeps every
     bar and label readable instead. */
  .chart-scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; margin:0 -4px; padding:0 4px 6px; width:100%; max-width:100%; }
  .cadence-chart .bars{ width:max-content; min-width:100%; }
  .cadence-chart .bar-col{ flex:0 0 42px; }
}

@media (max-width:400px){
  .hero-showcase{ grid-template-columns:1fr; }
  .hero-showcase-item{ height:150px; }
}

/* ---------- Header + hero fixes (Oct 2026) ----------
   The header is sticky and sits above the hero rather than over it, so a
   transparent background showed the cream page behind white nav text and
   the links were close to invisible until you scrolled. Solid ink fixes it.
   .nav-inner's "padding:18px 0" also wiped the side padding from .wrap,
   which pushed the logo against the screen edge on phones. */
header.site-nav{ background:var(--ink); }
.nav-inner{ padding-left:28px; padding-right:28px; }
.hero h1{ max-width:17ch; }
@media (max-width:680px){
  .nav-inner{ padding:12px 16px; }
  .nav-actions{ gap:8px; }
  .hero h1{ max-width:none; }
}

/* Checkout shipping choices: ".field label" and ".field input" (from the
   form styles) out-rank ".shipping-option", so each option rendered as a
   block with a full-width radio button stacked above its text. */
.field .shipping-option{ display:flex; align-items:flex-start; font-size:13.5px; font-weight:400; margin-bottom:0; }
.field .shipping-option input{ width:auto; padding:0; margin-top:3px; }

/* Cookie notice sat above the cart drawer and checkout modal (150 vs
   100/110), covering the Checkout button for anyone who hadn't clicked
   "Got it" yet. Keep it under the overlay so the cart always works. */
#cookieBanner{ z-index:80; }

/* ---------- Accessibility: text contrast in both themes ----------
   Every colour here was checked against the backgrounds it sits on for a
   contrast ratio of at least 4.5 to 1 (WCAG AA). Dark mode used to leave a
   lot of text in its light-theme colour: dark grey, dark red and near-black
   on a near-black page, and the nav text almost invisible. */
:root{ --muted:#5C5975; --soft:#4A4763; --link:#A6331F; --up:#2F6E5B; --down:#A6331F; --on-dark:#F8F7F2; }
html.dark{ --muted:#B9B6CC; --soft:#CFCCE0; --link:#FF9C8A; --up:#7AD3B6; --down:#FF9C8A; }

/* The nav, hero and footer sit on the dark ink colour in both themes, so
   their text stays light instead of following the page colour. */
.brand, .brand-mark, nav.primary-links a, .icon-btn, .hero{ color:var(--on-dark); }

.price .was, .cart-item-info .unit, .empty-cart, .modal-sub, .field-hint,
.shipping-option .so-eta, .shipping-table th, .setguide-card .sg-code,
.sg-market small, .sg-market-note, .cadence-chart .bar-year, .cadence-caption,
.archive-year-toggle .count, .archive-set-name .code, .archive-set-meta,
.admin-table th, .order-filter-row .order-count, .order-card-head .order-date,
.order-card-section h4, .legal-updated{ color:var(--muted); }

.section-head p, .value-card p, .security-note, .setguide-card .sg-spec,
.market-disclaimer, .archive-intro{ color:var(--soft); }

.setguide-card .sg-link, .value-card a, .security-note a, .about-card a,
html .legal-wrap a{ color:var(--link); }
.trend-up, .sg-market .trend-up, .stock-tag.in{ color:var(--up); }
.trend-down, .sg-market .trend-down, .stock-tag.low{ color:var(--down); }
/* Year and footer headings are h3 now (they followed an h2, so h4 skipped a level). Same look as before. */
.footer-grid h3{ color:#fff; font-size:14px; margin-bottom:16px; font-weight:700; }
.archive-year-toggle h3{ font-family:'Shippori Mincho', serif; font-size:17px; margin:0; color:inherit; }

/* Buttons do not inherit text colour by default, so these were black in
   dark mode. */
.archive-year-toggle, .archive-year-toggle h4, button.archive-set-row, .faq-question,
.modal-close, .drawer-close, .qty-btn{ color:inherit; }
html.dark .glossary-chip strong, html.dark .weight-chip strong{ color:var(--text); }
html.dark .shipping-option:has(input:checked){ border-color:var(--gold); }
html.dark .drawer{ background:var(--paper-raised); color:var(--text); }

/* White on the brand red was 4.4 to 1. A slightly deeper red passes. */
.btn-primary, .newsletter{ background:#C93A23; }
.newsletter p{ color:#fff; }
.last-updated{ color:rgba(255,255,255,0.66); }
.admin-corner{ color:rgba(255,255,255,0.62); }

/* Scrollable chart and tables can be focused and scrolled from the keyboard. */
.chart-scroll:focus-visible, .table-scroll:focus-visible{ outline:3px solid var(--gold); outline-offset:2px; }
/* The search box had its focus ring switched off. */
.site-search input:focus-visible{ outline:3px solid var(--gold); outline-offset:2px; }
.checkout-consent{ font-size:12px; color:var(--muted); margin:10px 0 0; text-align:center; }
.checkout-consent a{ color:var(--link); }

/* Second row of market tiles (7-day, 30-day, card range, grade). */
.sg-market .sg-row-break{ flex-basis:100%; height:0; border-top:1px solid var(--line); margin:0; }

/* Product names in the shop link to each box's own page. */
.product-card h3 a.product-link{color:inherit; text-decoration:none;}
.product-card h3 a.product-link:hover{text-decoration:underline; text-underline-offset:3px;}
.box-links{margin:18px 0 0; font-size:14px; color:#4A4763; line-height:1.8;}
.box-links a{color:inherit;}

/* ---------- Page speed fixes (Oct 2026) ----------
   The four hero tiles are built by shop.js after the first paint. Reserve
   their space up front so the trust bar and everything below don't jump
   down when they appear (Google counts that as layout shift). Heights match
   the tiles as they render today: 300px each, 18px gap, 4 across on wide
   screens, 2 across up to 680px, 1 across up to 400px. */
.hero-showcase{ min-height:300px; }
@media (max-width:680px){
  .hero-showcase{ min-height:618px; }
  /* Phones get a narrower, lighter crop of the same hero picture (13KB vs 132KB). */
  .hero-bg-parallax{ background-image:url('images/hero-bg-mobile.webp'); }
}
@media (max-width:400px){
  .hero-showcase{ min-height:1254px; }
}
/* The light sweep across each box tile used to animate background-position,
   which makes the browser repaint all ten tiles on every frame (Google flags
   it as heavy main-thread work on phones). Same sweep, moved with transform
   instead, which the GPU handles without repainting. */
.product-art::before{
  background-size:100% 100%;
  animation:sheenMove 4.5s ease-in-out infinite;
  will-change:transform;
}
@keyframes sheenMove{
  0%{ transform:translateX(-100%); }
  100%{ transform:translateX(100%); }
}

/* Newsletter: optional "restocks and new sets" tick box. */
.nl-optin{flex-basis:100%; display:flex; align-items:flex-start; gap:8px; font-size:13.5px; line-height:1.4; color:#fff; cursor:pointer;}
.nl-optin input{width:18px; height:18px; margin:1px 0 0; flex:0 0 auto; accent-color:var(--gold, #C8952E);}

/* "Email me when it's back" on sold-out boxes (shop cards and box pages). */
.stock-alert-form{display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; position:relative;}
.stock-alert-form[hidden]{display:none;}
.stock-alert-form input[type="email"]{flex:1 1 180px; min-width:0; padding:10px 12px; border:1px solid rgba(20,19,42,0.25); border-radius:8px; font:inherit; font-size:15px; background:#fff; color:#14132A;}
.stock-alert-form .btn{flex:0 0 auto;}
.stock-alert-note{flex-basis:100%; margin:0; font-size:13px; color:#4A4763;}
.stock-alert-note a{color:inherit;}
.notify-btn[hidden]{display:none;}
