/* Tshirtgang Shops — layout 1
   Colours come from CSS variables set per-shop in <head>:
   --primary, --secondary, --bg, --text */

* { box-sizing: border-box; }
/* Always reserve the scrollbar gutter so page width doesn't shift between
   short and tall pages (e.g. stepping through bundle items with different
   numbers of colour/size options). */
html { scrollbar-gutter: stable; }
body {
  margin: 0;
  font-family: "Inter", -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  /* sticky footer: fill the viewport, footer pinned to the bottom */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
h1, h2, h3 { line-height: 1.2; }
.muted { opacity: .65; }
/* screen-reader-only (keeps a semantic h1/label without affecting layout) */
.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;
}
.small { font-size: .85rem; }

/* ---- top bar ---- */
.topbar {
  background: var(--primary);
  color: var(--on-primary);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: .4rem 1.5rem;
  font-size: .85rem;
  font-weight: 600;
}
.topbar-cart:hover { text-decoration: underline; }

/* ---- header ----
   App-style bar: hamburger (left) · logo + shop name (centred) · cart (right),
   with a full-width pill search on its own row below. The nav lives in a
   slide-out drawer on every breakpoint, opened by the hamburger. */
.header {
  /* solid secondary fill (no gradient) */
  background-color: var(--secondary);
  color: var(--on-secondary);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas:
    "menu logo cart"
    "search search search";
  align-items: center;
  column-gap: .75rem;
  row-gap: .8rem;
  padding: .9rem 1rem;
  /* sticky shrink-on-scroll: pins to the top once scrolled past (#header-sentinel).
     The header creates its own stacking context, and the nav drawer (1001) +
     backdrop (1000) live INSIDE it (see header.php), so their z-indexes only
     order within this context. To let the open drawer cover the root-level
     sticky add-to-cart bar (z-index 999), the header context itself must sit
     above it — hence 1000, not the old 80 (which let the cart bar paint over
     the whole header, drawer included). */
  position: sticky;
  top: 0;
  z-index: 1000;
  transition: padding .2s ease, box-shadow .2s ease;
}

/* hamburger (left) — visible on every breakpoint, all-icon header */
.nav-toggle {
  grid-area: menu;
  justify-self: start;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none;
  color: var(--on-secondary);             /* auto-contrast on the secondary bg */
  font-size: 1.4rem; cursor: pointer;
  padding: .25rem .45rem;
}

/* logo + shop name, centred together */
.logo {
  grid-area: logo;
  justify-self: center;
  display: inline-flex; align-items: center; gap: .6rem;
  color: var(--on-secondary);
  min-width: 0; text-align: left;
}
.logo-img {
  /* free-form logo: natural aspect ratio, no circle crop — wide logos work */
  height: 54px; width: auto; max-width: 210px;
  border-radius: 6px;
  object-fit: contain;
  flex: none;
  transition: height .2s ease, width .2s ease;
}
.logo-text { font-size: 1.4rem; font-weight: 800; letter-spacing: .02em; }
.header .logo-text { font-size: 1.05rem; line-height: 1.15; letter-spacing: .01em; transition: font-size .2s ease; }

/* nav drawer (all breakpoints).
   visibility:hidden keeps the off-canvas drawer from ever painting unless
   .open is set — prevents the brief flash seen when the sticky header
   re-layouts on scroll. visibility flips instantly on open, and is delayed
   until the slide-out finishes on close so the closing animation stays visible. */
.nav {
  /* z-index above the sticky mobile add-to-cart bar (999) so the open
     drawer covers it instead of the cart bar floating over the drawer */
  position: fixed; top: 0; left: 0; bottom: 0; z-index: 1001;
  width: min(300px, 85vw);
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 0; padding: 3.6rem 1.5rem 1.5rem;
  background: var(--secondary);
  color: var(--on-secondary);
  transform: translateX(-105%);
  visibility: hidden;
  transition: transform .25s ease, visibility 0s linear .25s;
  box-shadow: 4px 0 24px rgba(0,0,0,.35);
  overflow-y: auto;
}
.nav.open {
  transform: translateX(0);
  visibility: visible;
  transition: transform .25s ease, visibility 0s;
}
.nav a {
  display: block; width: 100%;
  padding: .8rem 0; font-size: 1rem; font-weight: 600;
  /* neutral divider stays visible on both light and dark drawer backgrounds */
  border-bottom: 1px solid rgba(128,128,128,.28);
  /* auto-contrast text: dark on a light/white secondary, white on a dark one,
     so the drawer is legible whatever the shop's palette resolves to */
  color: var(--on-secondary);
  opacity: 1;
}
/* hover keeps the link's own colour (palette-safe) and underlines instead */
.nav a:hover { opacity: 1; text-decoration: underline; text-underline-offset: 4px; }
/* current top category reads as selected via a persistent underline (matches hover) */
.nav a.active { text-decoration: underline; text-underline-offset: 4px; text-decoration-thickness: 2px; }
/* sub-categories sit indented beneath their parent in the mobile drawer:
   lighter, smaller, no own border so each parent + its subs read as one group */
.nav a.nav-sub {
  padding: .55rem 0 .55rem 1.4rem;
  font-size: .9rem; font-weight: 500;
  color: var(--on-secondary);
  color: color-mix(in srgb, var(--on-secondary) 78%, transparent);
  border-bottom: 1px solid rgba(128,128,128,.16);
}
.nav a.nav-sub:hover { color: var(--on-secondary); }
.nav-close {
  display: block; position: absolute; top: .6rem; right: .9rem;
  background: none; border: none; color: var(--on-secondary);
  font-size: 1.8rem; cursor: pointer; line-height: 1;
}
/* grouped account/help links inside the drawer.
   Muted auto-contrast: a softened tint of --on-secondary so secondary links
   read on either a light or dark drawer, one step down from the main links. */
.nav-extra { display: block; width: 100%; margin-top: .5rem; }
.nav-extra a {
  text-transform: none; letter-spacing: 0;
  font-size: .85rem; font-weight: 500;
  padding: .55rem 0; border-bottom: none;
  color: var(--on-secondary);
  color: color-mix(in srgb, var(--on-secondary) 75%, transparent); opacity: 1;
}
.nav-extra a:hover { color: var(--on-secondary); }
.nav-extra a i { width: 1.1rem; margin-right: .55rem; text-align: center; opacity: .85; }
.nav-heading {
  display: block; width: 100%;
  margin-top: 1.1rem; padding-bottom: .25rem;
  font-size: .65rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .1em;
  /* section headings stay muted, adapting to the drawer background */
  color: var(--on-secondary);
  color: color-mix(in srgb, var(--on-secondary) 55%, transparent); opacity: 1;
}

/* full-width pill search on its own row, icon on the left */
.header-search {
  grid-area: search;
  display: flex; align-items: center; gap: .35rem;
  background: #f1f1f4;
  border-radius: 999px;
  padding: 0 .6rem 0 .9rem;
  max-width: 100%;        /* never spill past its grid cell / the viewport */
}
.header-search button {
  border: none; background: none; cursor: pointer;
  /* dark glyph: the pill is a fixed light surface, so --on-secondary would vanish here */
  color: #5b6470; font-size: 1rem;
  padding: .55rem .15rem; display: inline-flex;
}
.header-search input {
  /* width:0 + flex-grow: the field grows to fill the pill, but its default
     intrinsic size (the ~20-char search box) no longer feeds the parent's
     max-content and pushes the header past the viewport on mobile. */
  flex: 1; min-width: 0; width: 0;
  border: none; background: none;
  padding: .7rem .25rem; font-size: .95rem;
  color: #1a1a1a; font-family: inherit;
}
.header-search input::placeholder { color: #8a909b; }
.header-search input:focus { outline: none; }
.header-search:focus-within { box-shadow: 0 0 0 2px var(--primary); }

/* cart: clean outline-style icon (right) with a small gold count badge */
.header-cart {
  grid-area: cart;
  justify-self: end;
  display: inline-flex; align-items: center;
  color: var(--on-secondary);             /* auto-contrast on the secondary bg */
  padding: .25rem .35rem;
}
.header-cart-icon { position: relative; display: inline-flex; font-size: 1.5rem; line-height: 1; }
.header-cart-count {
  position: absolute; top: -7px; right: -9px;
  background: #f4c542; color: #1a1a1a;     /* gold badge, dark text */
  min-width: 17px; height: 17px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .66rem; font-weight: 800; padding: 0 4px; line-height: 1;
  border: 2px solid var(--secondary); box-sizing: content-box;
}

/* backdrop behind the open drawer */
.nav-backdrop {
  display: none; position: fixed; inset: 0;
  /* sits below the drawer (1001) but above the sticky cart bar (999) */
  background: rgba(0,0,0,.5); z-index: 1000;
}
.nav-backdrop.show { display: block; }

/* slim sticky header once scrolled past #header-sentinel (toggled by JS).
   The sticky box reserves its full-size space up-page, so shrinking = no jump. */
.header.shrink { padding-top: .5rem; padding-bottom: .5rem; box-shadow: 0 2px 14px rgba(0,0,0,.28); }
.header.shrink .logo-img { height: 32px; width: auto; }
.header.shrink .logo-text { font-size: .95rem; }
.header.shrink .header-search { display: none; }

/* ---- desktop header (≥861px): big header, logo left, centred inline
   links, pill search + cart on the right. The drawer/hamburger pattern
   above stays for mobile only. ---- */
@media (min-width: 861px) {
  .header {
    grid-template-columns: auto 1fr minmax(220px, 300px) auto;
    grid-template-areas: "logo nav search cart";
    row-gap: 0;
    padding: 1rem 1.5rem;
  }
  .nav-toggle, .nav-close, .nav-heading, .nav-extra { display: none; }
  /* sub-category links are a mobile-drawer feature only; the inline desktop nav
     has no room for them and the Shop page shows them as quick-filter chips */
  .nav a.nav-sub { display: none; }
  /* desktop nav drops the "Shop " prefix (e.g. "Shop Apparel" → "Apparel");
     the word stays in the mobile drawer where it reads as an action.
     "Shop All" has no span, so it keeps its full label. */
  .nav a .nav-shop-word { display: none; }
  .logo { justify-self: start; }
  .logo-img { height: 60px; max-width: 260px; }
  .header .logo-text { font-size: 1.25rem; }

  /* drawer becomes a centred inline link row */
  .nav {
    grid-area: nav;
    position: static;
    width: auto;
    flex-direction: row; align-items: center; justify-content: center;
    flex-wrap: wrap; gap: 2.25rem;
    padding: 0;
    background: none; box-shadow: none; overflow: visible;
    transform: none; visibility: visible; transition: none;
  }
  .nav a {
    display: inline-block; width: auto;
    padding: 0; border-bottom: none;
    font-size: .85rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em;
    color: var(--on-secondary); opacity: .9;
    white-space: nowrap;
  }
  .nav a:hover { opacity: 1; text-decoration: underline; text-underline-offset: 5px; }
}

/* mid-width desktops: drop the shop name beside the logo first (it repeats
   throughout the page) and tighten link spacing, so the nav stays one row */
@media (min-width: 861px) and (max-width: 1300px) {
  .header .logo-text { display: none; }
  .nav { gap: 1.4rem; }

  .header-search { grid-area: search; }
  /* keep the search available in the slim scrolled header on desktop */
  .header.shrink .header-search { display: flex; }
}

/* mobile: drop the shop-name text beside the logo so the logo image can stand
   on its own, larger and uncluttered */
@media (max-width: 860px) {
  .header .logo-text { display: none; }
  .logo-img { height: 62px; max-width: 220px; }
  .header.shrink .logo-img { height: 40px; }
}

/* ---- hero ---- */
.hero {
  background: var(--secondary) center / cover no-repeat;
  color: #fff;
  min-height: 420px;
  display: flex;
  align-items: center;
}
.hero-content {
  padding: 3rem 1.5rem;
  max-width: 560px;
  margin-left: 3vw;
}
.hero h1 {
  font-size: clamp(2rem, 5vw, 3.2rem);
  font-weight: 900;
  text-transform: uppercase;
  margin: 0 0 1rem;
  text-shadow: 0 2px 12px rgba(0,0,0,.55);
}
.hero p { font-size: 1.1rem; margin: 0 0 1.5rem; text-shadow: 0 1px 8px rgba(0,0,0,.55); }
.hero-buttons { display: flex; gap: 1rem; flex-wrap: wrap; }

/* Banner-image hero: full-width natural height, capped + cover when wide */
.hero-banner { display: block; min-height: 0; position: relative; }
.hero-img { display: block; width: 100%; height: auto; }
@media (min-width: 1600px) {
  .hero-img { height: 480px; object-fit: cover; object-position: center; }
}
.hero-overlay { position: absolute; left: 4vw; bottom: 9%; }
@media (max-width: 560px) {
  .hero-overlay .btn-lg { padding: .6rem 1.3rem; font-size: .85rem; }
}

/* ---- buttons ---- */
.btn {
  display: inline-block;
  padding: .65rem 1.4rem;
  border: 2px solid transparent;
  border-radius: 4px;
  font-weight: 700;
  font-size: .9rem;
  text-transform: uppercase;
  letter-spacing: .03em;
  cursor: pointer;
  text-align: center;
}
.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-primary:hover { filter: brightness(.92); }
.btn-outline { border-color: #fff; color: #fff; background: transparent; }
.btn-outline:hover { background: rgba(255,255,255,.12); }
.page .btn-outline, .cart-actions .btn-outline { border-color: var(--secondary); color: var(--secondary); }
.page .btn-outline:hover { background: rgba(0,0,0,.05); }
.btn-lg { padding: .85rem 2rem; font-size: 1rem; }
.btn-block { display: block; width: 100%; }

/* ---- categories ---- */
.categories {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1rem;
  padding: 1.5rem;
}
.category-card {
  background: #f4f4f4;
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform .15s;
}
.category-card:hover { transform: translateY(-3px); }
/* Always square, never distorted: a 1:1 box with object-fit:contain shows the
   whole image (letterboxed on white) instead of stretching or cropping it. */
.category-card img { width: 100%; aspect-ratio: 1 / 1; object-fit: contain; background: #fff; display: block; }
.category-card-body { padding: .9rem 1rem; }
.category-card h3 { margin: 0 0 .3rem; font-size: 1rem; text-transform: uppercase; }
.shop-now { font-size: .8rem; font-weight: 700; }

/* ---- products ---- */
/* width: 100% is required — these are direct flex items of the column-flex body,
   and auto cross-axis margins otherwise suppress stretch, shrinking the box to its
   content width (e.g. a 1-product search collapsing to the search bar). An explicit
   width makes it a definite 1280px so the auto margins simply centre it. */
.page, .featured, .bundles-strip { width: 100%; box-sizing: border-box; padding: 1.5rem; max-width: 1280px; margin: 0 auto; }
/* when the strip is nested inside an already-centered .page (products listing),
   don't double up the padding/width — inherit the page container instead */
.page .bundles-strip { padding: 0; max-width: none; margin: 0 0 1.5rem; }
.section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 1rem;
}
.section-head h1, .section-head h2 { text-transform: uppercase; margin: 0; }
.section-head a { font-weight: 700; font-size: .9rem; color: var(--primary); white-space: nowrap; }
.section-head a:hover { text-decoration: underline; }
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1.25rem;
}
.product-card {
  border: 1px solid #e4e4e4;
  border-radius: 6px;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  background: #fff;
}
.product-card img { height: 180px; width: 100%; object-fit: contain; }
.product-card h3 { font-size: .95rem; margin: 0; font-weight: 600; }
.sku { opacity: .55; font-weight: 400; font-size: .85em; }
.price { font-weight: 800; font-size: 1.05rem; }
.price-lg { font-size: 1.6rem; margin: .5rem 0; }
/* large persistent search bar on the products listing */
.shop-search {
  display: flex; align-items: center; gap: .6rem;
  background: #fff; border: 2px solid #e2e2e2; border-radius: 12px;
  padding: .35rem .5rem .35rem 1rem; margin: 0 0 1.5rem;
  /* Hard-contain the input + SEARCH button so the bar can never push the page
     wider than the viewport on mobile: cap to the container width and clip any
     residual sub-pixel spill. The :focus-within state only changes border
     colour (inset), so overflow:hidden won't swallow a focus ring here. */
  max-width: 100%;
  width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}
.shop-search:focus-within { border-color: var(--secondary); }
.shop-search > i { font-size: 1.05rem; opacity: .5; flex-shrink: 0; }
.shop-search input[type="search"] {
  /* width:0 + flex-grow: the field still fills the bar, but its default
     intrinsic (~20-char) width no longer inflates the page's max-content
     and force horizontal overflow/scroll on mobile. */
  flex: 1; min-width: 0; width: 0; border: none; outline: none; background: transparent;
  font-size: 1.05rem; padding: .55rem .25rem; color: var(--text);
}
.shop-search .btn { flex-shrink: 0; padding: .65rem 1.5rem; }
@media (max-width: 520px) {
  .shop-search .btn { padding: .65rem 1rem; }
}

/* apparel quick-filter chips */
.quick-cats { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1.25rem; }
.quick-cat {
  display: inline-block; padding: .4rem .9rem; border-radius: 999px;
  border: 1px solid #d8d8d8; background: #fff; color: var(--text);
  font-size: .85rem; font-weight: 600; white-space: nowrap;
}
.quick-cat:hover { border-color: var(--primary); }
.quick-cat.active { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }

/* Category switcher on the listing page — mirrors the homepage "Shop by
   Category" tiles (image + name), so switching categories feels the same as
   the front page rather than a row of pills. Wraps like the homepage grid;
   the active category is ringed in the theme colour. Per-tile border-radius is
   set inline from the shop's category_image_shape (square/circle/squircle). */
.cat-switch { display: flex; flex-wrap: nowrap; gap: 1rem; padding: .25rem .1rem 1rem; justify-content: safe center; overflow-x: auto; }
.cat-switch-item {
  /* ONE row: items share the width, shrinking from 300px to a 50px floor so
     every category fits on a single line; scrolls only if there are too many to
     fit even at 50px. Matches the homepage Auto tiles. */
  flex: 1 1 0; min-width: 50px; max-width: 300px; text-align: center;
  text-decoration: none; color: var(--text);
}
.cat-switch-img {
  display: flex; align-items: center; justify-content: center;
  width: 100%; aspect-ratio: 1 / 1; overflow: hidden;
  background: #fff; border: 2px solid #e4e4e4; color: #b9b9b9; font-size: 1.6rem;
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.cat-switch-img img { width: 100%; height: 100%; object-fit: contain; background: #fff; display: block; }
.cat-switch-item:hover .cat-switch-img { border-color: var(--primary); transform: translateY(-2px); }
.cat-switch-item.active .cat-switch-img { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary); }
.cat-switch-name { display: block; margin-top: .45rem; font-size: .82rem; font-weight: 600; line-height: 1.2; }
.cat-switch-item.active .cat-switch-name { color: var(--primary); }
@media (max-width: 700px) {
  /* Mobile: fixed 50x50 tiles in a horizontal swipe shelf. */
  .cat-switch { justify-content: flex-start; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .cat-switch::-webkit-scrollbar { display: none; }
  .cat-switch-item { flex: 0 0 auto; width: 50px; min-width: 0; scroll-snap-align: start; }
  .cat-switch-name { font-size: .72rem; }
}

/* size measurements + size chart */
.size-chart-toggle {
  background: none; border: none; padding: 0; margin: .6rem 0 0; cursor: pointer;
  color: var(--secondary); font-weight: 600; font-size: .9rem;
}
.size-chart-toggle:hover { text-decoration: underline; }
.size-chart-toggle i { margin-right: .35rem; }
.size-measure {
  display: flex; flex-wrap: wrap; gap: 1rem; margin-top: .6rem;
  background: #f7f7f7; border: 1px solid #ececec; border-radius: 8px;
  padding: .85rem 1.25rem; font-size: 1.05rem;
}
.size-measure:empty { display: none; }
.size-measure span { flex: 1 1 0; min-width: 80px; text-align: center; }
.size-measure span + span { border-left: 1px solid #e2e2e2; }
.size-measure b { display: block; font-weight: 700; text-transform: uppercase; font-size: .68rem; opacity: .55; }
.size-chart-table { margin-top: .8rem; }
.size-chart-scroll { overflow-x: auto; }

/* Flex/div size grid (no <table>): each row is a flex row, cells share width
   fluidly (flex:1) and shrink with the viewport down to a min, after which the
   .size-chart-scroll wrapper scrolls horizontally. */
.size-flex {
  border: 1px solid #e4e4e4; border-radius: 10px; overflow: hidden;
  font-size: .9rem; min-width: max-content;
}
.sf-row { display: flex; }
.sf-row + .sf-row { border-top: 1px solid #ececec; }
.sf-cell {
  flex: 1 1 0; min-width: 2.9rem; padding: .55rem .5rem;
  display: flex; align-items: center; justify-content: center; text-align: center;
}
.sf-cell + .sf-cell { border-left: 1px solid #f0f0f0; }
.sf-label {
  flex: 0 0 6.5rem; justify-content: flex-start; text-align: left;
  font-weight: 700; background: #fafafa;
}
.sf-head { background: #f3f3f3; font-weight: 700; }
.sf-head .sf-label { background: #f3f3f3; }
/* Two orientations of the same data: pivot (sizes across the top) on desktop,
   stacked (sizes down the left) on mobile. Only one is shown at a time. */
.size-flex.is-stacked { display: none; }
@media (max-width: 600px) {
  .size-flex.is-pivot   { display: none; }
  .size-flex.is-stacked { display: block; }
  .size-flex { font-size: .85rem; }
  .sf-label { flex-basis: 4.5rem; }
  .sf-cell { min-width: 2.6rem; padding: .5rem .4rem; }
}

.size-chart-block { margin: 1.75rem 0; }
.size-chart-block h2 { font-size: 1.05rem; margin: 0 0 .2rem; }
.size-chart-items { font-size: .82rem; margin: 0 0 .6rem; line-height: 1.4; }

/* swatches + price + button stick together at the bottom of every card */
.card-foot { margin-top: auto; display: flex; flex-direction: column; gap: .5rem; }

/* Decoration locations ("Front & back", "3 print locations") — a quiet
   qualifier under the product title, not a heading, so it stays sentence case
   (no uppercase) and low-contrast. Front-only products render nothing at all
   (see Shop::designLocations). */
.card-locations {
  font-size: .78rem; font-weight: 500; color: #8a9099;
}

/* "No exact matches for X — showing similar products." Shown above the grid
   when a search fell through to the loose second pass (Shop::products). */
.search-fuzzy-note {
  margin: 0 0 1rem; padding: .7rem 1rem;
  background: #fbf7e8; border: 1px solid #efe2b8; border-radius: 8px;
  font-size: .9rem; color: #6b5b1f;
}
.search-fuzzy-note strong { font-weight: 700; }

/* product-card colour swatches */
.card-swatches { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.card-swatch {
  width: 20px; height: 20px; border-radius: 50%; padding: 0; cursor: pointer;
  border: 1px solid rgba(0, 0, 0, .2); background-clip: padding-box;
  transition: transform .1s ease;
}
.card-swatch:hover { transform: scale(1.15); }
.card-swatch.active { outline: 2px solid var(--primary); outline-offset: 1px; }
.card-swatch-more { font-size: .78rem; font-weight: 700; opacity: .6; margin-left: 2px; }

/* ---- pagination ---- */
.pagination { display: flex; gap: .4rem; justify-content: center; margin: 2rem 0; flex-wrap: wrap; }
.pagination a, .page-current {
  padding: .45rem .8rem;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-weight: 600;
}
.page-current { background: var(--secondary); color: var(--on-secondary); border-color: var(--secondary); }

/* ---- product detail ---- */
.product-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2.5rem;
}
@media (max-width: 760px) { .product-detail-grid { grid-template-columns: 1fr; } }
.product-detail-image {
  border: 1px solid #e4e4e4;
  border-radius: 6px;
  padding: 1rem;
  background: #fff;
  align-self: start;
}
.option-group { margin: 1.1rem 0; }
.option-group > label { display: block; font-weight: 700; font-size: .85rem; text-transform: uppercase; margin-bottom: .45rem; }
.swatches, .sizes { display: flex; gap: .5rem; flex-wrap: wrap; }
.swatch input, .size-pill input { display: none; }
.swatch span {
  display: block; width: 30px; height: 30px;
  border-radius: 50%; border: 2px solid #ccc; cursor: pointer;
}
.swatch input:checked + span { border-color: var(--primary); outline: 2px solid var(--primary); outline-offset: 1px; }
.size-pill span {
  display: block; padding: .4rem .8rem;
  border: 1px solid #ccc; border-radius: 4px;
  font-size: .85rem; font-weight: 600; cursor: pointer;
}
.size-pill input:checked + span { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
/* Out of stock for the selected colour: greyed, struck through, not selectable. */
.size-pill.out-of-stock span {
  color: #b0b0b0; border-color: #e4e4e4; background: #f6f6f6;
  cursor: not-allowed; text-decoration: line-through; opacity: .8;
}
.qty-input { width: 75px; padding: .45rem; border: 1px solid #ccc; border-radius: 4px; font-size: 1rem; }

/* ---- cart ---- */
.cart-table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
.cart-table th {
  text-align: left; font-size: .78rem; text-transform: uppercase;
  border-bottom: 2px solid var(--secondary); padding: .55rem .5rem;
}
.cart-table td { padding: .7rem .5rem; border-bottom: 1px solid #e7e7e7; vertical-align: middle; }
.cart-product { display: flex; align-items: center; gap: .75rem; font-weight: 600; }
.cart-product img { width: 54px; height: 54px; object-fit: contain; border: 1px solid #eee; border-radius: 4px; }
.link-danger { background: none; border: none; color: #c0392b; font-size: 1.3rem; cursor: pointer; line-height: 1; }
.cart-actions { display: flex; justify-content: space-between; align-items: flex-end; gap: 1rem; flex-wrap: wrap; }
.cart-summary { text-align: right; }
.cart-subtotal { font-size: 1.1rem; margin-bottom: .7rem; }

/* ---- checkout ---- */
.checkout-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 2.5rem; align-items: start; }
@media (max-width: 820px) { .checkout-grid { grid-template-columns: 1fr; } }
.checkout-form h2 { font-size: 1.05rem; text-transform: uppercase; margin: 1.4rem 0 .6rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.form-field { margin-bottom: .9rem; }
.form-field label { display: block; font-size: .82rem; font-weight: 600; margin-bottom: .3rem; }
.form-field input {
  width: 100%; padding: .55rem .7rem;
  border: 1px solid #ccc; border-radius: 4px; font-size: .95rem;
}
.form-field.has-error input { border-color: #c0392b; }
.error { color: #c0392b; font-weight: 400; }
.order-summary {
  border: 1px solid #e4e4e4; border-radius: 6px;
  padding: 1.25rem; background: #fafafa;
}
.order-summary h2 { margin-top: 0; font-size: 1.05rem; text-transform: uppercase; }
.summary-line { display: flex; justify-content: space-between; gap: 1rem; padding: .45rem 0; border-bottom: 1px solid #eee; font-size: .92rem; }
.summary-line small { display: block; }
.summary-total {
  display: flex; justify-content: space-between;
  font-weight: 800; font-size: 1.15rem; padding-top: .8rem;
}

/* ---- product page v2 ---- */
.product-title-block { margin-bottom: 1.5rem; }
.product-eyebrow {
  font-size: .8rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .1em;
  color: var(--secondary); opacity: .8; margin-bottom: .35rem;
}
.product-title { margin: 0; font-size: clamp(1.5rem, 3.5vw, 2.3rem); font-weight: 800; }
/* Garment style/model line under the title ("Gildan 5000") — shown when the
   shop's "Show product style and model" setting is on. */
/* Garment style ("Gildan 5000") leading the Product Details list — shop setting
   show_product_style. Only used when the admin's details HTML is NOT already a
   list; when it is, the style becomes a real first <li> of that list instead and
   inherits its styling. */
.style-details-lead { margin: 0 0 .5rem; padding-left: 1.15rem; }

.gallery { display: flex; gap: 1rem; align-items: flex-start; }
.gallery-main {
  flex: 1; border: 1px solid #e4e4e4; border-radius: 8px;
  padding: 1rem; background: #fff;
}
.gallery-main img { width: 100%; object-fit: contain; }
.gallery-thumbs { display: flex; flex-direction: column; gap: .6rem; width: 72px; flex-shrink: 0; }
.gallery-thumbs button {
  border: 1px solid #ddd; border-radius: 6px; background: #fff;
  padding: 4px; cursor: pointer;
}
.gallery-thumbs button.active { border-color: var(--secondary); outline: 2px solid var(--secondary); }
.gallery-thumbs img { width: 100%; height: 56px; object-fit: contain; }
.gallery-view[hidden] { display: none; }
.gallery-thumb { position: relative; display: block; }
/* Additional product photos (not colour-swappable mockups). */
.gallery-photo { display: block; }
.gallery-photo img { width: 100%; display: block; }
.gallery-thumb-label {
  display: block; text-align: center; font-size: .7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; margin-top: 3px; color: var(--text);
}

/* On mobile, stack the main image on top and lay the FRONT/BACK thumbnails
   in a horizontal row across the bottom instead of a left-hand column. */
@media (max-width: 760px) {
  .gallery { flex-direction: column-reverse; }
  .gallery-thumbs {
    flex-direction: row; flex-wrap: wrap; justify-content: center;
    width: 100%; gap: .8rem;
  }
  .gallery-thumbs button { width: 72px; flex: 0 0 auto; }
}

.option-label-value { font-weight: 400; text-transform: none; }
/* crisp square-ish swatches */
.swatches .swatch span {
  width: 40px; height: 34px;
  border: 1px solid rgba(0,0,0,.25); border-radius: 6px;
}
.swatch input:checked + span {
  border-color: #fff;
  outline: 2px solid var(--primary); outline-offset: 0;
}
.size-pill span { border-radius: 8px; padding: .55rem 1.1rem; }

.qty-stepper {
  display: inline-flex; align-items: stretch;
  border: 1px solid #ccc; border-radius: 8px; overflow: hidden; background: #fff;
}
.qty-stepper button {
  width: 44px; border: none; background: #fff;
  font-size: 1.25rem; cursor: pointer; line-height: 1;
}
.qty-stepper button:hover { background: #f2f2f2; }
.qty-stepper input {
  width: 56px; border: none; border-left: 1px solid #eee; border-right: 1px solid #eee;
  text-align: center; font-size: 1rem; padding: .55rem 0;
  -moz-appearance: textfield; appearance: textfield;
}
.qty-stepper input::-webkit-outer-spin-button,
.qty-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.purchase-actions { display: flex; flex-direction: column; gap: .7rem; margin-top: 1.5rem; max-width: 480px; }
.btn-dark { background: var(--primary); color: var(--on-primary); border-radius: 10px; }
.btn-dark:hover { filter: brightness(1.15); }
.product-description {
  margin-top: 2rem; max-width: 70ch;
  background: #f8f9fb; border: 1px solid #e6e7eb; border-radius: 12px;
  padding: 1.15rem 1.35rem; box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
.product-description + .product-description { margin-top: 1rem; }
.product-description h2 { font-size: 1.15rem; margin: 0 0 .5rem; }
.product-description p { margin: 0; line-height: 1.6; color: #333; }

/* style-level product details: free-form HTML from the main site.
   Collapsible accordion on mobile; always expanded on desktop. */
.style-details-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  width: 100%; margin: 0; padding: 0;
  background: none; border: 0; cursor: default;
  font: inherit; color: inherit; text-align: left;
}
.style-details-toggle h2 { margin: 0; }
.style-details-chevron { display: none; }
.product-style-details .style-details-body { margin-top: .5rem; line-height: 1.6; color: #333; }
.product-style-details .style-details-body > :first-child { margin-top: 0; }
.product-style-details .style-details-body > :last-child { margin-bottom: 0; }
.product-style-details .style-details-body p { margin: 0 0 .75rem; }
.product-style-details .style-details-body ul,
.product-style-details .style-details-body ol { margin: 0 0 .75rem; padding-left: 1.25rem; }
.product-style-details .style-details-body li { margin: .2rem 0; }

@media (max-width: 768px) {
  .style-details-toggle { cursor: pointer; }
  .style-details-chevron {
    display: inline-block; flex: none; color: #666;
    transition: transform .2s ease;
  }
  .product-style-details .style-details-body { display: none; }
  .product-style-details.is-open .style-details-body { display: block; }
  .product-style-details.is-open .style-details-chevron { transform: rotate(180deg); }
}

/* product trust bar (print method · ships-in · est. delivery) + share */
.product-trust {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap; margin-top: 2.25rem;
}
.trust-bar {
  display: flex; flex-wrap: wrap; flex: 1; min-width: 280px;
  background: #fff; border: 1px solid #e8e8e8; border-radius: 12px;
}
.trust-item { display: flex; align-items: center; gap: .8rem; padding: 1rem 1.5rem; flex: 1; min-width: 200px; }
.trust-item + .trust-item { border-left: 1px solid #eee; }
.trust-item > i { font-size: 1.5rem; color: var(--secondary); flex-shrink: 0; }
.trust-item strong { display: block; font-size: .95rem; }
.trust-item span { display: block; font-size: .82rem; opacity: .6; }
.trust-deliv { color: #2e7d32; opacity: 1; font-weight: 700; }

.product-share { display: flex; align-items: center; gap: .55rem; }
.share-label { font-weight: 700; opacity: .55; font-size: .9rem; }
.share-btn {
  width: 38px; height: 38px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid #ddd; background: #fff; color: var(--text); cursor: pointer;
  text-decoration: none; font-size: 1rem; transition: background .12s, border-color .12s, color .12s;
}
.share-btn:hover { border-color: var(--secondary); }
.share-btn.copied { background: #2e7d32; border-color: #2e7d32; color: #fff; }
@media (max-width: 760px) {
  .trust-bar { flex-direction: column; }
  .trust-item + .trust-item { border-left: none; border-top: 1px solid #eee; }
}

/* ---- sticky mobile add-to-cart bar ---- */
/* Hidden on desktop; on mobile it slides up from the bottom once the
   in-page Add to cart scrolls out of view (.visible toggled by JS). */
.sticky-cart {
  display: none;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 999;
  align-items: center;
  gap: 1rem;
  padding: .65rem 1rem;
  padding-bottom: calc(.65rem + env(safe-area-inset-bottom));
  background: #fff;
  border-top: 1px solid #e4e4e4;
  box-shadow: 0 -4px 16px rgba(0,0,0,.12);
  transform: translateY(110%);
  transition: transform .25s ease;
}
.sticky-cart-price { display: flex; flex-direction: column; line-height: 1.15; }
.sticky-cart-label {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; opacity: .6;
}
#sticky-cart-total { font-size: 1.1rem; font-weight: 700; }
.sticky-cart-btn { flex: 1; margin: 0; }
@media (max-width: 768px) {
  .sticky-cart { display: flex; }
  .sticky-cart.visible { transform: translateY(0); }

  /* Compact colour swatches on mobile — same tap target intent, far less
     vertical space than the 40×34 desktop squares. Desktop is untouched. */
  .swatches { gap: .4rem; }
  .swatches .swatch span { width: 32px; height: 28px; }
}

/* ---- confirmation ---- */
.confirmation-v2 { max-width: 900px; min-width: min(820px, 100%); }
.confirm-head { text-align: center; margin: 1rem 0 2rem; }
.confirm-head h1 { margin: 0 0 .6rem; }
.confirm-head p { margin: .2rem 0; }
.confirm-check {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--primary); color: var(--on-primary);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.7rem; margin-bottom: 1rem;
  box-shadow: 0 6px 18px rgba(0,0,0,.12);
}
/* Order-status tracker: three-step path with a connecting line */
.order-track {
  list-style: none; margin: 0 0 2rem; padding: 0;
  display: flex; justify-content: space-between; position: relative;
  max-width: 640px; margin-left: auto; margin-right: auto;
}
.order-track-step {
  flex: 1 1 0; text-align: center; position: relative;
  display: flex; flex-direction: column; align-items: center; gap: .5rem;
}
/* connector line runs from the centre of one dot to the next */
.order-track-step::before {
  content: ""; position: absolute; top: 17px; left: -50%; width: 100%;
  height: 3px; background: #e0e0e0; z-index: 0;
}
.order-track-step:first-child::before { display: none; }
.order-track-dot {
  position: relative; z-index: 1;
  width: 36px; height: 36px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .9rem; font-weight: 700;
  background: #fff; color: #9a9a9a; border: 3px solid #e0e0e0;
}
.order-track-label { font-size: .82rem; line-height: 1.25; color: #777; max-width: 9rem; }
/* completed steps: filled primary, connector into them is primary too */
.order-track-step.is-done .order-track-dot,
.order-track-step.is-current .order-track-dot {
  background: var(--primary); color: var(--on-primary); border-color: var(--primary);
}
.order-track-step.is-done::before,
.order-track-step.is-current::before { background: var(--primary); }
.order-track-step.is-current .order-track-dot {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 22%, transparent);
}
.order-track-step.is-done .order-track-label,
.order-track-step.is-current .order-track-label { color: #333; font-weight: 600; }

.order-status-banner {
  max-width: 640px; margin: 0 auto 2rem; padding: .9rem 1.1rem;
  border-radius: 10px; text-align: center; font-size: .95rem;
  border: 1px solid #e4c200; background: #fff8dc;
}
.order-status-banner.order-status-cancelled { border-color: #e0b4b4; background: #fdecec; }
.order-tracking {
  text-align: center; margin: -1rem auto 2rem; font-size: .95rem; color: #444;
}
.order-tracking a { color: var(--secondary); }

/* Local-pickup details on the order page (where + when to collect). Sits in
   the same slot the tracking line uses for a delivery, so the two never
   appear together and the negative top margin stays correct either way. */
.order-pickup {
  max-width: 420px; margin: -1rem auto 2rem; padding: 1rem 1.25rem;
  border: 1px solid #e4e4e4; border-radius: 12px; background: #fafafa;
  text-align: center; font-size: .95rem; color: #444;
}
.order-pickup-line { margin: 0 0 .65rem; line-height: 1.5; }
.order-pickup-line:last-of-type { margin-bottom: .4rem; }
.order-pickup .muted { margin: 0; }

@media (max-width: 520px) {
  .order-track-label { font-size: .72rem; }
  .order-track-dot { width: 32px; height: 32px; }
  .order-track-step::before { top: 15px; }
}

.confirm-card {
  background: #fafafa; border: 1px solid #e4e4e4; border-radius: 12px;
  padding: 1.5rem 1.75rem;
}
.confirm-card .aside-line { border-bottom: 1px solid #ececec; }
.confirm-card .aside-line:last-of-type { border-bottom: none; }
.confirm-actions { text-align: center; margin-top: 2rem; }
.confirm-check-muted { background: #ececec; color: #555; }
.order-lookup {
  display: flex; gap: .7rem; justify-content: center;
  max-width: 620px; margin: 0 auto; flex-wrap: wrap;
}
.order-lookup input {
  flex: 1; min-width: 200px;
  padding: .8rem 1rem; font-size: .95rem;
  border: 1px solid #ccc; border-radius: 6px;
}
.order-lookup input:focus { outline: 2px solid var(--secondary); outline-offset: -1px; }

/* ---- product mockups (garment + design overlay) ---- */
.mockup { position: relative; width: 100%; }
.mockup > img { width: 100%; height: auto; display: block; }
/* Designs that aren't the full 2200x3000 print ratio anchor to the TOP of the
   canvas box (not vertically centred). */
.mockup-overlay { position: absolute; object-fit: contain; object-position: center top; }

/* Jersey number drawn in the place-it box (live preview + cart/order render).
   font-size is fit to the box height by fitJerseyNumbers() in footer.php. */
.mockup-number {
  /* Centred in the box by default (front + sleeves). The back is the exception:
     its number sits high up, just under the collar (see override below). */
  position: absolute; display: flex; align-items: center; justify-content: center;
  overflow: hidden; line-height: 1; pointer-events: none;
  color: var(--jersey-color, #15233b);
  /* Outlined numbers: stroke under the fill, so a thick outline thickens the
     glyph outward instead of eating into it (the default centres the stroke). */
  paint-order: stroke fill;
}
.mockup-number[data-surface="back"] { align-items: flex-start; }
.mockup-number span { display: block; white-space: nowrap; }

/* Jersey fonts. Add more @font-face + .jersey-font-{name} pairs as new fonts
   are dropped in /fonts/ (the name matches Shops_Products.jersey_font). */
@font-face {
  font-family: 'JerseyBasketball';
  src: url('/fonts/Basketball.otf') format('opentype');
  font-display: swap;
}
.jersey-font-basketball { font-family: 'JerseyBasketball', 'Arial Narrow', Impact, sans-serif; font-weight: 800; }
@font-face {
  font-family: 'JerseyUniversNextProHeavy';
  src: url('/fonts/UniversNextProHeavy.ttf') format('truetype');
  font-display: swap;
}
.jersey-font-universnextproheavy { font-family: 'JerseyUniversNextProHeavy', 'Arial Narrow', Impact, sans-serif; font-weight: 800; }
@font-face {
  font-family: 'JerseyAlfaSlabOne';
  src: url('/fonts/AlfaSlabOne-Regular.ttf') format('truetype');
  font-display: swap;
}
/* Alfa Slab One is a heavy slab-serif that already ships at one weight, so it
   takes a serif fallback stack and normal weight rather than the condensed
   sans/800 the two jersey faces above use — synthesising bold on an already-
   black face just smears it. The second selector is a safety net: helpers.php
   slugs jersey_font straight into the class name, so it matches whether the
   admin stores "alfaslabone" or the filename-shaped "alfaslabone-regular". */
.jersey-font-alfaslabone,
.jersey-font-alfaslabone-regular { font-family: 'JerseyAlfaSlabOne', Rockwell, 'Courier Bold', Georgia, serif; font-weight: 400; }
@font-face {
  font-family: 'JerseyAnton';
  src: url('/fonts/Anton.ttf') format('truetype');
  font-display: swap;
}
.jersey-font-anton { font-family: 'JerseyAnton', 'Arial Narrow', Impact, sans-serif; font-weight: 400; }
@font-face {
  font-family: 'JerseyChunkFive';
  src: url('/fonts/ChunkFive_Ex.ttf') format('truetype');
  font-display: swap;
}
.jersey-font-chunkfive_ex,
.jersey-font-chunkfiveex,
.jersey-font-chunkfive-ex { font-family: 'JerseyChunkFive', Rockwell, Georgia, serif; font-weight: 400; }
@font-face {
  font-family: 'JerseyHighJakarta';
  src: url('/fonts/HighJakarta.ttf') format('truetype');
  font-display: swap;
}
/* The file's internal family is "High Jakarta" (two words), so the admin may
   store it spaced, underscored or hyphenated — fontSlug() keeps _ and - but
   drops spaces, giving three possible class names for the one face. Same safety
   net as ChunkFive_Ex and NBA_Bulls above. */
.jersey-font-highjakarta,
.jersey-font-high_jakarta,
.jersey-font-high-jakarta { font-family: 'JerseyHighJakarta', Impact, 'Arial Narrow', sans-serif; font-weight: 400; }
@font-face {
  /* MachInfested.otf — the file's internal family is "ITC Machine Std"; the
     alias below is what the stylesheet and the DB slug agree on. */
  font-family: 'JerseyMachInfested';
  src: url('/fonts/MachInfested.otf') format('opentype');
  font-display: swap;
}
.jersey-font-machinfested { font-family: 'JerseyMachInfested', Impact, 'Arial Narrow', sans-serif; font-weight: 400; }
@font-face {
  font-family: 'JerseyNBABulls';
  src: url('/fonts/NBA_Bulls.ttf') format('truetype');
  font-display: swap;
}
.jersey-font-nba_bulls,
.jersey-font-nbabulls,
.jersey-font-nba-bulls { font-family: 'JerseyNBABulls', Impact, 'Arial Narrow', sans-serif; font-weight: 400; }
@font-face {
  /* WinterPark.otf — internal family is just "Winter". */
  font-family: 'JerseyWinterPark';
  src: url('/fonts/WinterPark.otf') format('opentype');
  font-display: swap;
}
.jersey-font-winterpark { font-family: 'JerseyWinterPark', 'Arial Narrow', Impact, sans-serif; font-weight: 400; }

/* Jersey number entry on the product page — a titled group of per-position
   number fields, so it's clear each input maps to a print location. */
.jersey-fields {
  border: 1px solid #e3e3e3; border-radius: 12px;
  padding: .55rem 1rem 1rem; margin: 1rem 0 0; background: #fcfcfc;
}
.jersey-legend {
  font-weight: 700; font-size: .92rem; padding: 0 .45rem;
  display: inline-flex; align-items: center; gap: .45rem;
}
.jersey-legend i { color: var(--primary); }
.jersey-optional {
  font-weight: 500; font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
  color: #fff; background: #b9b9b9; border-radius: 999px; padding: .1rem .5rem;
}
.jersey-required {
  font-weight: 600; font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
  color: #fff; background: #c0392b; border-radius: 999px; padding: .1rem .5rem;
}
.req-star { color: #c0392b; }
.jersey-warning {
  margin: .8rem 0 0; font-size: .82rem; color: #c0392b; font-weight: 600;
  display: flex; align-items: center; gap: .4rem;
}
/* keep the warning hidden until JS reveals it (the display:flex above would
   otherwise override the `hidden` attribute) */
.jersey-warning[hidden] { display: none; }
/* a required field left empty on add-to-cart: 2px red border + light red fill */
.jersey-field-box.is-missing { border: 2px solid #c0392b; background: #fdecec; }
.form-flash {
  display: flex; align-items: center; gap: .5rem;
  padding: .7rem .9rem; border-radius: 9px; margin: 0 0 1rem; font-size: .9rem;
}
.form-flash-error { background: #fdecec; border: 1px solid #e0b4b4; color: #a5281b; }
.jersey-hint { margin: 0 0 .8rem; font-size: .82rem; color: #777; }
.jersey-grid { display: flex; flex-wrap: wrap; gap: .7rem; }
.jersey-field {
  flex: 1 1 8rem; min-width: 7rem; display: flex; flex-direction: column;
  gap: .3rem; cursor: text;
}
.jersey-field-label {
  font-size: .72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .03em; color: #555;
  /* Reserve two lines so short ("Front") and long ("Right Sleeve") labels
     occupy the same height and every input box below stays aligned. */
  line-height: 1.1; min-height: 2.2em;
}
.jersey-fee { color: #888; font-weight: 600; text-transform: none; letter-spacing: 0; }
/* "required" beside a position that must be filled in. Takes the slot the
   "(+$5.00)" add-on price uses for an optional position — a required one can
   never add anything, its fee is already in the displayed price. Same red as
   the asterisk and the nameplate pill. */
.jersey-req-text {
  color: #c0392b; font-weight: 600; text-transform: none; letter-spacing: 0;
}
.jersey-field-box {
  display: flex; align-items: center; gap: .1rem;
  border: 1.5px solid #d6d6d6; border-radius: 9px; padding: 0 .65rem;
  background: #fff; transition: border-color .15s, box-shadow .15s;
}
.jersey-field-box:focus-within {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 20%, transparent);
}
.jersey-hash { color: #b3b3b3; font-weight: 700; font-size: 1.05rem; }
.jersey-input,
.sleeve-text-input {
  flex: 1; width: 100%; border: 0; outline: 0; background: transparent;
  padding: .55rem .15rem; font-size: 1.15rem; font-weight: 700;
  letter-spacing: .05em; text-align: left; color: #1a1a1a;
}
/* sleeve text is free text, not a big 3-char number — ease the size/spacing */
.sleeve-text-input { font-size: 1rem; letter-spacing: .01em; }
/* Nameplate name input — a single full-width text field in the same card. */
.nameplate-field { display: block; }
.nameplate-input {
  width: 100%; box-sizing: border-box;
  border: 1px solid #d5d5d8; border-radius: 8px; background: #fff;
  padding: .6rem .75rem; font-size: 1rem; font-weight: 600;
  letter-spacing: .02em; color: #1a1a1a; outline: 0;
}
.nameplate-input:focus { border-color: #1a1a1a; }

/* Card images: garment mockups are square PNGs. Frame the uploaded photo in a
   matching square box (contain, letterboxed if it isn't square) so a photo-led
   card is the same size as a mockup-led card in the grid. */
.product-card .mockup > img { height: auto; width: 100%; object-fit: contain; }
.product-card .gallery-photo {
  aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.product-card .gallery-photo > img { width: 100%; height: 100%; object-fit: contain; }
/* Photo-led card toggles between the photo and the front mockup on colour pick.
   Explicit [hidden] rules because the display:flex above would otherwise beat
   the hidden attribute. */
.product-card .gallery-photo[hidden] { display: none; }
.card-mockup-lead { display: block; }
.card-mockup-lead[hidden] { display: none; }

/* mockup debug (?debug=1) */
.mockup-debug-box {
  position: absolute; pointer-events: none;
  border: 2px dashed #ff00ff;
  background: rgba(255,0,255,.08);
}
.mockup-debug { font-size: .75rem; margin: .75rem 0 0; text-align: left; width: 100%; }
.mockup-debug summary { cursor: pointer; font-weight: 700; color: #c026d3; }
.mockup-debug pre {
  background: #16161a; color: #7fff7f;
  padding: .6rem; border-radius: 6px;
  overflow: auto; max-height: 420px; font-size: .72rem;
  white-space: pre-wrap; word-break: break-word;   /* wrap long URLs instead of scrolling */
}
.mockup-debug-note { font-size: .75rem; color: #c026d3; }

/* ---- cart (Shopify-style) ---- */
.cart-page { max-width: 1100px; min-width: min(1000px, 100%); }
.cart-head { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.cart-head h1 { margin-bottom: .5rem; }
.cart-continue { font-size: .9rem; font-weight: 600; text-decoration: underline; }
.cart-columns {
  display: grid; grid-template-columns: 1fr 220px 110px;
  gap: 1rem; padding: .9rem 0 .5rem;
  border-bottom: 1px solid #e4e4e4;
  font-size: .75rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; opacity: .6;
}
.cart-col-total { text-align: right; }
.cart-line {
  display: grid; grid-template-columns: 1fr 220px 110px;
  gap: 1rem; align-items: center;
  padding: 1.25rem 0; border-bottom: 1px solid #ececec;
}
.cart-line-product { display: flex; gap: 1rem; align-items: center; }
.cart-line-image { width: 90px; flex-shrink: 0; }
.cart-line-image .mockup { border: 1px solid #eee; border-radius: 8px; background: #fff; overflow: hidden; }
.cart-line-name { font-weight: 700; }
.cart-line-name:hover { text-decoration: underline; }
.cart-line-variant, .cart-line-unit { font-size: .88rem; }
.cart-line-variant { display: flex; gap: .4rem; margin: .25rem 0; flex-wrap: wrap; align-items: center; }
.cart-edit-toggle {
  background: none; border: none; padding: 0;
  color: var(--secondary); font-size: .82rem; font-weight: 700;
  text-decoration: underline; cursor: pointer;
}
.cart-line-editor { display: flex; gap: .6rem; margin: .4rem 0; flex-wrap: wrap; }
.cart-line-editor[hidden] { display: none; }

/* styled dropdowns */
.dd { position: relative; }
.dd-toggle {
  display: inline-flex; align-items: center; justify-content: space-between; gap: .6rem;
  min-width: 150px; padding: .5rem .8rem;
  border: 1px solid #ccc; border-radius: 3px; background: #fff;
  font-size: .88rem; font-weight: 600; cursor: pointer;
}
.dd-toggle:focus { outline: 2px solid var(--secondary); outline-offset: -1px; }
.dd-toggle b { font-weight: 400; opacity: .55; }
.dd-panel {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 50;
  width: 250px; padding: .6rem;
  background: #fff; border: 1px solid #e2e2e2; border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0,0,0,.16);
}
.dd-search {
  width: 100%; padding: .5rem .65rem; margin-bottom: .45rem;
  border: 1px solid #ddd; border-radius: 6px; font-size: .88rem;
}
.dd-list { list-style: none; margin: 0; padding: 0; max-height: 250px; overflow: auto; }
.dd-list li { padding: .45rem .55rem; border-radius: 4px; cursor: pointer; font-size: .9rem; }
.dd-list li:hover { background: #f3f3f3; }
.dd-list li.selected { font-weight: 700; }
.cart-line-qty { display: flex; align-items: center; gap: .75rem; }
.cart-line-qty .qty-stepper input { width: 48px; }
.cart-line-remove {
  background: none; border: none; cursor: pointer;
  font-size: 1.1rem; opacity: .55;
}
.cart-line-remove:hover { opacity: 1; }
.cart-line-total { text-align: right; font-weight: 700; }
.cart-footer { display: flex; justify-content: flex-end; padding-top: 1.5rem; }
.cart-totals { width: 100%; max-width: 360px; text-align: right; }
.cart-subtotal {
  display: flex; justify-content: space-between;
  font-size: 1.15rem; margin-bottom: .35rem;
}
.cart-totals .btn { margin-top: .9rem; }
@media (max-width: 700px) {
  .cart-columns { display: none; }
  .cart-line { grid-template-columns: 1fr; }
  .cart-line-total { text-align: left; }
}

/* ---- checkout (Shopify-style) ---- */
.checkout-v2 {
  display: grid;
  /* minmax(0, fr) kills the implicit min-content sizing, so the column
     ratio stays FIXED no matter which sections are shown/hidden */
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr);
  width: 100%;
  max-width: 1280px; margin: 0 auto; align-items: start;
}
/* hard minimums so toggling shipping/address sections can never reflow */
.checkout-main  { min-width: min(560px, 100%); }
.checkout-aside { min-width: min(380px, 100%); }
@media (max-width: 880px) {
  .checkout-main, .checkout-aside { min-width: 0; }
}
@media (max-width: 880px) { .checkout-v2 { grid-template-columns: 1fr; } }
.checkout-main { padding: 2rem 3rem 3rem 1.5rem; }
.checkout-crumbs { font-size: .85rem; margin-bottom: 1.25rem; }
.checkout-crumbs a { color: var(--secondary); font-weight: 600; }
.checkout-crumbs span { opacity: .6; }
.checkout-section-title {
  font-size: 1.05rem; font-weight: 700;
  margin: 1.75rem 0 .9rem; text-transform: uppercase; letter-spacing: .03em;
}
.cfield { margin-bottom: .85rem; }
.cfield input, .cfield select {
  width: 100%; padding: .85rem 1rem;
  border: 1px solid #d4d4d4; border-radius: 6px;
  font-size: .95rem; background: #fff;
}
.cfield select { appearance: none; -webkit-appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath fill='%23666' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center; background-size: 10px; padding-right: 2.4rem;
}
.cfield input:focus, .cfield select:focus {
  /* Keep a clearly visible border on focus in EVERY theme. The old inset
     outline used var(--secondary); on a white/light theme that painted the
     field borderless. A fixed dark focus border never disappears, and the
     themed ring is a soft glow on top (invisible-but-harmless on white). */
  outline: none;
  border-color: #1a1a1a;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--secondary) 22%, transparent);
}
.cfield.has-error input, .cfield.has-error select { border-color: #c0392b; }
.cfield-error { color: #c0392b; font-size: .82rem; display: block; margin-top: .25rem; }
.cfield-row { display: grid; grid-template-columns: 1fr 1fr; gap: .85rem; }
.cfield-row-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 560px) { .cfield-row, .cfield-row-3 { grid-template-columns: 1fr; } }

.ship-options { border: 1px solid #d4d4d4; border-radius: 6px; overflow: hidden; }
.ship-option {
  display: flex; align-items: center; gap: .9rem;
  padding: .95rem 1rem; cursor: pointer;
  border-bottom: 1px solid #e4e4e4; background: #fff;
}
.ship-option:last-child { border-bottom: none; }
.ship-option:has(input:checked) { background: rgba(0,0,0,.03); outline: 2px solid var(--secondary); outline-offset: -2px; }
.ship-option input { accent-color: var(--secondary); width: 18px; height: 18px; }
.ship-option-body { flex: 1; display: flex; flex-direction: column; }
.ship-option-label { font-weight: 600; font-size: .95rem; }
.ship-option-address { font-size: .85rem; }
.ship-option-price { font-weight: 700; }

.payment-page { max-width: 560px; }
.payment-box { margin-top: 1.5rem; display: flex; flex-direction: column; gap: 1.1rem; }

.checkout-main form { width: 100%; }
/* the hidden attribute must win over display:flex */
.address-locked[hidden] { display: none; }

.address-locked {
  display: flex; flex-direction: column; gap: .25rem;
  border: 1px solid #d4d4d4; border-radius: 6px;
  background: #f5f5f5; padding: .9rem 1rem;
  font-weight: 600;
}

/* Sizing / final-sale notice above the submit button. Amber rather than red:
   it is a "read this before you commit", not an error the customer has to fix,
   and a red block here would compete with real validation errors. */
.checkout-note {
  display: flex; align-items: flex-start; gap: .65rem;
  margin-top: 1.75rem; padding: .85rem 1rem;
  background: #fffaeb; border: 1px solid #fcd982; border-radius: 10px;
  font-size: .88rem; line-height: 1.5; color: #7a5303;
}
.checkout-note i { flex: none; margin-top: .15rem; color: #b7791f; }
.checkout-note strong { display: block; margin-bottom: .15rem; color: #6b4700; }

.checkout-actions {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; margin-top: 1.75rem; flex-wrap: wrap;
}
.checkout-return { font-size: .9rem; font-weight: 600; color: var(--secondary); }

.checkout-aside {
  background: #fafafa; border-left: 1px solid #e4e4e4;
  padding: 2rem 1.5rem; position: sticky; top: 0;
  min-height: 100%;
}
@media (max-width: 880px) { .checkout-aside { border-left: none; border-top: 1px solid #e4e4e4; position: static; } }
.aside-line { display: flex; align-items: center; gap: 1rem; padding: .6rem 0; }
.aside-thumb {
  position: relative; width: 64px; flex-shrink: 0;
  border: 1px solid #ddd; border-radius: 8px; background: #fff;
}
.aside-qty {
  position: absolute; top: -8px; right: -8px;
  background: var(--secondary); color: var(--on-secondary);
  font-size: .72rem; font-weight: 700;
  min-width: 20px; height: 20px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; padding: 0 5px;
}
.aside-info { flex: 1; display: flex; flex-direction: column; }
.aside-name { font-weight: 700; font-size: .92rem; }
.aside-price { font-weight: 600; font-size: .92rem; }
.aside-totals { border-top: 1px solid #e4e4e4; margin-top: 1rem; padding-top: 1rem; }
.aside-row { display: flex; justify-content: space-between; padding: .3rem 0; font-size: .95rem; }
.aside-row[hidden] { display: none; }
.aside-total { font-size: 1.1rem; padding-top: .7rem; }
.aside-total strong { font-size: 1.35rem; }
#aside-discount-row, .aside-discount { color: #2e7d32; }

/* Coupon entry in the order summary */
.coupon-box { border-top: 1px solid #e4e4e4; margin-top: 1rem; padding-top: 1rem; }
.coupon-label { display: block; font-size: .85rem; font-weight: 600; margin-bottom: .4rem; }
.coupon-row { display: flex; gap: .5rem; }
.coupon-row input {
  flex: 1; min-width: 0; padding: .55rem .7rem; border: 1.5px solid #d6d6d6;
  border-radius: 8px; font-size: .95rem; text-transform: uppercase;
}
.coupon-row input:focus { outline: 0; border-color: var(--primary); }
.coupon-apply { padding: .55rem 1.1rem; white-space: nowrap; }
.coupon-error { margin: .5rem 0 0; font-size: .82rem; color: #c0392b; }
.coupon-applied {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  background: #eef7ee; border: 1px solid #cfe6cf; border-radius: 8px;
  padding: .55rem .8rem; font-size: .9rem;
}
.coupon-applied i { color: #2e7d32; margin-right: .15rem; }
.coupon-remove { background: none; border: 0; color: #c0392b; font-size: .82rem; cursor: pointer; text-decoration: underline; }

/* ---- checkout test-mode coupon debug panel (admin-only, DEBUG only) ----
   Deliberately loud (dashed amber) so it can never be mistaken for a customer
   feature. Gated server-side in partials/checkout_debug_coupons.php. */
.coupon-debug {
  margin-bottom: 1rem; padding: .75rem .85rem;
  border: 1.5px dashed #e0a800; border-radius: 8px;
  background: #fffbea; color: #5b4a00; font-size: .85rem;
}
.coupon-debug-head { display: flex; align-items: center; gap: .4rem; margin-bottom: .55rem; }
.coupon-debug-head i { color: #b8860b; }
.coupon-debug-title { font-weight: 700; text-transform: uppercase; letter-spacing: .03em; font-size: .78rem; }
.coupon-debug-badge {
  margin-left: auto; font-size: .65rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; background: #e0a800; color: #fff;
  padding: .1rem .4rem; border-radius: 4px;
}
.coupon-debug-empty { margin: 0; font-style: italic; opacity: .8; }
.coupon-debug-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }
.coupon-debug-item { display: flex; flex-direction: row; align-items: center; gap: .5rem; padding-bottom: .5rem; border-bottom: 1px solid #f0e3a8; }
.coupon-debug-item:last-child { padding-bottom: 0; border-bottom: 0; }
.coupon-debug-code {
  font-weight: 700; font-size: .85rem;
  background: #fff; border: 1px solid #e0c84d; border-radius: 4px; padding: .1rem .35rem;
  user-select: all;
}
.coupon-debug-summary { font-weight: 600; margin-left: auto; text-align: right; }
.coupon-debug-note { margin: .6rem 0 0; font-size: .72rem; font-style: italic; opacity: .75; }

/* ---- info pages ---- */
.static-page { max-width: 800px; }
.static-page h1 { margin-bottom: 1.25rem; }
.static-page p { max-width: 65ch; }
.static-page a { color: var(--secondary); font-weight: 600; text-decoration: underline; }
.static-page ul { max-width: 65ch; margin: .5rem 0; padding-left: 1.25rem; }
.static-page li { margin: 0 0 .35rem; }
.faq-item { margin-bottom: 1.5rem; }
.faq-item h3 { margin: 0 0 .35rem; font-size: 1.05rem; }
.faq-item p { margin: 0; }
/* Admin-authored override body (Shops_Pages.content, nl2br plain text) */
.static-content { max-width: 65ch; line-height: 1.65; white-space: normal; }
.static-content a { color: var(--secondary); font-weight: 600; text-decoration: underline; }
.contact-email { font-size: 1.05rem; margin: 1rem 0; }
.confirm-help { text-align: center; margin-top: 1.25rem; font-size: .9rem; }

/* ---- above-footer banner (its own image) ---- */
.footer-banner { display: flex; justify-content: center; padding: 1.5rem 1rem; }
.footer-banner img { display: block; max-height: 300px; max-width: 100%; width: auto; height: auto; }
/* on phones: edge-to-edge, no padding, sitting flush against the footer */
@media (max-width: 600px) {
  .footer-banner { padding: 0; }
  .footer-banner img { width: 100%; max-height: none; }
}

/* ---- footer ---- */
.footer {
  background: var(--footer-bg, var(--secondary));
  /* always the opposite of the footer background (auto-contrast) */
  color: var(--on-footer, #fff);
  margin-top: auto; padding-top: 1rem;
}
.footer-inner {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 2rem;
  padding: 2.5rem 1.5rem;
  max-width: 1280px;
  margin: 0 auto;
}
/* minmax(0,...) lets the tracks shrink below their content's min-content so a
   wide brand logo / long link label can't force the footer past a narrow phone
   viewport (was a fixed-240px brand column → horizontal scroll under ~378px). */
@media (max-width: 760px) { .footer-inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
/* min(240px, 100%): keep the 240px cap on wide screens, but never exceed the
   (now shrinkable) column on mobile. */
.footer-brand img { max-height: 80px; max-width: min(240px, 100%); margin-bottom: .7rem; }
.footer-brand-name { display: block; font-size: 1.2rem; font-weight: 800; margin-bottom: .35rem; }
.footer-brand p { opacity: .7; font-size: .9rem; }
.footer-col h4 {
  text-transform: uppercase; font-size: .85rem; margin: 0 0 .7rem;
  /* contrast-safe on any footer colour */
  color: var(--on-footer, #fff); opacity: .9;
}
.footer-col a { display: block; font-size: .88rem; opacity: .8; padding: .18rem 0; }
.footer-col a:hover { opacity: 1; }
.footer-base {
  border-top: 1px solid rgba(255,255,255,.15);
  text-align: center;
  padding: 1rem;
  font-size: .8rem;
  opacity: .7;
}

/* ---- bundles: promo strip + cards ---- */
.bundles-strip { margin-bottom: 2rem; }
.bundle-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.25rem;
}
.bundle-card {
  border: 1px solid #e4e4e4; border-radius: 10px; background: #fff;
  overflow: hidden; display: flex; flex-direction: column;
  transition: box-shadow .15s ease, transform .15s ease;
}
.bundle-card:hover { box-shadow: 0 10px 26px rgba(0,0,0,.12); transform: translateY(-2px); }
.bundle-card-media { position: relative; background: #f7f7f7; padding: .4rem; min-height: 200px; display: flex; align-items: center; justify-content: center; }
.bundle-card-media > img { height: 200px; width: 100%; object-fit: contain; }
.bundle-card-badge {
  position: absolute; top: .6rem; left: .6rem;
  background: var(--primary); color: var(--on-primary);
  font-size: .72rem; font-weight: 800; text-transform: uppercase;
  padding: .25rem .55rem; border-radius: 20px;
}
.bundle-card-body { padding: .9rem 1rem 1.1rem; display: flex; flex-direction: column; gap: .3rem; }
.bundle-card-tag { font-size: .72rem; font-weight: 700; text-transform: uppercase; opacity: .55; }
.bundle-card-body h3 { margin: 0; font-size: 1rem; font-weight: 700; }
.bundle-card-price { display: flex; align-items: baseline; gap: .5rem; margin-top: .15rem; }
.bundle-card-price .was { text-decoration: line-through; opacity: .5; font-size: .9rem; }
.bundle-card-price .now { font-weight: 800; font-size: 1.15rem; }

/* ---- bundle wizard ---- */
.bundle-page { max-width: 1280px; }   /* match the product page width */
.bundle-head { display: flex; gap: 1.5rem; align-items: center; margin-bottom: 1.5rem; flex-wrap: wrap; }
.bundle-head-image {
  width: 160px; flex-shrink: 0; border: 1px solid #e4e4e4;
  border-radius: 10px; background: #f7f7f7; overflow: hidden;
}
.bundle-head-image > img { width: 100%; height: 160px; object-fit: contain; }
.bundle-head-info { flex: 1; min-width: 240px; }
.bundle-price-summary { display: flex; align-items: baseline; gap: .8rem; margin-top: .6rem; flex-wrap: wrap; }
.bundle-was { text-decoration: line-through; opacity: .5; font-size: 1.1rem; }
.bundle-now { font-weight: 800; font-size: 1.7rem; }
.bundle-save-badge {
  background: var(--primary); color: var(--on-primary);
  font-weight: 800; font-size: .8rem; text-transform: uppercase;
  padding: .25rem .6rem; border-radius: 20px;
}

.bundle-steps-bar { display: flex; gap: .5rem; margin: 1rem 0 1.5rem; flex-wrap: wrap; }
.bundle-step-dot {
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: .85rem; cursor: pointer;
  background: #ececec; color: #888; border: 2px solid transparent;
}
.bundle-step-dot.active { background: var(--secondary); color: var(--on-secondary); }

.bundle-step { display: none; }
.bundle-step.active { display: block; }
.bundle-step-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2.5rem; align-items: start; }
.bundle-step-media {
  position: relative;
  border: 1px solid #e8e8e8; border-radius: 10px; background: #f7f7f7;
  padding: 1rem; display: flex; align-items: center; justify-content: center;
}
.bundle-step-media .mockup > img { width: 100%; height: auto; object-fit: contain; }
/* the per-item front/back gallery sits flush inside the media box */
.bundle-step-media .gallery { width: 100%; }
.bundle-step-media .gallery-main { border: none; padding: 0; background: transparent; }
.two-sided-badge {
  position: absolute; top: .6rem; right: .6rem; z-index: 2;
  background: var(--secondary); color: var(--on-secondary);
  font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
  padding: .25rem .55rem; border-radius: 20px;
}
.two-sided-badge i { margin-right: .3rem; }
.two-sided-tag { color: var(--secondary); font-weight: 800; }
.bundle-step-eyebrow { font-size: .78rem; font-weight: 700; text-transform: uppercase; opacity: .55; }
.bundle-step-name { margin: .2rem 0 .4rem; font-size: 1.4rem; }

/* per-step action buttons live in the right column, under the options.
   Stack them full-width so the primary CTA dominates; Back becomes a quiet
   link tucked underneath instead of crowding the Add/Buy buttons. */
.bundle-step-actions { display: flex; flex-direction: column; gap: .75rem; margin-top: 1.75rem; }
.bundle-step-actions .btn { width: 100%; }
.bundle-step-actions .bundle-back {
  order: 10;                       /* always last, under the primary CTA(s) */
  width: auto; align-self: center;
  background: #ededed; color: #666;
  font-weight: 600; opacity: 1; padding: .5rem 1.4rem; border-radius: 4px;
}
.bundle-step-actions .bundle-back:hover {
  background: #e2e2e2; color: var(--secondary); filter: none; text-decoration: none;
}
/* "Buy it now" is the express path — same colour as Add to Cart so the pair
   reads as one family, just stepped down in brightness to keep Add to Cart the
   primary of the two. Applies wherever the pair appears (product AND bundle
   pages); it used to be a bundle-only outline treatment.
   No border override: .btn already reserves 2px of transparent border, so the
   two stacked buttons stay exactly the same height. */
.btn-buy-now {
  background: var(--primary); color: var(--on-primary);
  filter: brightness(.85);
}
/* Hover lifts it back toward the primary rather than darkening further, so the
   feedback direction matches Add to Cart's. */
.btn-buy-now:hover { filter: brightness(.95); }
.btn-light { background: #ededed; color: var(--secondary); }
.btn-light:hover { filter: brightness(.95); }

/* Confirmation modal (e.g. removing a bundle from the cart) */
.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0,0,0,.5);
  display: flex; align-items: center; justify-content: center; padding: 1.5rem;
}
.modal-overlay[hidden] { display: none; }
.modal {
  background: #fff; border-radius: 12px; max-width: 420px; width: 100%;
  padding: 1.6rem 1.6rem 1.3rem; box-shadow: 0 12px 40px rgba(0,0,0,.25); text-align: center;
}
.modal h3 { margin: 0 0 .5rem; font-size: 1.2rem; }
.modal p  { margin: 0 0 1.2rem; color: #555; }
.modal-actions { display: flex; gap: .6rem; justify-content: center; }
.btn-danger { background: #c0392b; color: #fff; }
.btn-danger:hover { background: #a93226; }
@media (max-width: 760px) {
  .bundle-step-grid { grid-template-columns: 1fr; }
}

/* ---- cart: bundle grouping ---- */
.cart-bundle {
  border: 1px solid #e4e4e4; border-left: 3px solid var(--secondary);
  border-radius: 8px; padding: .25rem 1rem .5rem; margin: .5rem 0;
}
.cart-bundle-head {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; padding: .65rem 0 .4rem; border-bottom: 1px dashed #e0e0e0;
  margin-bottom: .25rem; flex-wrap: wrap;
}
.cart-bundle-label { font-weight: 800; text-transform: uppercase; font-size: .85rem; }
.cart-bundle-saving { font-weight: 700; font-size: .85rem; color: #2e7d32; }
.cart-bundle-discount .cart-line-total { color: #2e7d32; }
.cart-bundle-discount .cart-line-name { font-weight: 600; opacity: .85; }
.cart-savings { color: #2e7d32; font-size: 1rem; }

/* ---- bundle layered preview: one item full size + smaller items on top ---- */
.bundle-stack { position: relative; width: 100%; }
.bundle-stack-base { width: 88%; margin: 0 auto; }
.bundle-stack-base .mockup > img { width: 100%; height: auto; display: block; }
.bundle-stack-overlay {
  position: absolute; width: 42%;
  background: #fff; border: 2px solid #fff; border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,.18); overflow: hidden;
}
.bundle-stack-overlay .mockup { width: 100%; }
.bundle-stack-overlay .mockup > img { width: 100%; height: auto; display: block; }
.bundle-stack-o1 { right: 2%;  bottom: 2%; }
.bundle-stack-o2 { left: 2%;   bottom: 2%; }
.bundle-stack-o3 { right: 2%;  top: 2%; }
.bundle-stack-more {
  position: absolute; left: 4%; top: 4%; z-index: 2;
  min-width: 30px; height: 30px; padding: 0 6px;
  background: var(--secondary); color: var(--on-secondary);
  font-weight: 800; font-size: .8rem; border-radius: 16px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 10px rgba(0,0,0,.22);
}
/* keep the small layers small even though the design overlay shares .mockup */
.bundle-head-image .bundle-stack-base .mockup > img { height: auto; }

/* ---- 404 page ---- */
.error-page .error-hero {
  text-align: center; padding: 2.5rem 1rem 2rem; margin-bottom: 1rem;
}
.error-hero .error-code {
  font-size: 4.5rem; font-weight: 800; line-height: 1;
  color: var(--primary); letter-spacing: .02em;
}
.error-hero h1 { margin: .5rem 0 .4rem; font-size: 1.6rem; }
.error-hero p { max-width: 46ch; margin: 0 auto; }
.error-actions {
  margin-top: 1.4rem; display: flex; gap: .75rem;
  justify-content: center; flex-wrap: wrap;
}

/* ---- button loading spinner (Stripe pay button, etc.) ---- */
.btn-spin {
  display: inline-block; width: 1em; height: 1em; vertical-align: -0.15em;
  margin-right: .5em; border: 2px solid currentColor;
  border-right-color: transparent; border-radius: 50%;
  animation: btn-spin .6s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
.btn.is-loading { cursor: progress; opacity: .9; }
.btn:disabled { cursor: not-allowed; }

/* ---- active-window: status banner + live countdown ---- */
.shop-status-banner {
  text-align: center; padding: .6rem 1rem; font-size: .9rem; font-weight: 600;
  line-height: 1.4;
}
.shop-status-banner.is-before { background: var(--primary); color: var(--on-primary); }
.shop-status-banner.is-after  { background: #3a3a3a; color: #fff; }
.shop-status-banner i { margin-right: .4rem; }

.shop-countdown {
  width: 100%; margin: 0 0 1.25rem; padding: 1.1rem 1.25rem;
  display: flex; flex-direction: column; align-items: center; gap: .25rem;
  border: 1px solid #e4e4e4; border-left: none; border-right: none; border-radius: 0;
  background: #fafafa; text-align: center;
}
.shop-countdown.is-closing { background: #fff7ed; border-color: #fed7aa; }
.shop-countdown-label {
  font-size: .8rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; opacity: .85;
}
.shop-countdown-label i { margin-right: .35rem; }
.shop-countdown-clock { font-size: 2.1rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.shop-countdown-sub { font-size: .85rem; opacity: .7; }
.purchase-closed { margin-top: 1rem; }

/* ---- admin bar (product pages, Level >= 8 only) ----
   Dark utility strip with a purple admin shield and quick links to the main
   site's control-panel pages for editing the current product. */
.admin-bar {
  background: #16161a;
  color: #e9e9ee;
  border-bottom: 2px solid #7c3aed;
  font-size: .85rem;
}
.admin-bar-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: .55rem 1.25rem;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem 1rem;
}
.admin-bar-brand {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-weight: 800;
  letter-spacing: .02em;
}
.admin-bar-icon {
  color: #a855f7;
  font-size: 1.05rem;
}
.admin-bar-pid {
  font-weight: 600;
  color: #a1a1aa;
  font-variant-numeric: tabular-nums;
}
.admin-bar-style {
  font-weight: 700;
  color: #e4e4e7;
  margin-left: .4rem;
  padding-left: .5rem;
  border-left: 1px solid #3f3f46;
}
.admin-bar-label {
  color: #a1a1aa;
  font-weight: 600;
}
.admin-bar-links {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin-left: auto;
}
.admin-bar-link {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .65rem;
  border-radius: 6px;
  background: #26262e;
  color: #e9e9ee;
  font-weight: 600;
  border: 1px solid #34343e;
  transition: background .15s ease, border-color .15s ease;
}
.admin-bar-link:hover {
  background: #7c3aed;
  border-color: #7c3aed;
  color: #fff;
}
.admin-bar-link i { color: #c4b5fd; }
.admin-bar-link:hover i { color: #fff; }
/* level-9 developer link — amber accent to set it apart */
.admin-bar-dev { border-color: #b45309; }
.admin-bar-dev i { color: #fbbf24; }
.admin-bar-dev:hover { background: #b45309; border-color: #b45309; }
@media (max-width: 768px) {
  /* Icon-only admin bar on small screens: hide every text label, keeping just
     the shield + product id and tappable icon buttons for each CP link. The
     buttons WRAP to a second row when they don't fit, rather than forcing one
     row — a non-wrapping row overflowed the viewport once a 6th button (Invoices)
     was added, dragging the whole page sideways. Wrapping keeps every button
     visible and can never push the page wider than the screen. */
  .admin-bar-title,
  .admin-bar-label,
  .admin-bar-link span { display: none; }
  .admin-bar          { overflow-x: hidden; }
  .admin-bar-inner  { flex-wrap: wrap; }
  .admin-bar-links  { flex-wrap: wrap; margin-left: auto; gap: .5rem; row-gap: .5rem; }
  .admin-bar-link {
    width: 40px; height: 40px;   /* comfortable tap target */
    flex: 0 0 auto;
    padding: 0; gap: 0;
    justify-content: center;
  }
  .admin-bar-link i { font-size: 1.05rem; }
}

/* ---- footer query timer (admin only) ----
   Collapsible per-request DB query breakdown shown beneath the footer. */
.site-version {
  max-width: 1200px;
  margin: 0 auto;
  padding: .5rem 1.25rem 0;
  color: #8b8b93;
  font-size: .75rem;
  text-align: center;
  letter-spacing: .02em;
}
.query-timer {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1.25rem 1rem;
  color: #cfcfd6;
  font-size: .8rem;
}
/* On mobile the sticky add-to-cart bar (fixed, bottom:0, z-index 999) overlaps
   whatever sits at the very bottom of the page. For signed-in staff that's the
   version stamp + SQL profiler, so give the footer extra bottom clearance only
   when those admin-only elements are present. Shoppers never see this. */
@media (max-width: 768px) {
  .footer:has(.site-version, .query-timer) {
    padding-bottom: calc(6rem + env(safe-area-inset-bottom));
  }
}
.query-timer-summary {
  display: flex;
  align-items: center;
  gap: .6rem;
  cursor: pointer;
  padding: .5rem .75rem;
  background: #1f1f25;
  border: 1px solid #34343e;
  border-radius: 6px;
  font-weight: 700;
  list-style: none;
}
.query-timer-summary::-webkit-details-marker { display: none; }
.query-timer-summary i { color: #a855f7; }
.query-timer-total {
  margin-left: auto;
  color: #fde047;
  font-variant-numeric: tabular-nums;
}
.query-timer-actions { margin: .6rem 0 0; }
.query-timer-copy {
  background: #2b2b34; color: #e7e7ea; border: 1px solid #44444f;
  border-radius: 6px; padding: .35rem .8rem; font-size: .8rem; font-weight: 600; cursor: pointer;
}
.query-timer-copy:hover { background: #34343e; }
.query-timer-list {
  margin: .5rem 0 0;
  padding: 0;
  list-style: none;
  max-height: 320px;
  overflow: auto;
  border: 1px solid #34343e;
  border-radius: 6px;
}
.query-timer-row {
  display: flex;
  gap: .75rem;
  padding: .4rem .75rem;
  border-bottom: 1px solid #2a2a32;
}
.query-timer-row:last-child { border-bottom: none; }
.query-timer-row:nth-child(odd) { background: #1c1c22; }
.query-timer-time {
  flex: 0 0 auto;
  min-width: 4.5rem;
  color: #fde047;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.query-timer-sql {
  flex: 1 1 auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: #d4d4dc;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: .76rem;
}
/* Slow query (>= 1s): red/orange highlight that wins over the zebra striping. */
.query-timer-row.is-slow,
.query-timer-row.is-slow:nth-child(odd) {
  background: #5a1e1e;
  border-left: 3px solid #f97316;
}
.query-timer-row.is-slow .query-timer-time { color: #fca5a5; font-weight: 700; }
.query-timer-row.is-slow .query-timer-sql  { color: #fde2e2; }
/* Diagnostic line when the profiler can't read a query log. */
.query-timer-note {
  margin: .5rem 0 0;
  padding: .6rem .75rem;
  background: #1c1c22;
  border: 1px solid #34343e;
  border-radius: 6px;
  color: #d4d4dc;
  line-height: 1.5;
}
.query-timer-note code { color: #fde047; }

/* ===========================================================================
   Invoices — customer invoice page + admin builder/manage. Uses the shared
   design tokens (--secondary etc.) and the existing .btn/.muted helpers.
   =========================================================================== */
.ta-r { text-align: right; white-space: nowrap; }

/* ---- shared invoice document (customer view + admin preview) ---- */
.invoice-page { max-width: 820px; margin: 0 auto; }
.invoice-doc {
  background: #fff; border: 1px solid #ececec; border-radius: 14px;
  padding: 1.75rem 1.9rem; box-shadow: 0 6px 24px rgba(0,0,0,.05);
}
.invoice-doc--flat { box-shadow: none; }
.invoice-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.invoice-head h1 { margin: 0; font-size: 1.7rem; }
/* Tshirtgang mark above the invoice title. The asset is a 160x160 square, so it
   is given a square box — letting it stretch to a banner would smear it. */
.invoice-logo {
  display: block; width: 44px; height: 44px; margin: 0 0 .6rem;
  border-radius: 8px; object-fit: contain;
}
.invoice-ref { margin: .2rem 0 0; color: #6b7280; font-size: .9rem; }
.invoice-h2 { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: #8a909b; margin: 0 0 .35rem; }

.invoice-status {
  display: inline-block; padding: .28rem .7rem; border-radius: 999px;
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  background: #eef0f3; color: #475569;
}
.invoice-status--sent  { background: #e0edff; color: #1d4ed8; }
.invoice-status--paid  { background: #dcfce7; color: #15803d; }
.invoice-status--void  { background: #fee2e2; color: #b91c1c; }
.invoice-status--draft { background: #f1f5f9; color: #64748b; }

.invoice-banner {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin: 1.1rem 0; padding: .8rem 1rem; border-radius: 10px; font-size: .92rem;
}
.invoice-banner a { font-weight: 700; text-decoration: underline; }
.invoice-banner--ok   { background: #ecfdf3; color: #15803d; border: 1px solid #bbf7d0; }
.invoice-banner--void { background: #fef2f2; color: #b91c1c; border: 1px solid #fecaca; }
.invoice-banner--err  { background: #fff7ed; color: #b45309; border: 1px solid #fed7aa; }

.invoice-parties { display: flex; gap: 2.5rem; flex-wrap: wrap; margin: 1.4rem 0; }
.invoice-parties p { margin: 0; line-height: 1.55; font-size: .95rem; }

.invoice-table { width: 100%; border-collapse: collapse; margin: .4rem 0 1rem; }
.invoice-table thead th {
  text-align: left; font-size: .68rem; text-transform: uppercase; letter-spacing: .06em;
  color: #8a909b; border-bottom: 1px solid #ececec; padding: .5rem .4rem;
}
.invoice-table tbody td { padding: .75rem .4rem; border-bottom: 1px solid #f2f2f4; vertical-align: top; }
.invoice-item-name { display: block; font-weight: 600; }
.invoice-item-meta { display: block; font-size: .84rem; color: #6b7280; margin-top: .12rem; }
.invoice-item-sizes { display: block; font-size: .84rem; color: #374151; margin-top: .12rem; }

.invoice-totals { margin-left: auto; max-width: 320px; }
.invoice-total-row { display: flex; justify-content: space-between; gap: 1rem; padding: .32rem 0; font-size: .95rem; }
.invoice-total-row--grand {
  border-top: 2px solid #1f2937; margin-top: .35rem; padding-top: .6rem;
  font-size: 1.15rem; font-weight: 800;
}
.aside-taxid { margin-top: .35rem; text-align: left; font-size: .75rem; color: #b0b4ba; font-weight: 400; }
.invoice-notes { margin-top: 1.6rem; }
.invoice-notes p { margin: 0; line-height: 1.55; font-size: .95rem; }

/* ---- customer pay box ---- */
.invoice-pay { margin-top: 1.8rem; border-top: 1px solid #ececec; padding-top: 1.4rem; }
.invoice-pay-methods { border: 0; padding: 0; margin: 0 0 1rem; display: flex; gap: .6rem; flex-wrap: wrap; }
.invoice-pay-methods legend { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em; color: #8a909b; margin-bottom: .4rem; }
.invoice-pay-method {
  display: inline-flex; align-items: center; gap: .45rem; cursor: pointer;
  border: 1px solid #d7dbe0; border-radius: 10px; padding: .55rem 1rem; font-weight: 600;
}
.invoice-pay-method input { accent-color: var(--secondary); }
.invoice-pay-fine { font-size: .8rem; color: #8a909b; margin: .7rem 0 0; text-align: center; }
.invoice-pay-unavailable { margin-top: 1.5rem; color: #b45309; font-weight: 600; }

/* ---- admin pages (list / builder / manage) ---- */
.admin-page { max-width: 1040px; margin: 0 auto; }
.admin-page-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.2rem; }
.admin-page-head h1 { margin: 0; font-size: 1.6rem; }
.admin-head-actions { display: flex; align-items: center; gap: 1rem; }
.admin-link { font-weight: 600; color: var(--secondary); text-decoration: none; }
.admin-link:hover { text-decoration: underline; }

.admin-table-wrap { overflow-x: auto; }
.admin-table { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid #ececec; border-radius: 12px; overflow: hidden; }
.admin-table thead th { text-align: left; font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: #8a909b; background: #fafafa; padding: .7rem .8rem; }
.admin-table tbody td { padding: .8rem; border-top: 1px solid #f2f2f4; vertical-align: middle; }
.admin-cust-name { display: block; font-weight: 600; }
.admin-cust-email { display: block; font-size: .82rem; color: #6b7280; }

.admin-grid { display: grid; grid-template-columns: 1fr; gap: 1.2rem; align-items: start; }
@media (min-width: 861px) { .admin-grid { grid-template-columns: 1fr 340px; } }
.admin-card { background: #fff; border: 1px solid #ececec; border-radius: 12px; padding: 1.2rem 1.3rem; margin-bottom: 1.2rem; }
.admin-card-hint { font-size: .82rem; margin: 0 0 .6rem; }
.admin-link-field { width: 100%; font-size: .82rem; padding: .55rem .6rem; border: 1px solid #d7dbe0; border-radius: 8px; margin-bottom: .6rem; background: #f9fafb; color: #374151; }
.admin-btn-warn { color: #b45309; border-color: #fed7aa; }
.admin-btn-danger { color: #b91c1c; border-color: #fecaca; }
.admin-side .btn { margin-bottom: .55rem; }

/* ---- builder controls ---- */
.inv-builder { background: #fafafa; border: 1px solid #eee; border-radius: 10px; padding: 1rem 1.1rem; margin-bottom: 1rem; }
.inv-builder-row { display: flex; gap: .75rem; flex-wrap: wrap; align-items: flex-end; margin-bottom: .8rem; }
.inv-field { display: flex; flex-direction: column; gap: .3rem; flex: 1 1 160px; min-width: 0; }
.inv-field--grow { flex: 3 1 240px; }
.inv-field--sm { flex: 0 1 130px; }
.inv-field--full { flex: 1 1 100%; }
.inv-field > span { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: #8a909b; }
.inv-field input, .inv-field select, .inv-field textarea {
  width: 100%; padding: .55rem .6rem; border: 1px solid #d7dbe0; border-radius: 8px;
  font: inherit; font-size: .92rem; background: #fff; box-sizing: border-box;
}
.inv-field input:focus, .inv-field select:focus, .inv-field textarea:focus { outline: none; border-color: var(--secondary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--secondary) 25%, transparent); }
.inv-add-wrap { justify-content: flex-end; align-items: flex-end; }
.inv-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; margin-bottom: 1rem; }
@media (max-width: 600px) { .inv-grid-2 { grid-template-columns: 1fr; } }
.inv-field-row { display: flex; gap: .6rem; }

.inv-sizes { margin: 0 0 .8rem; }
.inv-sizes-label { display: block; font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: #8a909b; margin-bottom: .4rem; }
.inv-sizes-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: .5rem; }
.inv-size-cell { display: flex; flex-direction: column; gap: .2rem; }
.inv-size-cell span { font-size: .8rem; font-weight: 700; text-align: center; }
.inv-size-cell input { width: 100%; padding: .45rem; border: 1px solid #d7dbe0; border-radius: 8px; text-align: center; font: inherit; box-sizing: border-box; }

.inv-msg { color: #b45309; font-size: .88rem; font-weight: 600; margin: .3rem 0 0; }
.inv-lines-table { margin-top: .4rem; }
.inv-line-del { background: none; border: none; color: #b91c1c; font-size: 1.2rem; line-height: 1; cursor: pointer; padding: 0 .3rem; }
.inv-line-del:hover { color: #7f1d1d; }

/* invoice builder: product preview + one-per-row size table */
.inv-builder-top { display: flex; gap: 1.1rem; align-items: flex-start; }
.inv-builder-controls { flex: 1 1 auto; min-width: 0; }
.inv-builder-preview {
  flex: 0 0 132px; width: 132px; height: 156px;
  border: 1px solid #e5e7eb; border-radius: 10px; background: #fff;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.inv-builder-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }
.inv-preview-empty { color: #cbd0d8; font-size: 1.7rem; }
@media (max-width: 560px) {
  .inv-builder-top { flex-direction: column; align-items: stretch; }
  .inv-builder-preview { align-self: center; }
}
.inv-size-table { border-collapse: collapse; margin-top: .1rem; }
.inv-size-table th {
  text-align: left; font-weight: 700; font-size: .9rem;
  padding: .3rem .8rem .3rem 0; white-space: nowrap; color: #374151;
}
.inv-size-table td { padding: .22rem 0; }
.inv-size-table input {
  width: 110px; padding: .42rem .55rem; border: 1px solid #d7dbe0;
  border-radius: 8px; font: inherit; text-align: center; box-sizing: border-box;
}
.inv-size-table input:focus { outline: none; border-color: var(--secondary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--secondary) 25%, transparent); }

/* invoice line-item thumbnail (customer invoice + admin manage) */
.invoice-item { display: flex; gap: .7rem; align-items: flex-start; }
.invoice-item-thumb {
  position: relative; flex: 0 0 56px; width: 56px; align-self: flex-start;
  border: 1px solid #eee; border-radius: 6px; background: #fff; overflow: hidden;
}
.invoice-item-thumb .mockup { width: 100%; }
.invoice-item-body { min-width: 0; }

/* invoice document: never overflow its container; long emails/words wrap */
.invoice-doc { box-sizing: border-box; max-width: 100%; overflow-wrap: break-word; }

/* invoice line-items → stacked, labelled rows on phones (no sideways scroll) */
@media (max-width: 560px) {
  .invoice-doc { padding: 1.1rem 1.15rem; }
  .invoice-parties { gap: 1.2rem; }
  .invoice-totals { max-width: none; }

  .invoice-table thead { display: none; }
  .invoice-table,
  .invoice-table tbody,
  .invoice-table tr,
  .invoice-table td { display: block; width: 100%; }
  .invoice-table tr { border-bottom: 1px solid #ececec; padding: .55rem 0; }
  .invoice-table tbody td { border: 0; padding: .1rem 0; }
  .invoice-table td:first-child { padding-bottom: .35rem; }
  .invoice-table td.ta-r {
    display: flex; align-items: baseline; justify-content: space-between;
    white-space: normal; margin-top: .1rem;
  }
  .invoice-table td.ta-r::before {
    content: attr(data-label);
    color: #8a909b; font-weight: 600; text-transform: uppercase;
    font-size: .68rem; letter-spacing: .05em;
  }
}

/* ---- Admin: info-page editor (Shops_Pages) ---- */
.page-editor .field { display:block; margin:0 0 1rem; }
.page-editor .field-label { display:flex; align-items:center; justify-content:space-between; gap:.5rem; font-weight:700; font-size:.8rem; margin-bottom:.35rem; text-transform:uppercase; letter-spacing:.02em; }
.page-editor input[type=text],
.page-editor textarea { width:100%; box-sizing:border-box; padding:.6rem .7rem; border:1px solid var(--border,#d0d0d7); border-radius:8px; font:inherit; background:#fff; color:inherit; }
.page-editor textarea { font:13px/1.55 Consolas,Menlo,monospace; resize:vertical; min-height:340px; }
.page-editor .field-check { display:flex; align-items:center; gap:.5rem; }
.page-editor .field-check input { width:auto; }
.editor-grid { display:grid; grid-template-columns:1fr 1fr; gap:1.25rem; align-items:start; }
.editor-preview { border:1px dashed var(--border,#d0d0d7); border-radius:8px; padding:1rem 1.1rem; min-height:340px; max-height:70vh; overflow:auto; background:#fff; }
.editor-restore { font-size:.72rem; text-transform:none; letter-spacing:0; font-weight:600; background:none; border:none; cursor:pointer; padding:0; }
.editor-actions { display:flex; align-items:center; gap:1.5rem; margin-top:.75rem; }
.pill-yes, .pill-no { display:inline-block; padding:.15rem .55rem; border-radius:999px; font-size:.72rem; font-weight:700; }
.pill-yes { background:#e6f7ec; color:#137a3a; }
.pill-no  { background:#f3f3f5; color:#8a8a94; }
@media (max-width:760px){ .editor-grid { grid-template-columns:1fr; } }


/* Customizable info pages: match the narrow default-page measure and wrap at
   word boundaries. Non-breaking spaces are normalized server-side, so normal
   text never breaks mid-word; break-word only saves a genuinely long URL. */
.page.static-page .static-content { max-width: 65ch; }
.static-content { overflow-wrap: break-word; }
.static-content img, .static-content table { max-width: 100%; height: auto; }

/* Quill rich-text editor in the page editor (self-hosted under /assets/vendor/quill) */
.page-editor .ql-toolbar { border-top-left-radius:8px; border-top-right-radius:8px; border-color:var(--border,#d0d0d7); }
.page-editor .ql-container { border-bottom-left-radius:8px; border-bottom-right-radius:8px; border-color:var(--border,#d0d0d7); font:inherit; }
.page-editor .ql-editor { min-height:340px; }
.page-editor .editor-tools { display:inline-flex; gap:1rem; }
/* Render Quill alignment / indent classes on the storefront info pages */
.static-content .ql-align-center { text-align:center; }
.static-content .ql-align-right { text-align:right; }
.static-content .ql-align-justify { text-align:justify; }
.static-content .ql-indent-1 { padding-left:3em; }
.static-content .ql-indent-2 { padding-left:6em; }
.static-content .ql-indent-3 { padding-left:9em; }

/* Group "family of brands" logo strip across the very top of the site */
.group-strip { width:100%; background:#0b0b0e; border-bottom:1px solid rgba(255,255,255,.08); }
.group-strip-inner { max-width:1280px; margin:0 auto; display:flex; flex-wrap:wrap; align-items:center;
  justify-content:center; gap:.75rem 2rem; padding:.5rem 1rem; box-sizing:border-box; }
.group-site { display:inline-flex; align-items:center; opacity:.8; transition:opacity .15s ease; text-decoration:none; }
.group-site:hover { opacity:1; }
.group-site img { height:26px; width:auto; max-width:140px; object-fit:contain; display:block; }
.group-site-name { color:#e9e9ee; font-size:.8rem; font-weight:700; letter-spacing:.01em; }
.group-site--current { opacity:1; }
.group-site--current img, .group-site--current .group-site-name {
  outline:2px solid rgba(255,255,255,.28); outline-offset:3px; border-radius:4px; }
@media (max-width:640px){
  .group-strip-inner { flex-wrap:nowrap; overflow-x:auto; justify-content:flex-start; gap:1.5rem;
    -webkit-overflow-scrolling:touch; }
  .group-site img { height:22px; }
  .group-site { flex:0 0 auto; }
}

/* Group strip: on mobile, swap logos for compact favicons when 3+ sites */
.group-favicon { display:none; height:24px; width:24px; max-width:24px; object-fit:contain; border-radius:5px; }
@media (max-width:640px){
  .group-strip--compact .group-strip-inner { flex-wrap:wrap; overflow-x:visible; justify-content:center; gap:1.1rem; }
  .group-strip--compact .group-site--has-favicon .group-logo { display:none; }
  .group-strip--compact .group-site--has-favicon .group-favicon { display:inline-block; }
}

/* Group strip compact: more spacing between marks, centered, slightly larger favicons */
@media (max-width:640px){
  .group-strip--compact .group-strip-inner { gap:1.75rem; justify-content:center; padding:.6rem 1rem; }
  .group-strip--compact .group-favicon { height:28px; width:28px; max-width:28px; }
}

/* Group strip: centre on mobile as well. `safe center` keeps items centred when
   they fit and falls back to start (no clipping) if they ever overflow. */
@media (max-width:640px){
  .group-strip-inner { justify-content:safe center; }
  .group-strip--compact .group-strip-inner { justify-content:safe center; }
}

/* Group strip: in a compact (3+) group on mobile, the <picture> swaps a site's
   logo img to its favicon — size that as a small square icon. Only the
   picture-wrapped imgs (has-favicon sites) are affected; faviconless logos stay. */
@media (max-width:640px){
  .group-strip--compact .group-site picture img { height:28px; width:28px; max-width:28px; object-fit:contain; border-radius:5px; }
}

/* --- Classes moved from inline style="" attributes (CSP hardening: lets us
       drop style-src 'unsafe-inline' once the dynamic mockup styles are moved
       too). Purely presentational — identical to the former inline values. --- */
.u-center      { text-align: center; }
.u-mt-1        { margin-top: 1rem; }
.featured-cta      { text-align: center; margin-top: 1.75rem; }
.featured-cta-btn  { display: inline-block; min-width: min(100%, 360px); }
.admin-debug-bar   { margin: 0; padding: 12px 16px; background: #16161a; color: #7fff7f; border-bottom: 2px solid #7c3aed; font: 12px/1.5 Consolas, Menlo, monospace; }
.admin-debug-title { color: #a855f7; }
.admin-debug-pre   { margin: .5rem 0 0; white-space: pre-wrap; word-break: break-word; color: #cfe; }
.price-debug       { margin: .75rem 0; padding: 10px 12px; background: #16161a; border-radius: 6px; font: 12px/1.55 Consolas, Menlo, monospace; text-align: left; }
.price-debug-pre   { margin: .4rem 0 0; white-space: pre-wrap; color: #7fff7f; }
.dbg-copy { float: right; background: #26262e; color: #e9e9ee; border: 1px solid #3f3f46; border-radius: 5px; padding: .15rem .55rem; font: inherit; font-size: 11px; cursor: pointer; }

/* ---- Mobile product-listing declutter (2026-07-27) ----
   The count sits ABOVE a full-width title (the wrapped side-by-side pair ate
   half the screen), and the filter chip rows become one-line horizontal swipe
   rails — same pattern as the homepage category shelf — instead of tall wraps.
   Desktop keeps the original layout. */
@media (max-width: 700px) {
  .listing-head { flex-direction: column; align-items: flex-start; gap: .15rem; }
  .listing-head .muted { order: -1; align-self: flex-end; font-size: .78rem; letter-spacing: .04em; text-transform: uppercase; }
  .listing-head h1 { width: 100%; font-size: 1.5rem; line-height: 1.2; }

  .quick-cats {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity; scrollbar-width: none;
    margin: 0 -1.5rem .8rem; padding: 0 1.5rem .3rem;   /* rail bleeds to the screen edge */
  }
  .quick-cats::-webkit-scrollbar { display: none; }
  .quick-cat { flex: 0 0 auto; scroll-snap-align: start; }
}

/* ---- Mobile filter sheet (products listing, 2026-07-27) ----
   On mobile the chip rails are replaced by a Filters button (with an active
   count) + removable active-filter pills + a bottom sheet holding the filter
   groups. Desktop (>700px) keeps the chip rails; all of this stays hidden. */
.filters-bar, .active-filters, .filters-sheet { display: none; }

@media (max-width: 700px) {
  .page .listing-rails { display: none; }   /* rails replaced by the sheet */

  .filters-bar { display: block; margin: 0 0 .9rem; }
  .filters-toggle {
    display: flex; align-items: center; gap: .55rem; width: 100%;
    padding: .7rem .95rem; border: 1px solid #d8d8d8; border-radius: 10px;
    background: #fff; color: var(--text); font: inherit; font-weight: 700; cursor: pointer;
  }
  .filters-caret { margin-left: auto; opacity: .65; }
  .filters-count {
    background: var(--primary); color: var(--on-primary);
    border-radius: 999px; min-width: 1.35rem; height: 1.35rem; padding: 0 .3rem;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: .78rem; font-weight: 700;
  }

  .active-filters { display: block; margin: 0 0 1.1rem; }
  .active-filters-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: .5rem; }
  .active-filters-label { font-weight: 700; }
  .active-filters-clear { color: var(--primary); font-weight: 700; font-size: .9rem; text-decoration: underline; }
  .active-filter-pills { display: flex; flex-wrap: wrap; gap: .45rem; }
  .active-pill {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .45rem .85rem; border-radius: 999px;
    background: #eef0f4;
    background: color-mix(in srgb, var(--primary) 14%, #fff);
    color: var(--text); font-size: .85rem; font-weight: 600; text-decoration: none;
  }
  .active-pill span { font-weight: 700; opacity: .7; }

  .filters-sheet.open { display: block; position: fixed; inset: 0; z-index: 2000; }
  .filters-sheet-backdrop { position: absolute; inset: 0; background: rgba(10, 20, 30, .5); }
  .filters-sheet-panel {
    position: absolute; left: 0; right: 0; bottom: 0;
    max-height: 84vh; overflow-y: auto;
    background: #fff; border-radius: 16px 16px 0 0;
    padding: 1rem 1rem 1.4rem; box-shadow: 0 -8px 30px rgba(0, 0, 0, .2);
  }
  .filters-sheet-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .35rem; }
  .filters-sheet-head h2 { margin: 0; font-size: 1.15rem; }
  .filters-sheet-close { background: none; border: 0; font-size: 1.6rem; line-height: 1; cursor: pointer; color: #444; padding: 0 .25rem; }
  .filters-group-title { margin: .9rem 0 .5rem; font-size: .95rem; }
  .filters-group { display: flex; flex-wrap: wrap; gap: .45rem; }
  .fpill {
    display: inline-block; padding: .45rem .95rem; border-radius: 999px;
    border: 1px solid #d8d8d8; background: #fff; color: var(--text);
    font-size: .88rem; font-weight: 600; text-decoration: none; white-space: nowrap;
  }
  .fpill.on { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
  .filters-sheet-reset {
    display: block; text-align: center; margin-top: 1.1rem;
    color: var(--text); opacity: .75; font-weight: 600; text-decoration: underline;
  }
}

/* ---- Empty cart: centre the message + Shop Now button (2026-07-27) ---- */
.cart-empty { text-align: center; padding: 2.5rem 1rem 3rem; }
.cart-empty .muted { margin: 0 0 1.1rem; font-size: 1.05rem; }

/* ---- Mobile: "Bundle & Save" + "Featured Products" headers stack like the
       Shop by Category one — link drops BELOW the title so long titles never
       wrap beside the link. Desktop keeps title-left / link-right. ---- */
@media (max-width: 700px) {
  .featured .section-head, .bundles-strip .section-head { display: block; }
  .featured .section-head a, .bundles-strip .section-head a { display: inline-block; margin-top: .35rem; }
}
