.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

.skip-link {
  position: absolute; top: -100px; left: 12px; z-index: 1000;
  background: var(--black-900); color: var(--white); padding: 10px 18px;
  border-radius: var(--radius-md); font-weight: 700; text-decoration: none;
  transition: top 0.15s ease;
}
.skip-link:focus { top: 12px; }
#main-content:focus { outline: none; }

/* Build Your Brand — shared design system
   Palette sourced from the real BYB logo (black badge, red/gold split ring,
   red/gold/white mark). Applied per the 60-30-10 rule rather than at equal
   weight everywhere: black carries structure (header/nav/footer/hero) ~60%,
   white/neutral carries content backgrounds ~30%, and red+gold together are
   the ~10% accent — gold for primary CTAs (highest contrast, does the job
   professional e-commerce guidance assigns to a single dominant action
   color), red reserved for emphasis (links, active states, category tags,
   urgency badges) the way the logo itself only reds out the word "YOUR". */

:root {
  /* Fallback only - main.js's syncHeaderHeight() overwrites this with the
     real, measured height of header.site-header on load/resize, since
     that height varies (nav can wrap to a second line at some widths).
     Used by anything that also sticks below the header, e.g.
     .filter-panel - see that function's comment for the real bug this
     fixed (August 2026). */
  --header-height: 100px;
  --black-900: #0d0d0d;
  --black-800: #1a1a1a;
  --black-700: #262626;
  --black-600: #333333;
  --red-600: #e2231a;
  --red-700: #b81b14;
  --red-100: #fdeceb;
  --gold-500: #f4b400;
  --gold-600: #d69e00;
  --gold-700: #8a6300; /* WCAG-AA-safe gold for text on white (gold-500/600 fail contrast there) */
  --ink: #101418;
  --slate-700: #3a4552;
  --slate-500: #66707b;
  --slate-300: #c3cad2;
  --slate-100: #eef1f4;
  --white: #ffffff;
  --success: #1a7a48; /* darkened from #1f8a53: that failed WCAG AA (~4.35:1) on white, this passes (~5.36:1) */
  --radius-sm: 6px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --shadow-card: 0 2px 10px rgba(13, 13, 13, 0.08);
  --shadow-hover: 0 12px 28px rgba(13, 13, 13, 0.18);
  --container: 1240px;
  font-size: 16px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--white);
  line-height: 1.5;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, h4 { margin: 0 0 0.5em; line-height: 1.2; font-weight: 700; }
p { margin: 0 0 1em; color: var(--slate-700); }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 24px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 22px;
  border-radius: var(--radius-sm);
  font-weight: 600;
  font-size: 0.95rem;
  border: 2px solid transparent;
  cursor: pointer;
  transition: all 0.15s ease;
}
.btn-primary { background: var(--gold-500); color: var(--black-900); }
.btn-primary:hover { background: var(--gold-600); }
.btn-outline { border-color: var(--white); color: var(--white); background: transparent; }
.btn-outline:hover { background: rgba(255,255,255,0.12); }
/* Real bug found 2026-09-12 (site owner report, shop.html "Corporate Gifts"
   pagination): .btn-outline is designed for dark backgrounds (white text/
   border on transparent) - correct on hero/CTA sections, but invisible
   (white-on-white) wherever it sits on the site's default white page
   background instead - shop.html's pagination controls and empty-state
   buttons, several quote.html/index.html/brand-your-school.html buttons.
   Flipping the shared .btn-outline would just break its many correct
   dark-background uses, so this is an explicit opt-in for outline buttons
   that sit on a light background. */
.btn-outline-dark { border-color: var(--slate-300); color: var(--black-900); background: transparent; }
.btn-outline-dark:hover { background: rgba(0,0,0,0.04); }
.btn-dark { background: var(--black-800); color: var(--white); }
.btn-dark:hover { background: var(--black-700); }
.btn-sm { padding: 8px 14px; font-size: 0.85rem; }
.btn-block { width: 100%; }
.btn:disabled, .btn:disabled:hover {
  background: var(--slate-100);
  color: var(--slate-500);
  cursor: not-allowed;
  border-color: transparent;
}

/* ---------- Focus visibility (keyboard navigation) ---------- */
/* Plain gold-500 fails WCAG 1.4.11 non-text contrast (3:1) against white
   content sections, even though it reads fine on black header/hero/footer
   surfaces - a dark inner ring + gold outer ring gives a visible indicator
   against both light and dark backgrounds at once, rather than picking a
   single colour that only works on half the site. */
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--black-900);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--gold-500);
  border-radius: 2px;
}

/* ---------- Top utility bar ---------- */
.topbar {
  background: var(--black-900);
  color: var(--slate-300);
  font-size: 0.82rem;
}
/* Real mobile bug (site-owner screenshot, September 2026): a fixed
   height:36px meant that on narrow phones, where the address+hours text
   alone fills the row and pushes phone/email onto a wrapped second line,
   that second line's bottom half got visually covered by the header
   below it - the container never grew to fit its own wrapped content.
   min-height lets it grow instead of clipping. */
.topbar .container { display: flex; justify-content: space-between; align-items: center; min-height: 36px; flex-wrap: wrap; gap: 8px; padding: 6px 0; }
.topbar a { color: var(--slate-300); }
.topbar a:hover { color: var(--white); }
.topbar-links { display: flex; gap: 18px; }

/* ---------- Header / mega menu ---------- */
header.site-header {
  background: var(--white);
  border-bottom: 1px solid var(--slate-100);
  position: sticky;
  top: 0;
  z-index: 100;
  box-shadow: 0 1px 0 rgba(0,0,0,0.03);
}
.header-row {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 16px 24px;
  max-width: var(--container);
  margin: 0 auto;
}
.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}
.logo-mark { height: 44px; width: 44px; border-radius: 50%; flex-shrink: 0; }
.logo-text {
  font-size: 1.35rem;
  font-weight: 800;
  color: var(--black-900);
  letter-spacing: -0.01em;
}
.logo-text span { color: var(--red-600); }
.search-bar {
  flex: 1;
  display: flex;
  border: 2px solid var(--slate-100);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.search-bar input {
  flex: 1;
  border: none;
  padding: 11px 14px;
  font-size: 0.95rem;
  outline: none;
}
.search-bar button {
  background: var(--black-900);
  color: var(--white);
  border: none;
  padding: 0 18px;
  cursor: pointer;
  font-weight: 600;
}
.header-actions { display: flex; align-items: center; gap: 22px; }
.header-action { display: flex; flex-direction: column; align-items: center; font-size: 0.75rem; color: var(--slate-700); position: relative; min-width: 46px; }
.header-action .icon { font-size: 1.3rem; }

/* Inline SVG icons (see assets/js/icons.js) - sized off font-size like the
   emoji they replaced, coloured via `color` (SVGs use stroke="currentColor"). */
[data-icon] svg, .icon svg { width: 1em; height: 1em; display: block; stroke: currentColor; }
[data-icon], .icon { display: inline-flex; align-items: center; justify-content: center; }
.quote-count {
  position: absolute;
  top: -6px;
  right: -2px;
  background: var(--gold-500);
  color: var(--black-900);
  font-size: 0.68rem;
  font-weight: 800;
  border-radius: 50%;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.nav-toggle {
  display: none;
  background: none;
  border: none;
  color: var(--black-900);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  padding: 6px 10px;
  margin-left: auto;
}

nav.main-nav {
  background: var(--black-900);
}
.main-nav .container { display: flex; align-items: stretch; }
.main-nav ul { display: flex; flex-wrap: wrap; }
.main-nav > .container > ul > li { position: relative; }
.main-nav a.nav-link {
  display: block;
  padding: 13px 16px;
  color: var(--white);
  font-size: 0.9rem;
  font-weight: 600;
}
.main-nav > .container > ul > li:hover .nav-link,
.main-nav a.nav-link.active { background: var(--black-700); color: var(--gold-500); }

.nav-item-with-toggle { display: flex; align-items: stretch; justify-content: space-between; }
/* Real mobile bug (site-owner report, September 2026 - "Displays, Banners &
   Signage looks dead when I tap it"): .nav-link here only sized to its own
   text (justify-content: space-between left the toggle button pinned to the
   far right), so on a full-width mobile row there was a wide dead gap
   between the text and the arrow that looked tappable but wasn't - affects
   every nav item with a submenu (Corporate Gifts, Clothing & Uniforms,
   Displays/Banners/Signage), not just one. flex: 1 lets the link fill all
   the space the toggle button isn't using, so the whole row minus the arrow
   itself navigates on tap. No visible effect on desktop, where the wrapper
   already shrinks to fit its content. */
.nav-item-with-toggle .nav-link { flex: 1; }
.mega-toggle {
  display: none;
  background: none;
  border: none;
  color: var(--white);
  font-size: 0.7rem;
  cursor: pointer;
  padding: 0 14px;
  transition: transform 0.15s ease;
}
.main-nav li.mega-open .mega-toggle { transform: rotate(180deg); }

.mega-panel {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  background: var(--white);
  box-shadow: var(--shadow-hover);
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  padding: 24px;
  min-width: 620px;
  gap: 28px;
  grid-template-columns: repeat(3, 1fr);
  z-index: 50;
}
/* Desktop/pointer: hover OR keyboard focus opens the mega-panel. Scoped to
   min-width so it doesn't fight the mobile accordion (.mega-open) below,
   which is what makes this reachable on touch devices - :hover alone never
   fires on a tap, so touch users could never open this menu before. */
@media (min-width: 981px) {
  .main-nav li:hover .mega-panel,
  .main-nav li:focus-within .mega-panel { display: grid; }
}
.mega-col h4 { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--red-600); margin-bottom: 10px; }
.mega-col a { display: block; padding: 6px 0; font-size: 0.9rem; color: var(--slate-700); }
.mega-col a:hover { color: var(--black-800); text-decoration: underline; }
.mega-badge {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 800;
  text-transform: uppercase;
  background: var(--red-100);
  color: var(--red-600);
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 6px;
  vertical-align: middle;
}

/* ---------- Hero ---------- */
.hero {
  background: linear-gradient(120deg, var(--black-900), var(--black-700));
  color: var(--white);
  padding: 64px 0 56px;
}
.hero .container { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 48px; align-items: center; }
.hero-eyebrow { color: var(--gold-500); font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; font-size: 0.8rem; margin-bottom: 12px; }
.hero h1 { font-size: 2.6rem; margin-bottom: 16px; }
.hero p.lead { color: var(--slate-300); font-size: 1.08rem; max-width: 52ch; }
.hero-cta { display: flex; gap: 14px; margin-top: 26px; flex-wrap: wrap; }
.hero-stats { display: flex; gap: 28px; margin-top: 36px; flex-wrap: wrap; }
.hero-stats div strong { display: block; font-size: 1.5rem; color: var(--gold-500); }
.hero-stats div span { font-size: 0.8rem; color: var(--slate-300); }
.hero-art {
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.14);
  border-radius: var(--radius-lg);
  padding: 20px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}
.hero-art .tile {
  aspect-ratio: 1;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.2rem;
  color: var(--gold-500);
  background: rgba(255,255,255,0.08);
}
.hero-art-photo { padding: 0; overflow: hidden; display: block; }
.hero-art-photo picture, .hero-art-photo img { display: block; width: 100%; height: auto; border-radius: var(--radius-lg); }

/* ---------- Trust strip ---------- */
.trust-strip { background: var(--slate-100); padding: 22px 0; }
.trust-strip .container { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.trust-item { display: flex; align-items: center; gap: 10px; font-size: 0.88rem; font-weight: 600; color: var(--black-800); }
.trust-item .icon { font-size: 1.3rem; }

/* ---------- Sections ---------- */
.section { padding: 56px 0; }
.section-alt { background: var(--slate-100); }
.section-head { display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 30px; gap: 20px; flex-wrap: wrap; }
.section-head h1, .section-head h2 { font-size: 1.7rem; color: var(--black-900); margin: 0; }
.section-head p { margin: 4px 0 0; }
.section-head .link-more { font-weight: 700; color: var(--red-600); white-space: nowrap; }

/* Category tiles */
.category-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.category-card {
  background: var(--white);
  border: 1px solid var(--slate-100);
  border-radius: var(--radius-md);
  padding: 22px;
  text-align: center;
  box-shadow: var(--shadow-card);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.category-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); }
.category-card .icon { font-size: 2.1rem; margin-bottom: 10px; color: var(--red-600); }
.category-card h3 { font-size: 1rem; margin-bottom: 4px; }
.category-card p { font-size: 0.82rem; margin-bottom: 0; }
.category-card .new-tag {
  display: inline-block;
  background: var(--gold-500);
  color: var(--black-900);
  font-size: 0.65rem;
  font-weight: 800;
  padding: 2px 8px;
  border-radius: 999px;
  margin-top: 8px;
}

/* Product grid & cards */
.product-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.product-card {
  border: 1px solid var(--slate-100);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--white);
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.product-card:hover { box-shadow: var(--shadow-hover); transform: translateY(-3px); }
.product-thumb {
  aspect-ratio: 4/3;
  background: var(--slate-100);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.6rem;
  position: relative;
  overflow: hidden;
}
.product-thumb img { width: 100%; height: 100%; object-fit: cover; }
.product-thumb .ribbon {
  position: absolute;
  top: 10px;
  left: 10px;
  background: var(--black-900);
  color: var(--white);
  font-size: 0.66rem;
  font-weight: 800;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 4px;
}
.product-thumb .ribbon.low { background: var(--red-700); }
.product-thumb .ribbon.eco { background: var(--success); }
.product-body { padding: 14px 16px 18px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.product-cat { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--red-600); font-weight: 700; }
.product-name { font-size: 0.98rem; font-weight: 700; color: var(--black-900); }
.product-desc { font-size: 0.82rem; color: var(--slate-500); flex: 1; }
/* Was gated behind body.customer-logged-in as a placeholder from before any
   supplier had real pricing loaded ("a safe no-op now" - no product had a
   priceFrom value yet, so the gate never actually mattered). Real pricing
   now exists across most of the catalogue (2026-09-06: Amrod, Captivity,
   National Flag, Headwear24, Mass Supply, King Caps, and more), and the
   site owner confirmed real approved prices should show to every visitor,
   not just logged-in customers - the login gate is removed; visibility is
   controlled entirely by productCard() only rendering this when a real
   priceFrom exists (assets/js/main.js). */
.product-price { display: block; font-weight: 800; color: var(--red-600); font-size: 0.9rem; }
.stock-row { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; font-weight: 600; }
.stock-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success); }
.stock-dot.low { background: var(--gold-700); }
.stock-dot.out { background: var(--red-700); }
.stock-dot.unknown { background: var(--slate-500); }
.stock-row.in { color: var(--success); }
.stock-row.low { color: var(--gold-700); }
.stock-row.out { color: var(--red-700); }
.stock-row.unknown { color: var(--slate-500); }
.product-actions { display: flex; gap: 8px; margin-top: 8px; }

/* Display Combos (specials.html / displays-combos.html, CLAUDE_WEBSITE_AND_
   BREVO_DIRECTIVE.md) - reuses .product-card/.product-body/.product-cat/
   .product-name/.product-desc/.product-actions above (same visual system
   sitewide), with its own media wrapper for the required 1:1 aspect ratio
   (directive section 4: "Images must use a consistent 1:1 aspect ratio,
   object-fit: cover") - the general .product-thumb is 4:3, wrong ratio for
   these specific assets. */
.combo-card { border: 1px solid var(--slate-100); border-radius: var(--radius-md); overflow: hidden; background: var(--white); box-shadow: var(--shadow-card); display: flex; flex-direction: column; transition: box-shadow 0.15s ease, transform 0.15s ease; }
.combo-card:hover { box-shadow: var(--shadow-hover); transform: translateY(-3px); }
.combo-card-media { aspect-ratio: 1/1; background: var(--slate-100); overflow: hidden; }
.combo-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.combo-filter-bar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 24px; }
.combo-filter-bar button { background: var(--slate-100); border: none; padding: 9px 18px; border-radius: 999px; font-weight: 600; font-size: 0.88rem; cursor: pointer; color: var(--black-900); }
.combo-filter-bar button.active { background: var(--black-900); color: var(--white); }
.combo-filter-bar button:focus-visible { outline: 2px solid var(--red-600); outline-offset: 2px; }

/* Testimonials */
.testimonial-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.testimonial-card {
  background: var(--white);
  border-left: 4px solid var(--gold-500);
  border-radius: var(--radius-sm);
  padding: 22px;
  box-shadow: var(--shadow-card);
}
.testimonial-card .stars { color: var(--gold-700); margin-bottom: 10px; }
.testimonial-card footer { margin-top: 12px; font-weight: 700; font-size: 0.85rem; color: var(--black-900); }

/* Company store callout */
.callout {
  background: var(--black-900);
  color: var(--white);
  border-radius: var(--radius-lg);
  padding: 40px;
  display: grid;
  grid-template-columns: 1.3fr 0.7fr;
  gap: 30px;
  align-items: center;
}
.callout h2 { color: var(--white); }
.callout .badge { background: var(--gold-500); color: var(--black-900); font-weight: 800; font-size: 0.72rem; text-transform: uppercase; padding: 4px 10px; border-radius: 999px; }

/* Filters + shop layout */
.shop-layout { display: grid; grid-template-columns: 260px 1fr; gap: 30px; align-items: start; }
.filter-panel {
  background: var(--white);
  border: 1px solid var(--slate-100);
  border-radius: var(--radius-md);
  padding: 20px;
  position: sticky;
  /* Was a hardcoded 100px, which broke (header covering the top of the
     filter list) the moment the sticky header's real height grew past that
     guess - e.g. the main nav wrapping to a second line at some widths
     once it had one more item than it used to. --header-height is the
     real, measured header height (see syncHeaderHeight() in main.js) with
     this fallback only for the instant before JS first runs. */
  top: calc(var(--header-height) + 12px);
  /* Sticky alone locks the panel rigid once its own content is taller than
     the space left below it - a customer then has to scroll the WHOLE page
     past the product grid just to reach lower filters, effectively
     unusable on a catalogue this size (real user feedback, August 2026).
     Letting the panel scroll independently once it hits the sticky
     position fixes that without giving up sticky's main benefit (filters
     stay visible while browsing). */
  max-height: calc(100vh - var(--header-height) - 32px);
  overflow-y: auto;
}
.filter-group { margin-bottom: 22px; }
/* Real user feedback (August 2026): "colour and gender searches are too far
   down." The category list (118+ entries, nested parent/child) rendered
   inline pushed every filter below it far down the panel's own internal
   scroll - Colour/Gender were technically second/third in the DOM, but a
   shopper had to scroll past the entire category tree to reach them.
   Giving the category list its own short, independently-scrolling box
   keeps the conventional "Category first" order while making Colour and
   Gender visible immediately underneath, no scrolling required. */
#category-filters { max-height: 220px; overflow-y: auto; padding-right: 4px; }
.color-filter-row { display: flex; flex-wrap: wrap; gap: 8px; }
.color-filter-swatch {
  width: 26px; height: 26px; border-radius: 50%; border: 2px solid transparent;
  cursor: pointer; padding: 0; box-shadow: 0 0 0 1px rgba(0,0,0,0.15) inset;
  position: relative;
}
.color-filter-swatch[aria-pressed="true"] { border-color: var(--gold-600); box-shadow: 0 0 0 1px rgba(0,0,0,0.15) inset, 0 0 0 2px var(--white); }
.color-filter-swatch[aria-pressed="true"]::after {
  content: "\2713"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: #fff; text-shadow: 0 0 2px rgba(0,0,0,0.8);
}
.filter-group h4 { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 10px; color: var(--black-800); }
.filter-group label { display: flex; align-items: center; gap: 8px; font-size: 0.88rem; padding: 4px 0; color: var(--slate-700); cursor: pointer; }
.results-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; flex-wrap: wrap; gap: 10px; }
.results-bar select { padding: 8px 10px; border-radius: var(--radius-sm); border: 1px solid var(--slate-300); }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { background: var(--red-100); color: var(--red-600); font-size: 0.8rem; font-weight: 600; padding: 5px 12px; border-radius: 999px; display: inline-flex; align-items: center; gap: 6px; }
.chip button { border: none; background: none; cursor: pointer; color: var(--red-600); font-weight: 800; }

/* Product detail */
.pdp { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 44px; }
/* Real bug (found via a Barron import product with 23 real colours, 2026-09-10):
   grid items default to min-width:auto, so the variant quantity table's own
   intrinsic max-content width - large on any product with enough colour
   columns - forced the whole grid track wider, stretching the sibling image
   column right along with it (the table's own overflow-x:auto wrapper never
   got the chance to do its job). min-width:0 lets both columns shrink to
   their track's real size instead of the content's demanded size. */
.pdp > div { min-width: 0; }
.pdp-gallery-main { aspect-ratio: 1; background: var(--slate-100); border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; font-size: 5rem; overflow: hidden; }
.pdp-gallery-main img { width: 100%; height: 100%; object-fit: cover; }

/* Product page skeleton - mirrors the .pdp grid's proportions (image column
   + detail column) so the layout doesn't jump once the real content
   replaces it, and gives a visible loading state instead of a bare
   "Loading product…" line while assets/data/products.json is fetched. */
.pdp-skeleton { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 44px; }
.skeleton-block { background: linear-gradient(90deg, var(--slate-100) 25%, var(--slate-200, #e5e7eb) 37%, var(--slate-100) 63%); background-size: 400% 100%; animation: skeleton-pulse 1.4s ease infinite; border-radius: var(--radius-md); }
.pdp-skeleton .pdp-gallery-main.skeleton-block { border-radius: var(--radius-lg); }
.skeleton-line { border-radius: 4px; }
@keyframes skeleton-pulse { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
@media (max-width: 780px) {
  .pdp-skeleton { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-block { animation: none; }
}
.pdp-gallery-thumbs { display: flex; gap: 10px; margin-top: 12px; }
.pdp-gallery-thumbs div { width: 64px; height: 64px; border-radius: var(--radius-sm); background: var(--slate-100); display: flex; align-items: center; justify-content: center; font-size: 1.4rem; border: 2px solid transparent; cursor: pointer; }
.pdp-gallery-thumbs div.active { border-color: var(--gold-500); }
.color-swatch-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.color-swatch-btn { padding: 6px 14px; border-radius: 999px; border: 1.5px solid var(--slate-300); background: var(--white); color: var(--black-900); font-size: 0.85rem; cursor: pointer; transition: border-color 0.15s ease; }
.color-swatch-btn:hover { border-color: var(--gold-600); }
.color-swatch-btn[aria-pressed="true"] { border-color: var(--gold-500); background: #fff8e6; font-weight: 700; }
/* Small visual colour dot shown next to a colour name (swatch buttons, the
   size x colour ordering grid) so a customer can tell "Navy" and "Royal"
   apart at a glance instead of reading text - see getColorSwatchCss() in
   product.html. A subtle border keeps white/pale dots visible against the
   page background. */
.color-dot { display: inline-block; width: 14px; height: 14px; border-radius: 50%; border: 1px solid rgba(0,0,0,0.15); vertical-align: -2px; margin-right: 6px; flex-shrink: 0; }

.size-guide-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 20px; }
.size-guide-modal { background: var(--white); border-radius: var(--radius-lg); padding: 24px; max-width: 480px; width: 100%; max-height: 85vh; overflow-y: auto; }
.pdp h1 { font-size: 1.9rem; }
.pdp-meta { display: flex; gap: 14px; margin-bottom: 16px; flex-wrap: wrap; }
.spec-table { width: 100%; border-collapse: collapse; margin: 18px 0; }
.spec-table td { padding: 8px 10px; border-bottom: 1px solid var(--slate-100); font-size: 0.88rem; }
.spec-table td:first-child { color: var(--slate-500); width: 40%; }
.branding-selector { background: var(--slate-100); border-radius: var(--radius-md); padding: 16px; margin: 14px 0; }
.branding-selector .form-field { margin-top: 10px; margin-bottom: 0; }
.branding-selector select { padding: 8px; border: 1px solid var(--slate-300); border-radius: var(--radius-sm); }
.material-options { background: var(--slate-100); border-radius: var(--radius-md); padding: 16px; margin: 14px 0; }
.material-options h3 { font-size: 1rem; margin: 0 0 6px; }
.material-options .material-intro { font-size: 0.85rem; color: var(--slate-500); margin-bottom: 12px; }
.material-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; margin-bottom: 14px; }
.material-card { background: var(--white); border: 1px solid var(--slate-300); border-radius: var(--radius-sm); padding: 10px 12px; }
.material-card h4 { font-size: 0.88rem; margin: 0 0 4px; }
.material-card p { font-size: 0.78rem; color: var(--slate-500); margin: 0; }
.material-preference { margin-top: 12px; }
.material-preference h4 { font-size: 0.85rem; margin: 0 0 8px; }
.material-pref-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.material-pref-chips label { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; background: var(--white); border: 1px solid var(--slate-300); border-radius: 999px; padding: 6px 12px; cursor: pointer; }
.material-disclaimer { font-size: 0.78rem; color: var(--slate-500); margin: 12px 0 0; }
.qty-box { display: flex; align-items: center; gap: 10px; margin: 18px 0; }
.qty-box input { width: 80px; padding: 10px; border-radius: var(--radius-sm); border: 1px solid var(--slate-300); text-align: center; }

/* Quote page */
.quote-table { width: 100%; border-collapse: collapse; margin-bottom: 24px; }
.quote-table th { text-align: left; font-size: 0.78rem; text-transform: uppercase; color: var(--slate-500); padding: 10px; border-bottom: 2px solid var(--slate-100); }
.quote-table td { padding: 12px 10px; border-bottom: 1px solid var(--slate-100); font-size: 0.9rem; vertical-align: middle; }
.quote-table input[type="number"] { width: 70px; padding: 6px; border-radius: var(--radius-sm); border: 1px solid var(--slate-300); text-align: center; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-grid .full { grid-column: 1 / -1; }
.form-field label { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 6px; color: var(--black-800); }
.form-field input, .form-field textarea, .form-field select {
  width: 100%;
  padding: 11px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--slate-300);
  font-family: inherit;
  font-size: 0.92rem;
}
.form-field input[type="checkbox"], .form-field input[type="radio"] {
  width: auto;
  padding: 0;
  border: none;
  accent-color: var(--red-600);
  flex-shrink: 0;
}
.empty-state { text-align: center; padding: 60px 20px; color: var(--slate-500); }
.empty-state .icon { font-size: 3rem; margin-bottom: 14px; }

/* Footer */
footer.site-footer { background: var(--black-900); color: var(--slate-300); padding: 50px 0 20px; margin-top: 40px; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 30px; margin-bottom: 30px; }
.footer-grid h4 { color: var(--white); font-size: 0.9rem; margin-bottom: 14px; }
.footer-grid a, .footer-grid p { color: var(--slate-300); font-size: 0.88rem; display: block; margin-bottom: 8px; }
.footer-grid a:hover { color: var(--gold-500); }
.footer-bottom { border-top: 1px solid rgba(255,255,255,0.1); padding-top: 18px; display: flex; justify-content: space-between; font-size: 0.8rem; flex-wrap: wrap; gap: 10px; }
.social-row { display: flex; gap: 12px; }
.social-row a { background: rgba(255,255,255,0.08); width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
.social-row a:hover { background: var(--gold-500); color: var(--black-900); }

a.footer-review-link { display: inline-block; margin-top: 14px; color: var(--gold-500); font-weight: 600; font-size: 0.9rem; }
a.footer-review-link:hover { color: var(--gold-600); text-decoration: underline; }

/* Anchor targets (#contact, #quote-process) need clearance for the sticky
   header stack (topbar + header row + nav row, ~164px tall) so a jump-link
   doesn't land with the heading hidden underneath it. */
section[id], footer[id] { scroll-margin-top: 180px; }

/* Breadcrumb */
.breadcrumb { font-size: 0.82rem; color: var(--slate-500); padding: 16px 0 0; }
.breadcrumb a { color: var(--red-600); }

/* Data source note banner */
.dev-note {
  background: #fff7e6;
  border: 1px solid var(--gold-500);
  color: #6b4c00;
  font-size: 0.82rem;
  padding: 10px 16px;
  text-align: center;
}
.dev-note strong { color: #4a3400; }

@media (max-width: 980px) {
  .hero .container { grid-template-columns: 1fr; }
  .category-grid, .product-grid { grid-template-columns: repeat(2, 1fr); }
  .specials-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .shop-layout { grid-template-columns: 1fr; }
  .filter-panel { position: static; }
  .pdp { grid-template-columns: 1fr; }
  .testimonial-grid { grid-template-columns: 1fr; }
  .callout { grid-template-columns: 1fr; }

  /* Mobile nav: hamburger-collapsed vertical list instead of the six nav
     items wrapping messily inside the black bar, and the "Shop All" submenu
     becomes a tap-to-open accordion since :hover never fires on touch. */
  .nav-toggle { display: inline-block; }
  .main-nav { display: none; }
  /* Capped + scrollable rather than growing unbounded (real bug, August
     2026 - see initNav()'s comment in main.js): once the nav gained two
     mega-panels and more top-level items, an opened menu could grow taller
     than the viewport and push all page content far down instead of just
     scrolling within itself - same "don't let this grow unbounded" fix
     already applied to .filter-panel/.wizard-summary. */
  .main-nav.open { display: block; max-height: calc(100vh - var(--header-height)); overflow-y: auto; }
  .main-nav .container { display: block; padding: 0; }
  .main-nav ul { flex-direction: column; flex-wrap: nowrap; width: 100%; }
  .main-nav > .container > ul > li { width: 100%; }
  .main-nav a.nav-link { padding: 14px 24px; }
  .mega-toggle { display: block; }
  .mega-panel {
    display: none;
    position: static;
    background: var(--black-800);
    box-shadow: none;
    border-radius: 0;
    padding: 4px 24px 16px;
    min-width: 0;
    grid-template-columns: 1fr;
    gap: 16px;
  }
  .main-nav li.mega-open .mega-panel { display: grid; }
  .mega-col a { color: var(--slate-300); }
  .mega-col a:hover { color: var(--white); }
}
@media (max-width: 640px) {
  .category-grid, .product-grid { grid-template-columns: 1fr 1fr; }
  .specials-grid { grid-template-columns: 1fr; }
  .header-row { flex-wrap: wrap; }
  .search-bar { order: 3; width: 100%; }
  .form-grid { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  /* Icon-only header actions: logo + "How Quotes Work" + "Quote List" +
     hamburger was crowding onto one line on narrow phones. */
  .header-action .label-text { display: none; }
  .header-action { min-width: 32px; }
  .header-actions { gap: 14px; }
  /* Two-up product cards get too cramped below ~480px (image + name + SKU
     + price/stock badge in a ~150px column) - single column reads better
     on the smallest phones. */
  .product-grid { grid-template-columns: 1fr; }
}

/* This Month's Specials — deliberately bold/dark (like the hero) rather
   than the white/section-alt pattern used elsewhere, since a time-limited
   promo should read as the most attention-grabbing section on the page. */
.specials-section {
  background: linear-gradient(120deg, var(--black-900), var(--black-800));
}
.specials-section h2 { color: var(--white); }
.specials-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.special-card {
  background: var(--white);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-hover);
  display: flex;
  flex-direction: column;
}
.special-card img { width: 100%; display: block; aspect-ratio: 4/5; object-fit: cover; object-position: top; }
.special-card-body { padding: 16px 18px 20px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.special-card-body h3 { font-size: 1.05rem; margin-bottom: 0; color: var(--black-900); }
.special-card-body p { font-size: 0.85rem; color: var(--slate-500); margin-bottom: 4px; }
.special-price { font-size: 1.3rem; font-weight: 800; color: var(--red-600); margin-bottom: 10px; }
.special-price span { font-size: 0.7rem; font-weight: 700; color: var(--slate-500); text-transform: uppercase; }

/* WhatsApp click-to-chat button. Deliberately uses WhatsApp's own brand
   green rather than the site palette - like a PayPal/Visa mark, the
   recognisability of the universal WhatsApp icon matters more here than
   strict brand consistency. Injected into every page by initNav() in
   main.js rather than duplicated in each HTML file. */
.whatsapp-fab {
  position: fixed;
  bottom: 24px;
  right: 24px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: #25d366;
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.8rem;
  box-shadow: 0 4px 14px rgba(0,0,0,0.25);
  z-index: 200;
  transition: transform 0.15s ease;
}

/* Golf Day Package Builder (golf-day.html) */
.golf-hero {
  background:
    linear-gradient(135deg, rgba(13,13,13,0.9) 0%, rgba(13,13,13,0.82) 45%, rgba(184,27,20,0.68) 140%),
    url("../img/byb/golf-day-hero-own-the-hole.webp") center 55% / cover no-repeat;
  color: var(--white);
  padding: 64px 0 48px;
}
.golf-hero .hero-eyebrow { color: var(--gold-500); }
.golf-hero h1 { font-size: 2.4rem; max-width: 20ch; }
.golf-hero p.lead { color: var(--slate-300); max-width: 60ch; font-size: 1.05rem; }

.golf-entry-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 36px; }
.golf-entry-card {
  background: var(--black-800);
  border: 1px solid var(--black-600);
  border-radius: var(--radius-lg);
  padding: 26px;
  cursor: pointer;
  transition: all 0.15s ease;
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
}
.golf-entry-card:hover, .golf-entry-card.active { border-color: var(--gold-500); transform: translateY(-3px); }
.golf-entry-card:focus-visible { outline: 2px solid var(--black-900); outline-offset: 2px; box-shadow: 0 0 0 4px var(--gold-500); }
.golf-entry-card .icon { width: 40px; height: 40px; color: var(--gold-500); margin-bottom: 14px; }
.golf-entry-card h3 { color: var(--white); font-size: 1.15rem; }
.golf-entry-card p { color: var(--slate-300); font-size: 0.9rem; }

.golf-tab-panel { display: none; }
.golf-tab-panel.active { display: block; }

.golf-disclaimer {
  background: var(--slate-100);
  border-left: 3px solid var(--gold-600);
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  color: var(--slate-700);
  margin-bottom: 24px;
}

.golf-package-card { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 0; background: var(--white); border: 1px solid var(--slate-100); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); margin-bottom: 24px; }
.golf-package-media { min-height: 260px; background: var(--slate-100); display: flex; align-items: center; justify-content: center; }
.golf-package-media img { width: 100%; height: 100%; object-fit: cover; }
.golf-package-media .icon { width: 80px; height: 80px; color: var(--slate-300); }
.golf-package-body { padding: 30px; }
.golf-package-body h3 { font-size: 1.4rem; color: var(--black-900); }
.golf-package-body .tagline { color: var(--red-600); font-weight: 600; margin-bottom: 12px; }
.golf-package-includes { margin: 16px 0; }
.golf-package-includes li { padding: 4px 0 4px 22px; position: relative; font-size: 0.92rem; color: var(--slate-700); }
.golf-package-includes li::before { content: "✓"; position: absolute; left: 0; color: var(--success); font-weight: 700; }
.golf-package-price { font-size: 1.1rem; font-weight: 700; color: var(--black-900); margin-top: 10px; }

.wizard-progress { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 30px; }
.wizard-progress .step-dot {
  flex: 1; min-width: 90px; text-align: center; padding: 10px 6px; border-radius: var(--radius-sm);
  background: var(--slate-100); color: var(--slate-500); font-size: 0.78rem; font-weight: 700;
}
.wizard-progress .step-dot.current { background: var(--gold-500); color: var(--black-900); }
.wizard-progress .step-dot.done { background: var(--black-800); color: var(--white); }

.wizard-layout { display: grid; grid-template-columns: 1fr 320px; gap: 32px; align-items: start; }
.wizard-step-panel { display: none; }
.wizard-step-panel.active { display: block; }
.wizard-nav { display: flex; justify-content: space-between; margin-top: 28px; }

.golf-pick-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.golf-pick-card { border: 1px solid var(--slate-100); border-radius: var(--radius-md); overflow: hidden; background: var(--white); transition: border-color 0.15s ease; }
.golf-pick-card.golf-pick-active { border-color: var(--gold-500); box-shadow: 0 0 0 1px var(--gold-500); }
button.golf-pick-card { display: block; width: 100%; text-align: left; font: inherit; color: inherit; padding: 0; cursor: pointer; }
button.golf-pick-card:focus-visible { outline: 2px solid var(--black-900); outline-offset: 2px; box-shadow: 0 0 0 4px var(--gold-500); }
.golf-pick-media { height: 130px; background: var(--slate-100); display: flex; align-items: center; justify-content: center; }
.golf-pick-media img { width: 100%; height: 100%; object-fit: cover; }
.golf-pick-media .icon { width: 44px; height: 44px; color: var(--slate-300); }
.golf-pick-body { padding: 14px; }
.golf-pick-body h4 { font-size: 0.98rem; margin-bottom: 4px; }
.golf-pick-desc { font-size: 0.82rem; margin-bottom: 8px; }
.golf-pick-price { font-size: 0.85rem; font-weight: 700; color: var(--red-600); margin-bottom: 10px; }
/* Print Just One's garment cards (August 2026) - unlike the position/print-
   size grids (still a plain <button class="golf-pick-card">), a garment
   card needs a real link (View full details) alongside the select action,
   and a <button> can't legally contain an <a>. So .golf-pick-card is the
   outer bordered wrapper here, .golf-pick-select is the actual clickable
   button/div inside it - same button-reset styling button.golf-pick-card
   already had, just under a different selector so it doesn't fight with
   the outer wrapper's own border/overflow. */
.golf-pick-select { display: block; width: 100%; text-align: left; font: inherit; color: inherit; padding: 0; cursor: pointer; background: none; border: none; }
.golf-pick-select:focus-visible { outline: 2px solid var(--black-900); outline-offset: 2px; box-shadow: 0 0 0 4px var(--gold-500); }
.golf-pick-meta { font-size: 0.78rem; color: var(--slate-500); margin: 0 0 4px; }
.golf-pick-viewlink { display: block; text-align: center; font-size: 0.78rem; padding: 8px; color: var(--red-600); text-decoration: underline; border-top: 1px solid var(--slate-100); }
.golf-pick-viewlink:hover { background: var(--slate-100); }
.golf-pick-qty { display: flex; align-items: center; gap: 12px; }
.qty-btn { width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--slate-300); background: var(--white); font-size: 1.1rem; cursor: pointer; line-height: 1; }
.qty-btn:hover { border-color: var(--gold-600); }
.qty-value { font-weight: 700; min-width: 20px; text-align: center; }

.golf-category-block + .golf-category-block { margin-top: 30px; }
.golf-category-block h4 { color: var(--black-900); margin-bottom: 4px; }

.golf-upgrade-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.golf-upgrade-card { display: flex; gap: 12px; border: 1px solid var(--slate-100); border-radius: var(--radius-md); padding: 14px; cursor: pointer; align-items: flex-start; }
.golf-upgrade-card.golf-pick-active { border-color: var(--gold-500); background: var(--gold-500); background: #fff8e6; }
.golf-upgrade-card input { margin-top: 3px; }
.golf-upgrade-card h4 { font-size: 0.95rem; margin-bottom: 2px; }
.golf-upgrade-card p { font-size: 0.82rem; margin: 0; }

.wizard-summary {
  /* Was a hardcoded 90px, same bug class already fixed on .filter-panel -
     the order summary box slid under the sticky header once the header grew
     taller than that guess (e.g. the nav wrapping to a second line, or the
     August 2026 site-wide nav sync adding more top-level items). See
     syncHeaderHeight() in main.js for how --header-height is measured. */
  position: sticky; top: calc(var(--header-height) + 12px); background: var(--black-900); color: var(--white);
  border-radius: var(--radius-lg); padding: 24px;
}
.wizard-summary h4 { color: var(--gold-500); font-size: 0.95rem; text-transform: uppercase; letter-spacing: 0.05em; }
.wizard-summary-lines { max-height: 260px; overflow-y: auto; margin: 14px 0; font-size: 0.85rem; }
.wizard-summary-lines div { display: flex; justify-content: space-between; gap: 8px; padding: 5px 0; border-bottom: 1px solid var(--black-700); color: var(--slate-300); }
.wizard-summary-total { display: flex; justify-content: space-between; font-size: 1.15rem; font-weight: 700; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--black-700); }
.wizard-summary-note { font-size: 0.75rem; color: var(--slate-300); margin-top: 12px; }

.golf-review-grid { display: grid; grid-template-columns: 1fr 340px; gap: 32px; align-items: start; }

@media (max-width: 980px) {
  .golf-entry-grid { grid-template-columns: 1fr; }
  .golf-package-card { grid-template-columns: 1fr; }
  .wizard-layout, .golf-review-grid { grid-template-columns: 1fr; }
  .wizard-summary { position: static; }
  .golf-pick-grid { grid-template-columns: repeat(2, 1fr); }
  .golf-upgrade-grid { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  .golf-pick-grid { grid-template-columns: 1fr; }
}

/* Print Just One's print-size picker is 4 columns on desktop (the class
   default above is 3) - given its own breakpoints rather than an inline
   style so it still collapses on narrow screens instead of permanently
   overriding the responsive rules above via inline-style specificity. */
.p1-printsize-grid { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 980px) { .p1-printsize-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px) { .p1-printsize-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 400px) { .p1-printsize-grid { grid-template-columns: 1fr; } }

/* Video advert cards + modal player (index.html featured row, our-work.html
   full grid) - see assets/js/video-player.js for the no-autoplay,
   lazy-load-on-click behaviour these classes support. */
.video-card { background: var(--white); border: 1px solid var(--slate-100); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); }
.video-card-media { position: relative; display: block; width: 100%; aspect-ratio: 9 / 16; border: 0; padding: 0; margin: 0; cursor: pointer; background: var(--black-900); }
.video-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.video-play-badge { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 56px; height: 56px; color: var(--white); filter: drop-shadow(0 2px 6px rgba(0,0,0,0.5)); pointer-events: none; }
.video-duration-badge { position: absolute; bottom: 10px; right: 10px; background: rgba(13,13,13,0.7); color: var(--white); font-size: 0.72rem; font-weight: 700; padding: 2px 8px; border-radius: 4px; }
.video-card-body { padding: 16px; }
.video-card-category { font-size: 0.68rem; font-weight: 800; text-transform: uppercase; color: var(--red-600); letter-spacing: 0.03em; }
.video-card-body h3 { font-size: 1rem; margin: 4px 0 6px; }
.video-card-body p { font-size: 0.85rem; }
.video-card-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }

.video-featured-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 24px; }
.video-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }

.video-modal-overlay { display: none; position: fixed; inset: 0; background: rgba(13,13,13,0.92); z-index: 500; align-items: center; justify-content: center; padding: 24px; }
.video-modal-overlay.open { display: flex; }
.video-modal-box { position: relative; max-width: 380px; width: 100%; }
.video-modal-player { width: 100%; max-height: 78vh; aspect-ratio: 9 / 16; border-radius: var(--radius-md); background: var(--black-900); display: block; }
.video-modal-close { position: absolute; top: -46px; right: 0; width: 36px; height: 36px; border-radius: 50%; background: var(--white); border: 0; cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--black-900); }
.video-modal-close svg { width: 20px; height: 20px; }
.video-modal-caption { color: var(--slate-300); font-size: 0.85rem; text-align: center; margin-top: 12px; }

@media (max-width: 980px) {
  .video-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 780px) {
  .video-featured-row {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: 16px;
    margin-left: -24px;
    margin-right: -24px;
    padding: 0 24px 8px;
  }
  .video-featured-row .video-card { flex: 0 0 82%; scroll-snap-align: center; }
}
@media (max-width: 560px) {
  .video-grid { grid-template-columns: 1fr 1fr; }
}

/* Print Just One (print-just-one.html) */
.print-one-trust-row { display: flex; flex-wrap: wrap; gap: 10px 24px; margin-top: 20px; }
.print-one-trust-row div { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; font-weight: 600; color: var(--slate-700); }
.print-one-trust-row .icon { width: 18px; height: 18px; color: var(--red-600); flex-shrink: 0; }

.print-one-unapproved { opacity: 0.6; }
.print-one-unapproved .golf-pick-media { filter: grayscale(1); }

.print-one-preview { max-width: 320px; margin: 20px auto 0; }
.print-one-mockup { position: relative; width: 100%; }
.print-one-garment-shape { position: relative; width: 100%; aspect-ratio: 3 / 4; background: var(--slate-100); border: 1px solid var(--slate-300); border-radius: 6px 6px 28px 28px; }
.print-one-mockup-art { position: absolute; object-fit: contain; }
.print-one-mockup-left-chest .print-one-mockup-art { width: 22%; top: 18%; left: 32%; }
.print-one-mockup-full-front .print-one-mockup-art, .print-one-mockup-full-back .print-one-mockup-art { width: 55%; top: 22%; left: 22.5%; }
.print-one-mockup-left-sleeve .print-one-mockup-art { width: 16%; top: 20%; left: 6%; }
.print-one-mockup-right-sleeve .print-one-mockup-art { width: 16%; top: 20%; left: auto; right: 6%; }
.print-one-card-badge {
  position: absolute; left: 8px; bottom: 8px; z-index: 2;
  background: var(--black-900); color: var(--white); font-size: 0.68rem; font-weight: 700;
  padding: 4px 9px; border-radius: 999px; text-decoration: none;
}
.print-one-card-badge:hover { background: var(--red-600); }
.whatsapp-fab:hover { transform: scale(1.08); }

/* Branded Bottled Water (bottled-water.html) - deliberately a BRIGHT theme,
   unlike golf-day.html's dark hero, per the site owner's explicit "bright,
   clean, premium, not overly dark" requirement. Shares the golf builder's
   generic wizard/pick-grid classes (.wizard-*, .golf-pick-grid, .qty-btn
   etc.) since those have no golf-specific styling - treat them as this
   project's shared "interactive configurator" components, not literally
   golf-only despite the class prefix. */
.water-hero { background: linear-gradient(135deg, var(--white) 0%, var(--slate-100) 100%); padding: 64px 0 48px; border-bottom: 3px solid var(--gold-500); }
.water-hero .hero-eyebrow { color: var(--red-600); }
.water-hero h1 { font-size: 2.4rem; max-width: 22ch; color: var(--black-900); }
.water-hero p.lead { color: var(--slate-700); max-width: 62ch; font-size: 1.05rem; }
.water-hero-grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 40px; align-items: center; }
.water-hero-photo picture, .water-hero-photo img { display: block; width: 100%; height: auto; border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }

.water-entry-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 36px; }
.water-entry-card {
  background: var(--white);
  border: 1px solid var(--slate-100);
  border-radius: var(--radius-lg);
  padding: 26px;
  cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: all 0.15s ease;
}
.water-entry-card:hover, .water-entry-card.active { border-color: var(--gold-500); box-shadow: var(--shadow-hover); transform: translateY(-3px); }
.water-entry-card .icon { width: 40px; height: 40px; color: var(--red-600); margin-bottom: 14px; }
.water-entry-card h3 { color: var(--black-900); font-size: 1.15rem; }
.water-entry-card p { color: var(--slate-500); font-size: 0.9rem; }

.water-label-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }

/* Game Capture Sails (2026-09-05) - same dedicated-hero-per-standalone-
   page pattern as .water-hero above, exact same values, new name for
   clarity since this page is nothing to do with water. */
.sail-hero { background: linear-gradient(135deg, var(--white) 0%, var(--slate-100) 100%); padding: 64px 0 48px; border-bottom: 3px solid var(--gold-500); }
.sail-hero .hero-eyebrow { color: var(--red-600); }
.sail-hero h1 { font-size: 2.4rem; max-width: 22ch; color: var(--black-900); }
.sail-hero p.lead { color: var(--slate-700); max-width: 62ch; font-size: 1.05rem; }
.sail-hero-grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 40px; align-items: center; }
.sail-hero-photo picture, .sail-hero-photo img { display: block; width: 100%; height: auto; border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }

.sail-entry-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 36px; }
.sail-entry-card {
  background: var(--white);
  border: 1px solid var(--slate-100);
  border-radius: var(--radius-lg);
  padding: 26px;
  cursor: pointer;
  box-shadow: var(--shadow-card);
  transition: all 0.15s ease;
}
.sail-entry-card:hover, .sail-entry-card.active { border-color: var(--gold-500); box-shadow: var(--shadow-hover); transform: translateY(-3px); }
.sail-entry-card .icon { width: 40px; height: 40px; color: var(--red-600); margin-bottom: 14px; }
.sail-entry-card h3 { color: var(--black-900); font-size: 1.15rem; }
.sail-entry-card p { color: var(--slate-500); font-size: 0.9rem; }

/* Game Capture Sails gallery (2026-09-05) - every thumbnail is the same
   fixed-ratio box (object-fit: cover) so a tall installation photo and a
   square fabric close-up sit in identical tiles rather than the earlier
   asymmetric grid the site owner found "looked funny". A plain <button>
   (not <img> alone) keeps the click target keyboard-focusable and
   properly labelled for the lightbox it opens. */
.sail-gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; margin-top: 8px; }
.sail-gallery-thumb { display: block; padding: 0; border: none; background: none; cursor: pointer; aspect-ratio: 1 / 1; border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-card); transition: transform 0.15s ease, box-shadow 0.15s ease; }
.sail-gallery-thumb:hover, .sail-gallery-thumb:focus-visible { transform: translateY(-3px); box-shadow: var(--shadow-hover); }
.sail-gallery-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }

.sail-lightbox { position: fixed; inset: 0; background: rgba(13,13,13,0.92); display: flex; align-items: center; justify-content: center; padding: 40px; z-index: 200; }
.sail-lightbox[hidden] { display: none; }
.sail-lightbox img { max-width: 100%; max-height: 100%; border-radius: var(--radius-md); box-shadow: 0 12px 40px rgba(0,0,0,0.5); }
.sail-lightbox-close { position: absolute; top: 20px; right: 24px; background: var(--white); border: none; border-radius: 50%; width: 40px; height: 40px; font-size: 1.1rem; cursor: pointer; color: var(--black-900); }
.sail-lightbox-close:hover { background: var(--gold-500); }
.water-label-card { border: 2px solid var(--slate-100); border-radius: var(--radius-md); padding: 18px; cursor: pointer; background: var(--white); transition: border-color 0.15s ease; }
.water-label-card.selected { border-color: var(--gold-500); box-shadow: 0 0 0 1px var(--gold-500); }
.water-label-card h4 { display: flex; align-items: center; gap: 8px; font-size: 1rem; margin-bottom: 8px; }
.water-label-tag { font-size: 0.68rem; font-weight: 800; text-transform: uppercase; padding: 3px 8px; border-radius: 999px; }
.water-label-tag.recommended { background: #e7f6ee; color: var(--success); }
.water-label-tag.premium { background: #fff7e6; color: var(--gold-700); }
.water-label-tag.upgrade { background: var(--red-100); color: var(--red-600); }
.water-label-card ul { margin: 0 0 8px; padding-left: 18px; }
.water-label-card li { font-size: 0.85rem; color: var(--slate-700); padding: 2px 0; }
.water-label-warning { background: var(--red-100); color: var(--red-700); font-size: 0.8rem; padding: 8px 10px; border-radius: var(--radius-sm); margin-top: 6px; }

.water-artwork-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.water-artwork-card { border: 2px solid var(--slate-100); border-radius: var(--radius-md); padding: 20px; cursor: pointer; background: var(--white); text-align: center; transition: border-color 0.15s ease; }
.water-artwork-card.selected { border-color: var(--gold-500); box-shadow: 0 0 0 1px var(--gold-500); }
.water-artwork-card .icon { width: 34px; height: 34px; color: var(--red-600); margin: 0 auto 10px; }
.water-artwork-card h4 { font-size: 0.98rem; margin-bottom: 6px; }
.water-artwork-card p { font-size: 0.82rem; margin: 0; }
button.water-label-card, button.water-artwork-card { display: block; width: 100%; font: inherit; color: inherit; }

.water-builder-layout { display: grid; grid-template-columns: 1fr 300px; gap: 28px; align-items: start; margin-top: 20px; }
.water-bottle-preview { position: sticky; top: calc(var(--header-height) + 12px); background: var(--slate-100); border-radius: var(--radius-lg); padding: 24px; text-align: center; }
.water-bottle-shape { width: 110px; height: 260px; margin: 0 auto; position: relative; }
.water-bottle-shape .neck { width: 34px; height: 30px; margin: 0 auto; background: rgba(200,220,235,0.55); border: 1px solid var(--slate-300); border-radius: 6px 6px 0 0; }
.water-bottle-shape .body { width: 110px; height: 230px; background: rgba(200,220,235,0.4); border: 1px solid var(--slate-300); border-radius: 16px; margin-top: -2px; position: relative; overflow: hidden; }
.water-bottle-shape .label {
  position: absolute; left: 6px; right: 6px; top: 90px; min-height: 70px;
  border-radius: 4px; padding: 8px 6px; font-size: 0.62rem; line-height: 1.3;
  display: flex; flex-direction: column; justify-content: center; word-break: break-word;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.08);
}
.water-bottle-shape .label img { max-width: 32px; max-height: 32px; margin: 0 auto 4px; }
.water-preview-note { font-size: 0.72rem; color: var(--slate-500); margin-top: 14px; }

.water-crosssell-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
.water-crosssell-card { background: var(--white); border: 1px solid var(--slate-100); border-radius: var(--radius-md); padding: 16px; text-align: center; box-shadow: var(--shadow-card); }
.water-crosssell-card .icon { width: 28px; height: 28px; color: var(--red-600); margin: 0 auto 8px; }
.water-crosssell-card span { font-size: 0.8rem; font-weight: 600; color: var(--black-900); }

@media (max-width: 980px) {
  .water-hero-grid { grid-template-columns: 1fr; }
  .water-entry-grid { grid-template-columns: 1fr; }
  .water-label-grid, .water-artwork-grid { grid-template-columns: 1fr; }
  .water-builder-layout { grid-template-columns: 1fr; }
  .water-bottle-preview { position: static; }
  .water-crosssell-grid { grid-template-columns: repeat(2, 1fr); }
}

/* AI Shopping Assistant floating widget (assets/js/ai-assistant.js).
   Real collision found (August 2026, full-site audit): this was originally
   stacked at bottom:96px assuming WhatsApp's fab (bottom:24px, 56px) was
   the only other fixed corner control - but assets/js/brand-assistant.js
   ("Sparky", a pre-existing guided-prompt widget, unrelated to this one)
   is ALSO on every page, an 82px launcher at bottom:92px (itself already
   stacked above WhatsApp via its own bottom-offset="76" attribute) -
   confirmed live via getBoundingClientRect() that Sparky's much bigger
   button was sitting almost exactly on top of this one, hiding it
   entirely. Moved above Sparky's real top edge (92 + 82 = 174) with a
   safety margin, rather than guessing - if Sparky's own offset ever
   changes, re-measure both live before adjusting this number again. */
.ai-assistant-fab {
  position: fixed;
  bottom: 200px;
  right: 24px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--red-600);
  color: var(--white);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  box-shadow: 0 4px 14px rgba(0,0,0,0.25);
  z-index: 200;
  cursor: pointer;
  transition: transform 0.15s ease;
}
.ai-assistant-fab:hover { transform: scale(1.08); }

.ai-assistant-panel {
  position: fixed;
  bottom: 200px;
  right: 24px;
  width: min(360px, calc(100vw - 32px));
  height: min(520px, calc(100vh - 140px));
  background: var(--white);
  border-radius: var(--radius-lg);
  box-shadow: 0 10px 40px rgba(0,0,0,0.3);
  display: none;
  flex-direction: column;
  overflow: hidden;
  z-index: 201;
}
.ai-assistant-panel.open { display: flex; }

.ai-panel-header {
  background: var(--black-900);
  color: var(--white);
  padding: 14px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700;
}
.ai-panel-close {
  background: none;
  border: none;
  color: var(--white);
  font-size: 1.4rem;
  cursor: pointer;
  line-height: 1;
}

.ai-panel-body {
  flex: 1;
  overflow-y: auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--slate-100);
}

.ai-msg {
  max-width: 88%;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  font-size: 0.9rem;
  line-height: 1.4;
}
.ai-msg-assistant { background: var(--white); border: 1px solid var(--slate-100); align-self: flex-start; }
.ai-msg-user { background: var(--red-600); color: var(--white); align-self: flex-end; }
.ai-typing { opacity: 0.6; font-style: italic; }

.ai-product-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-top: 10px;
}
.ai-product-card {
  display: block;
  background: var(--white);
  border: 1px solid var(--slate-100);
  border-radius: var(--radius-md);
  padding: 8px;
  text-decoration: none;
  color: var(--black-900);
  font-size: 0.78rem;
}
.ai-product-card img { width: 100%; height: 70px; object-fit: contain; margin-bottom: 6px; }
.ai-card-noimg {
  width: 100%; height: 70px; display: flex; align-items: center; justify-content: center;
  background: var(--slate-100); color: var(--slate-500); font-size: 0.7rem; margin-bottom: 6px; border-radius: 8px;
}
.ai-card-name { font-weight: 600; }
.ai-card-price { color: var(--red-600); font-weight: 700; margin-top: 2px; }

.ai-status-card, .ai-quote-draft {
  margin-top: 10px;
  background: var(--white);
  border: 1px solid var(--slate-100);
  border-radius: var(--radius-md);
  padding: 10px 12px;
  font-size: 0.85rem;
}
.ai-quote-draft ul { margin: 6px 0; padding-left: 18px; }
.ai-quote-draft-form { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.ai-quote-draft-form input {
  padding: 8px 10px; border: 1px solid var(--slate-100); border-radius: var(--radius-md); font-size: 0.85rem;
}
.ai-quote-draft-form button { align-self: flex-start; }
.ai-qd-result { font-size: 0.8rem; color: var(--slate-500); }

.ai-panel-input {
  display: flex;
  gap: 8px;
  padding: 12px;
  border-top: 1px solid var(--slate-100);
  background: var(--white);
}
.ai-panel-input input {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid var(--slate-100);
  border-radius: var(--radius-md);
  font-size: 0.9rem;
}

@media (max-width: 480px) {
  .ai-assistant-panel { right: 16px; }
  .ai-assistant-fab { right: 16px; }
}

/* Newsletter / specials signup (August 2026) - footer, every page. */
.footer-newsletter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  background: rgba(255,255,255,0.05);
  border-radius: var(--radius-lg);
  padding: 24px 28px;
  margin-bottom: 30px;
}
.footer-newsletter h4 { color: var(--white); margin: 0 0 4px; font-size: 1.05rem; }
.footer-newsletter p { color: var(--slate-300); margin: 0; font-size: 0.85rem; max-width: 46ch; }
.newsletter-form { display: flex; gap: 8px; flex-wrap: wrap; }
.newsletter-form input[type="email"] {
  padding: 11px 14px; border-radius: var(--radius-md); border: 1px solid rgba(255,255,255,0.2);
  background: rgba(255,255,255,0.08); color: var(--white); min-width: 220px; font-size: 0.9rem;
}
.newsletter-form input[type="email"]::placeholder { color: var(--slate-400); }
.newsletter-form .hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.newsletter-result { font-size: 0.8rem; margin-top: 8px; width: 100%; }

/* Copy Link / Share on WhatsApp controls (section 18 P2) - reused on
   product.html and campaign pages via main.js's shareButtonsHtml(). */
.share-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }

/* Social landing pages (BYB_Social_Media_and_Social_SEO_Operating_Plan_
   2026.md section 18 P0: "crawlable social landing pages") - shared hero/
   FAQ/mobile-sticky-CTA pattern reused by every keyword-cluster landing
   page (corporate-gifts.html, promotional-products.html, etc.), same
   design-token reuse discipline as the rest of the site rather than a new
   look per page. */
.landing-hero { background: var(--black-900); color: var(--white); padding: 48px 0 40px; }
.landing-hero h1 { color: var(--white); font-size: clamp(1.7rem, 4vw, 2.4rem); margin: 0 0 14px; }
.landing-hero p { color: var(--slate-300); font-size: 1.05rem; max-width: 62ch; margin: 0 0 22px; }
.landing-hero .btn { margin-right: 10px; }

.landing-faq { max-width: 780px; }
.landing-faq details {
  border: 1px solid var(--slate-100); border-radius: var(--radius-md);
  padding: 14px 18px; margin-bottom: 10px; background: var(--white);
}
.landing-faq summary {
  font-weight: 700; cursor: pointer; list-style: none; display: flex;
  justify-content: space-between; align-items: center; gap: 12px;
}
.landing-faq summary::-webkit-details-marker { display: none; }
.landing-faq summary::after { content: "+"; font-size: 1.3rem; color: var(--red-600); flex-shrink: 0; }
.landing-faq details[open] summary::after { content: "\2212"; }
.landing-faq p { color: var(--slate-700); margin: 10px 0 0; font-size: 0.95rem; }

.landing-internal-links { display: flex; flex-wrap: wrap; gap: 10px; }
.landing-internal-links a {
  background: var(--slate-100); color: var(--ink); padding: 8px 16px;
  border-radius: 999px; font-size: 0.88rem; font-weight: 600; text-decoration: none;
}
.landing-internal-links a:hover { background: var(--slate-300); }

/* Fixed bottom bar, mobile only (section 18 P0: "a mobile sticky quote
   action" on every landing page) - desktop already has the header's own
   "Quote List" action plus an in-page CTA button, so a second fixed bar
   there would just be clutter with no real problem to solve. */
.landing-sticky-cta { display: none; }
@media (max-width: 720px) {
  .landing-sticky-cta {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 500;
    background: var(--white); border-top: 1px solid var(--slate-100);
    padding: 10px 16px; box-shadow: 0 -4px 16px rgba(0,0,0,0.08);
  }
  .landing-sticky-cta .btn { width: 100%; text-align: center; }
  /* Real content sitting right at the bottom of a landing page (last FAQ
     answer, final internal link) must not be hidden behind the fixed bar -
     same class of bug the --header-height variable exists to prevent at
     the top of the page, mirrored here at the bottom. */
  body:has(.landing-sticky-cta) { padding-bottom: 64px; }
}

/* Real-work photo gallery (About page, 2026-09-07) - uniform grid tiles
   regardless of each source photo's actual dimensions (a mix of portrait
   phone photos and a few landscape ones). object-fit:cover crops to fill
   a fixed-aspect box rather than distorting/stretching - the underlying
   image file is never touched, only how much of it shows in this one
   layout. Click opens the real photo full-size in a lightbox rather than
   leaving the cropped view as the only way to see it. */
.photo-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 10px; }
.photo-gallery button { display: block; padding: 0; border: none; background: none; cursor: pointer; border-radius: var(--radius-sm); overflow: hidden; aspect-ratio: 4 / 5; }
.photo-gallery img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.2s ease; }
.photo-gallery button:hover img, .photo-gallery button:focus-visible img { transform: scale(1.05); }
.photo-lightbox { position: fixed; inset: 0; background: rgba(10,10,10,0.92); display: none; align-items: center; justify-content: center; z-index: 1000; padding: 24px; }
.photo-lightbox.open { display: flex; }
.photo-lightbox img { max-width: min(92vw, 1100px); max-height: 88vh; border-radius: var(--radius-md); }
.photo-lightbox-close { position: absolute; top: 18px; right: 24px; background: none; border: none; color: var(--white); font-size: 2rem; line-height: 1; cursor: pointer; padding: 6px 10px; }

/* ---- Print Just One redesign (2026-09-19): garment types on the left, colour/size chips,
   placement + size step, Continue button under the summary box ---- */
.p1-item-layout { display: grid; grid-template-columns: 220px 1fr; gap: 24px; align-items: start; }
.p1-cats { position: sticky; top: calc(var(--header-height) + 12px); }
.p1-cats h4 { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--slate-500); margin: 0 0 10px; }
.p1-cat-btn { display: flex; justify-content: space-between; align-items: center; gap: 8px; width: 100%; text-align: left; padding: 11px 12px; margin-bottom: 6px; border: 1px solid var(--slate-100); border-radius: var(--radius-md); background: var(--white); font: inherit; font-size: 0.9rem; cursor: pointer; }
.p1-cat-btn:hover { border-color: var(--slate-300); }
.p1-cat-btn.active { border-color: var(--gold-500); background: #fff8e6; font-weight: 700; }
.p1-cat-btn:focus-visible { outline: 2px solid var(--black-900); outline-offset: 2px; }
.p1-cat-count { color: var(--slate-500); font-weight: 400; font-size: 0.8rem; }
.p1-selected { border: 2px solid var(--gold-500); border-radius: var(--radius-lg); padding: 18px; margin-bottom: 20px; background: #fffdf5; scroll-margin-top: calc(var(--header-height) + 16px); }
.p1-selected h4 { margin: 0 0 12px; font-size: 1.05rem; }
.p1-label { font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--slate-700); margin: 14px 0 8px; }
.p1-chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.p1-chip { display: inline-flex; align-items: center; gap: 7px; padding: 8px 14px; border: 1px solid var(--slate-300); border-radius: 999px; background: var(--white); font: inherit; font-size: 0.88rem; cursor: pointer; }
.p1-chip:hover { border-color: var(--black-900); }
.p1-chip[aria-pressed="true"] { border-color: var(--black-900); background: var(--black-900); color: var(--white); }
.p1-chip:focus-visible { outline: 2px solid var(--black-900); outline-offset: 2px; box-shadow: 0 0 0 4px var(--gold-500); }
.p1-dot { width: 15px; height: 15px; border-radius: 50%; border: 1px solid rgba(0,0,0,0.3); flex-shrink: 0; }
.p1-sub { font-size: 0.95rem; margin: 22px 0 10px; }
.p1-note { font-size: 0.82rem; color: var(--slate-500); margin: 8px 0 0; }
.p1-pos-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.p1-summary-nav { display: flex; gap: 10px; margin-top: 18px; }
.p1-summary-nav .btn { flex: 1; justify-content: center; }
.p1-summary-nav #p1-prev { border-color: var(--slate-300); color: var(--white); }
.p1-mobile-bar { display: none; }
.print-one-mockup-front .print-one-mockup-art, .print-one-mockup-back .print-one-mockup-art { width: 55%; top: 22%; left: 22.5%; }
.print-one-mockup-right-chest .print-one-mockup-art { width: 22%; top: 18%; left: auto; right: 32%; }
@media (max-width: 980px) {
  .p1-item-layout { grid-template-columns: 1fr; }
  .p1-cats { position: static; }
  .p1-cats > div { display: flex; flex-wrap: wrap; gap: 6px; }
  .p1-cat-btn { width: auto; margin: 0; }
  .p1-pos-grid { grid-template-columns: repeat(2, 1fr); }
  .p1-summary-nav { display: none; }
  .wizard-layout { padding-bottom: 76px; }
  .p1-mobile-bar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; background: var(--black-900); color: var(--white); box-shadow: 0 -4px 14px rgba(0,0,0,0.25); }
  .p1-mobile-bar small { display: block; font-size: 0.7rem; color: var(--slate-300); text-transform: uppercase; letter-spacing: 0.04em; }
  .p1-mobile-bar strong { font-size: 1.05rem; }
}

/* 2026-09-21: colour row under the product photo (John). */
.pdp-colors { margin-top: 14px; }
.pdp-colors label { display: block; font-size: 0.85rem; font-weight: 700; margin-bottom: 2px; }
.pdp-colors .color-swatch-row { gap: 6px; }
.pdp-colors .color-swatch-btn, .color-chip { padding: 4px 10px; font-size: 0.78rem; }
.color-chip { display: inline-flex; align-items: center; border-radius: 999px; border: 1px solid var(--slate-200, #e2e2e2); background: var(--white); color: var(--black-900); }
.quote-table td .color-dot { margin-right: 6px; }
.quote-table.qt-compact th, .quote-table.qt-compact td { padding: 8px 4px; }
.quote-table.qt-compact th:first-child, .quote-table.qt-compact td:first-child { padding-left: 2px; padding-right: 8px; }
