/* Arema FC Official Store — storefront stylesheet
   Version 2.0 · loaded on /store pages only, on top of Bootstrap 4.3.1 and
   store/tokens.css v2.0.

   Scope discipline (docs/design/store/design.md §5.6): this file only covers what
   Bootstrap 4 genuinely lacks — ratio-locked image boxes, the sponsor ticker, the
   product slider, the two-tone heading device, section watermark, sold-out veil —
   plus re-tinting Bootstrap's own components (.carousel, .btn, .pagination, .badge)
   with tokens. Everything else must use Bootstrap utilities.
   Budget: ~300 lines (v1.0 shipped 224; five new v2.0 devices justify the rise —
   see design.md §5.6). Stop and re-check that section before adding more. */

/* ── Base ─────────────────────────────────────────────────────────── */
body.store {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
}
.store a { color: var(--color-link); }
.store a:hover { color: var(--color-link-hover); }
.store :focus-visible,
.store a:focus, .store button:focus, .store input:focus {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}
/* Default blue focus ring is only 1.74:1 on both the nav band and the dark
   footer — fails the 3:1 non-text minimum (design.md §7.2). Both surfaces use
   the yellow on-dark focus token instead. */
.store-header :focus-visible, .store-header a:focus, .store-header button:focus,
.store-on-dark :focus-visible, .store-on-dark a:focus, .store-on-dark button:focus {
  outline-color: var(--color-focus-on-dark);
}

/* ── Two-tone heading (signature device) ─────────────────────────── */
.store-heading {
  font-family: var(--font-clash); /* was --font-display; switched to Clash Grotesk per request */
  font-weight: var(--weight-bold);
  font-size: var(--text-xl);
  line-height: var(--leading-tight);
  text-transform: uppercase;
  text-align: center;
  margin: 0 0 var(--space-6);
}
@media (min-width: 768px) { .store-heading { font-size: var(--text-2xl); } }
/* PRODUK TERLARIS / SHOP BY CATEGORY headings, per Framer export. 32px has no
   matching --text-* token (nearest are 28px/36px), exempted rather than
   rounded. color rgb(26,26,26) matches --color-text (--neutral-900) exactly. */
.store-heading--single {
  font-family: var(--font-clash-display); /* Clash Display, loaded via Fontshare @import in main.css */
  font-size: 32px; /* token-exempt: exact 32px requested; falls between --text-2xl (28px) and --text-3xl (36px) */
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-1);
  color: var(--color-text);
}
/* #AREMA COLLECTION heading, per Framer export: single brand-red colour (not
   the usual two-tone device), Clash Display, heavier + centred — same
   treatment as .store-heading--new-arrival. 56px on desktop only (matches
   --text-4xl exactly); no mobile override requested, so it falls back to the
   base .store-heading mobile size (20px) below 768px. */
.store-heading--italic {
  font-family: var(--font-clash-display); /* Clash Display, loaded via Fontshare @import in main.css */
  font-style: italic;
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-1);
  text-align: center;
}
@media (min-width: 768px) {
  .store-heading--italic { font-size: var(--text-4xl); }
}
.store-heading--italic .store-heading-a {
  color: var(--heading-tone-a); /* blue requested, same brand-blue token used for .dukungan-penuh / NEW ARRIVAL's "NEW" */
}
/* Footer "#DUKUNGAN PENUH" heading, per Framer export. 28px matches --text-2xl
   exactly, applied unconditionally (no separate mobile size requested). Colour
   is left to .store-on-dark .store-heading-a/-b — this modifier only touches
   type, not colour, to keep the on-dark contrast fix intact. */
.store-heading--footer {
  font-family: var(--font-clash-display); /* Clash Display, loaded via Fontshare @import in main.css */
  font-size: var(--text-2xl); /* 28px, matches export exactly */
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-1);
}
.store-heading--italic .store-heading-b {
  color: var(--color-sale-accent); /* rgb(209,4,42) requested; matches --red-550 within a 1-value rounding difference */
}
/* font-family: inherit is required here — main.css's universal reset rule
   (the bare-asterisk selector, main.css:211) sets a fallback font-family
   directly on every element, including these spans, which beats inheriting
   from the parent .store-heading (inheritance only applies when nothing
   matches the element itself). Without this, every two-tone heading's first
   word/phrase silently renders in that fallback font instead of the
   heading's actual font. */
.store-heading-a { font-family: inherit; color: var(--heading-tone-a); } /* token-exempt: `inherit` is a CSS keyword, not a raw font stack — required to defeat main.css's universal reset */
.store-heading-b { font-family: inherit; color: var(--heading-tone-b); } /* token-exempt: `inherit` is a CSS keyword, not a raw font stack — required to defeat main.css's universal reset */
/* NEW ARRIVAL heading, per Framer export: single brand-red colour (not the
   usual two-tone device), heavier + centred. The export's 48px is a
   desktop-oriented value (Framer default breakpoint) with no matching
   --text-* token (nearest are 36px/56px) — scoped to >=768px, same as every
   other heading in this file (.store-heading itself, .dukungan-penuh), so it
   doesn't overflow the narrow mobile NEW ARRIVAL container. Below 768px the
   base .store-heading size (20px) applies instead. */
.store-heading--new-arrival {
  font-family: var(--font-clash-display); /* Clash Display, loaded via Fontshare @import in main.css — distinct from the Clash Grotesk used elsewhere */
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-1);
  text-align: center;
}
@media (min-width: 768px) {
  .store-heading--new-arrival { font-size: 48px; } /* token-exempt: exact 48px requested; falls between --text-3xl (36px) and --text-4xl (56px) */
}
.store-heading--new-arrival .store-heading-a {
  color: var(--heading-tone-a); /* rgb(9,55,129) requested; same brand-blue token used for .dukungan-penuh, no exact-match token exists */
}
.store-heading--new-arrival .store-heading-b {
  color: var(--color-sale-accent); /* rgb(209,4,42) requested; matches --red-550 within a 1-value rounding difference */
}
/* On dark surfaces the light pair is 1.76:1 — blocking failure. Yellow required. */
.store-on-dark .store-heading-a { color: var(--heading-tone-a-on-dark); }
.store-on-dark .store-heading-b { color: var(--heading-tone-b-on-dark); }

.store-product-title { font-family: var(--font-display); font-size: var(--text-xl); font-weight: var(--weight-semibold); margin-bottom: var(--space-3); }

/* Product detail: back link + field labels ("Varian" / "Stok"), per the
   rendered product-page reference — not in components.md's original spec
   (which had a breadcrumb and no Stok field). token-exempt: none, built
   entirely from existing tokens; flagged as unspecified in the
   design-implementer summary. */
.store-back-link {
  display: inline-flex; align-items: center;
  font-size: var(--text-sm); color: var(--color-text);
}
.store-back-link:hover { color: var(--color-link); text-decoration: none; }
.store-field-label {
  font-size: var(--text-base); font-weight: var(--weight-semibold);
  color: var(--color-text); margin-bottom: var(--space-3);
}
/* Product detail: the gallery scrolls with the page while the price/detail
   column stays pinned in view (per request) — only meaningful once the
   columns sit side by side, so it's scoped to --bp-md and up. */
@media (min-width: 768px) {
  .store-detail-sticky { position: sticky; top: var(--space-6); align-self: flex-start; }
}

.store-eyebrow {
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.store-on-dark .store-eyebrow { color: var(--color-text-on-dark-muted); }

.store-section-cta { text-align: center; margin-top: var(--space-8); }
/* Reading-line measure for prose under a centred heading — a ch-based measure,
   not the spacing scale, so it is deliberately not a --space-* token. */
.store-measure { max-width: 50ch; }
/* Collection band body copy, per Framer export. color rgb(18,18,18) has no
   matching token (nearest is --color-text) — exempted rather than
   substituted, since it's a deliberate near-black distinct from --neutral-900. */
.store-collection-desc {
  font-family: var(--font-jakarta);
  font-feature-settings: 'blwf' 1, 'cv09' 1, 'cv03' 1, 'cv04' 1, 'cv11' 1; /* export's font-open-type-features, translated to the standard CSS property */
  font-style: italic;
  letter-spacing: 0.3px; /* token-exempt: exact 0.3px requested; no matching --tracking-* token */
  line-height: 1.5; /* 150%, matches export exactly */
  text-align: center;
  color: rgb(18, 18, 18); /* token-exempt: exact rgb(18,18,18) requested; distinct from --color-text */
}
/* Footer "Pastikan membeli produk original..." body copy, per Framer export.
   18px matches --text-price exactly (reused for its value only — this is not
   a price display, just the nearest token). Colour left to the existing
   --color-text-on-dark-muted inline style; this only adds type properties. */
.store-footer-desc {
  font-family: var(--font-jakarta);
  font-feature-settings: 'blwf' 1, 'cv09' 1, 'cv03' 1, 'cv04' 1, 'cv11' 1; /* export's font-open-type-features, translated to the standard CSS property */
  font-size: var(--text-price); /* 18px, matches export exactly */
  letter-spacing: 0.3px; /* token-exempt: exact 0.3px requested; no matching --tracking-* token */
  line-height: 1.5; /* 150%, matches export exactly */
}
/* "LENGKAPI KOLEKSINYA..." CTA line, per Framer export. rgb(26,26,26) matches
   --color-text (--neutral-900) exactly. */
.store-collection-cta-text {
  font-family: var(--font-clash);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-1);
  text-align: center;
  color: var(--color-text);
  font-size: var(--text-xl); /* 24px, matches export exactly */
}

/* ── Sponsor ticker ───────────────────────────────────────────────── */
.store-ticker {
  background: var(--color-surface);
  border-bottom: var(--border-width) solid var(--color-border);
  height: var(--ticker-height);
  overflow: hidden;
  display: flex;
  align-items: center;
}
.store-ticker-track {
  display: flex; align-items: center; white-space: nowrap;
  animation: store-ticker 30s linear infinite;
}
.store-ticker-track img { height: var(--space-5); width: auto; margin: 0 var(--space-6); opacity: 0.7; }
@keyframes store-ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .store-ticker { overflow-x: auto; }
  .store-ticker-track { animation: none; }
}

/* ── Header ───────────────────────────────────────────────────────── */
.store-header { background: var(--color-surface-brand); color: var(--color-text-on-brand); }
.store-header a { color: var(--color-text-on-brand); }
.store-brand { display: flex; align-items: center; gap: var(--space-3); min-height: var(--header-height); }
.store-brand img { height: 40px; width: auto; } /* token-exempt: no --brand-logo-height token exists yet; proposed in design-implementer summary */
.store-brand-title { font-family: var(--font-display); font-size: var(--text-lg); font-weight: var(--weight-semibold); line-height: 1; }
.store-brand-sub { font-size: var(--text-sm); letter-spacing: var(--tracking-wider); text-transform: uppercase; line-height: 1; }
.store-nav-link {
  display: inline-block; padding: var(--space-3) 0;
  font-size: var(--text-sm); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  border-bottom: var(--nav-underline-width) solid transparent;
}
.store-nav-link:hover, .store-nav-link.active { border-bottom-color: var(--color-text-on-brand); text-decoration: none; }
.store-nav-badge {
  display: inline-block; margin-left: var(--space-1);
  background: var(--color-accent); color: var(--color-on-accent);
  border-radius: var(--radius-full); padding: 0 var(--space-2);
  font-size: var(--text-xs); font-weight: var(--weight-semibold); vertical-align: middle;
}
.store-cart {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--touch-target-min); min-height: var(--touch-target-min);
}
.store-cart-count {
  position: absolute; top: var(--space-1); right: 0;
  background: var(--color-surface); color: var(--color-surface-brand);
  border-radius: var(--radius-full); font-size: var(--text-xs); font-weight: var(--weight-semibold);
  padding: 0 var(--space-2); line-height: 1.6;
}

/* ── Hero carousel (Bootstrap .carousel — ratio box only) ───────────── */
.store-hero .carousel-item { position: relative; padding-top: var(--hero-ratio-mobile); overflow: hidden; }
@media (min-width: 768px) { .store-hero .carousel-item { padding-top: var(--hero-ratio-desktop); } }
/* Mobile: fixed hero height instead of the ratio box (per request). */
@media (max-width: 767.98px) {
  .store-hero .carousel-item { padding-top: 0; height: var(--hero-height-mobile); }
}
.store-hero .carousel-item img {
  position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;
}
.store-hero .carousel-control-prev,
.store-hero .carousel-control-next {
  width: var(--touch-target-min); height: var(--touch-target-min);
  top: 50%; bottom: auto; transform: translateY(-50%);
  background: rgba(11, 13, 23, 0.45); border-radius: var(--radius-full);
  opacity: 1; margin: 0 var(--space-4);
}
.store-hero .carousel-control-prev { left: 0; }
.store-hero .carousel-control-next { right: 0; }

/* ── Product slider ───────────────────────────────────────────────── */
.store-slider {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  gap: var(--space-4); padding-bottom: var(--space-2); -webkit-overflow-scrolling: touch;
}
.store-slider::-webkit-scrollbar { display: none; }
.store-slider-item { flex: 0 0 72%; scroll-snap-align: start; }
@media (min-width: 768px) { .store-slider-item { flex-basis: 32%; } }
@media (min-width: 992px) { .store-slider-item { flex-basis: 24%; } }

/* Full-bleed New Arrival / Shop-by-category slider: track spans the whole
   viewport width, with 40px 24px padding (--space-10 --space-6) keeping cards
   off the screen edge; cards are fixed at 30% of viewport per the request.
   justify-content: center gives equal left/right space when the cards do not
   fill the row; the inter-card gap stays exactly --space-6. Once the row
   overflows, the container scrolls and centring no longer applies. */
.store-slider--full {
  padding: 0 var(--space-6);
  gap: var(--space-6); /* 24px between cards */
  justify-content: center;
}
.store-slider-item--30 { flex-basis: 72%; }
@media (min-width: 768px) { .store-slider-item--30 { flex-basis: 32.4%; } }
/* Shop by Category on mobile: stack the cards as full-width rows instead of a
   horizontal scroll (per request). Only .store-slider--full uses this now. */
@media (max-width: 767.98px) {
  .store-slider--full {
    flex-direction: column;
    overflow-x: visible;
    scroll-snap-type: none;
  }
  .store-slider--full > .store-slider-item { flex-basis: auto; width: 100%; }
}

/* Auto-scrolling New Arrival marquee: same seamless technique as .store-ticker.
   The track is two identical halves; translating it 0 → -50% moves exactly one
   half, so the loop has no visible seam. Pauses on hover/focus. */
.store-marquee { overflow: hidden; }
.store-marquee-track {
  display: flex; width: max-content; gap: var(--space-6);
  animation: store-marquee 40s linear infinite;
}
.store-marquee:hover .store-marquee-track,
.store-marquee:focus-within .store-marquee-track { animation-play-state: paused; }
/* Fixed viewport-relative card width so the track measures predictably for the
   -50% loop: wide on mobile, ~30vw from --bp-md (matching the static slider). */
.store-marquee-item { flex: 0 0 auto; width: 72vw; }
@media (min-width: 768px) { .store-marquee-item { width: 30vw; } }
@keyframes store-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  /* No motion: fall back to a normal horizontal scroll row. */
  .store-marquee { overflow-x: auto; }
  .store-marquee-track { animation: none; }
}

/* Product grid (best sellers): CSS-grid with a 24px gap matching the New
   Arrival slider (--space-6). Column counts mirror the previous Bootstrap
   classes col-6 / col-md-4 / col-lg-3 (2 → 3 → 4 columns). */
.store-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }
/* Produk Terlaris: 2 columns on mobile (2×2 for four items), 4 inline columns
   from --bp-md. Tracks are proportional but capped at --card-max-width (436px),
   and the grid is centred so cards stop growing on wide screens with equal
   left/right space. */
@media (min-width: 768px) {
  .store-grid--4 {
    grid-template-columns: repeat(4, minmax(0, var(--card-max-width)));
    justify-content: center;
  }
}
/* Full-bleed grid: same width as the SHOP BY CATEGORY strip — 24px side padding
   (--space-6), matching .store-slider--full's horizontal inset. */
.store-grid--full { padding-left: var(--space-6); padding-right: var(--space-6); }

/* ── Product card ─────────────────────────────────────────────────── */
.store-card {
  display: block; height: 100%;
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--duration-base) var(--ease-out);
}
.store-card:hover { box-shadow: var(--shadow-md); text-decoration: none; }
.store-card:hover .store-thumb img { transform: scale(1.03); }

.store-thumb { position: relative; padding-top: var(--product-image-ratio); background: var(--color-surface-subtle); overflow: hidden; }
.store-thumb img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; transition: transform var(--duration-base) var(--ease-out); }
.store-thumb-empty { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 25%; opacity: 0.35; }
.store-card-body { padding: var(--space-4); }
.store-card-title {
  font-family: var(--font-clash);
  font-size: var(--text-lg); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-1); color: var(--color-text);
  margin: 0 0 var(--space-2);
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* Bordered-image card style (New Arrival + Produk Terlaris, per request): the
   card has no shadow/border/outline; a 1px border with --radius-card sits on the
   image instead. Reused by --featured and the best-sellers grid. */
.store-card--bordered-image { border: 0; box-shadow: none; }
.store-card--bordered-image:hover { box-shadow: none; }
.store-card--bordered-image .store-thumb {
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-card);
}
/* NEW ARRIVAL only: fixed-height thumb instead of the 1:1 ratio box. */
.store-card--featured .store-thumb { padding-top: 0; height: var(--card-photo-height); }

/* ── Category photo card (with text fallback — store_kategori has no image column) ── */
.store-category-card { display: block; border-radius: var(--radius-md); overflow: hidden; background: var(--color-surface-subtle); border: var(--border-width) solid var(--color-border); transition: box-shadow var(--duration-base) var(--ease-out); }
.store-category-card:hover { box-shadow: var(--shadow-md); border-color: var(--color-border-interactive); text-decoration: none; }
.store-category-thumb { position: relative; padding-top: var(--category-image-ratio); overflow: hidden; }
.store-category-thumb img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; }
.store-category-body { padding: var(--space-4); }
.store-category-title { font-size: var(--text-lg); font-weight: var(--weight-semibold); margin-bottom: var(--space-2); }
.store-category-list { font-size: var(--text-sm); color: var(--color-text-muted); margin: 0; list-style: none; padding: 0; }
/* Dash marker before each category name (list-style is none). */
.store-category-list li::before { content: "\2013"; margin-right: var(--space-2); }

/* Reveal-on-hover variant: photo fills the card and is all that shows at rest.
   The full-height body panel (scrim + title + list) is parked just below the
   card and glides up on hover — the homepage .news-item idiom (index.php),
   rebuilt on store tokens with a transform-based slide for a smoother motion. */
.store-category-card--reveal { position: relative; height: var(--category-card-height); }
.store-category-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.store-category-card--reveal .store-category-body {
  position: absolute; inset: 0; width: 100%;
  display: flex; flex-direction: column; justify-content: flex-end;
  background: var(--color-scrim);
  /* Parked fully below the card at rest → only the photo is visible, no title. */
  transform: translateY(100%);
  transition: transform var(--duration-slow) var(--ease-out);
}
.store-category-card--reveal .store-category-title { color: var(--color-text-on-dark); margin-bottom: 0; }
.store-category-card--reveal .store-category-list { color: var(--color-text-on-dark); margin-top: var(--space-2); }
/* Slide the whole panel up into view on hover / keyboard focus. */
.store-category-card--reveal:hover .store-category-body,
.store-category-card--reveal:focus-visible .store-category-body { transform: translateY(0); }
/* Touch devices have no hover: reveal the panel permanently so it is reachable. */
@media (hover: none) {
  .store-category-card--reveal .store-category-body { transform: translateY(0); }
}

/* ── Price ────────────────────────────────────────────────────────── */
.store-price { font-family: var(--font-clash); font-size: var(--text-price); font-weight: var(--weight-medium); letter-spacing: var(--tracking-1); color: var(--color-text); }
.store-price--sale { color: var(--color-accent); }
.store-price-was { color: var(--color-text-muted); font-size: var(--text-sm); }
/* Sale price stacked: struck-through original on top, sale price below. */
.store-price-group { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); }
/* Mobile: smaller card title + price (per request). Title 20px→16px, price
   18px→14px; the struck-through "was" price steps down to --text-xs to keep it
   secondary to the live price. */
@media (max-width: 767.98px) {
  .store-card-title { font-size: var(--text-base); }
  .store-price { font-size: var(--text-sm); }
  .store-price-was { font-size: var(--text-xs); }
}

/* ── Badge & sold-out veil ────────────────────────────────────────── */
.store-badge {
  position: absolute; top: var(--space-3); left: var(--space-3); z-index: 1;
  border-radius: var(--radius-full); padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.store-badge--new { background: var(--color-surface-brand); color: var(--color-text-on-brand); }
.store-badge--out { background: var(--color-text-muted); color: var(--color-surface); }
/* Discount badge — top-right, frosted glass, italic bold red (replaces the SALE
   label). Layout + style from the Framer export, mapped to tokens.
   padding 8px 12px 12px 16px = --space-2 --space-3 --space-3 --space-4. */
.store-discount {
  position: absolute; top: var(--space-4); right: var(--space-4); z-index: 1;
  display: flex; flex-flow: column; align-items: center;
  place-content: center; gap: var(--space-4);
  width: min-content; height: min-content; overflow: visible;
  background-color: var(--color-glass);
  -webkit-backdrop-filter: blur(var(--blur-glass));
  backdrop-filter: blur(var(--blur-glass));
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-3);
  font-family: var(--font-jakarta);
  font-style: italic; font-weight: var(--weight-bold);
  font-size: var(--text-sm); line-height: 1; text-align: center;
  color: var(--color-sale-accent);
}
.store-veil { position: absolute; inset: 0; z-index: 1; background: var(--color-sold-out-veil); }

/* ── Variant chips ────────────────────────────────────────────────── */
.store-chip {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--touch-target-min); min-height: var(--touch-target-min);
  padding: 0 var(--space-3); margin: 0 var(--space-2) var(--space-2) 0;
  border: var(--border-width) solid var(--color-border-interactive);
  border-radius: var(--radius-sm); font-size: var(--text-sm); font-weight: var(--weight-medium);
  background: var(--color-surface); color: var(--color-text); cursor: pointer;
}
.store-chip:hover { border-color: var(--color-action); }
.store-chip.selected { background: var(--color-action); color: var(--color-on-action); border-color: var(--color-action); }
.store-chip[aria-disabled="true"] {
  color: var(--color-text-disabled); border-color: var(--color-border); cursor: not-allowed;
  background-image: linear-gradient(to top right, transparent 47%, var(--color-border) 47%, var(--color-border) 53%, transparent 53%);
}

/* ── Gallery thumbnails ───────────────────────────────────────────── */
.store-gallery-thumb {
  width: var(--space-16); height: var(--space-16); padding: 0; overflow: hidden; /* 64px, spec'd in components.md */
  border: var(--border-width) solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-surface-subtle);
}
.store-gallery-thumb img { width: 100%; height: 100%; object-fit: cover; }
.store-gallery-thumb.selected { border-width: var(--border-width-thick); border-color: var(--color-action); }
/* Product detail page, per the rendered reference: a 2-up grid of large 1:1
   thumbnails instead of the 64px strip above. unspecified: components.md
   still specs 64px — flagged in the design-implementer summary. */
.store-gallery-thumb--lg {
  width: 100%; height: 0; padding-top: 100%; position: relative;
}
.store-gallery-thumb--lg img { position: absolute; top: 0; left: 0; }

/* ── Bootstrap component re-tinting ───────────────────────────────── */
/* Primary actions are black pills — never blue, never red (design.md Principle 3). */
.store .btn-primary,
.store .btn-action {
  background-color: var(--color-action); border-color: var(--color-action); color: var(--color-on-action);
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-wide); text-transform: uppercase;
  border-radius: var(--radius-full); min-height: var(--touch-target-min); padding-left: var(--space-6); padding-right: var(--space-6);
}
/* "LIHAT SEMUA KOLEKSI" / "KOLEKSI KIPA ILAKES" collection CTAs, per Framer
   export: rounded-rect (not pill), centred flex row, 12px 24px padding. */
.store .btn-action {
  display: inline-flex; flex-flow: row; place-content: center; align-items: center;
  gap: var(--space-3); width: min-content;
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-6);
  white-space: nowrap;
}
.store .btn-primary:hover, .store .btn-action:hover { background-color: var(--color-action-hover); border-color: var(--color-action-hover); color: var(--color-on-action); }
.store .btn-primary:disabled, .store .btn-action:disabled { background-color: var(--color-surface-subtle); border-color: var(--color-border); color: var(--color-text-disabled); }
.store .btn-on-dark { background-color: var(--color-surface); border-color: var(--color-surface); color: var(--color-text); border-radius: var(--radius-full); }
/* "Tambahkan ke Keranjang", per Framer export — deliberately blue, matching
   the cart drawer's Checkout button, not the store's default black pill
   action. DEVIATION from design.md Principle 3 ("every primary action is a
   black pill") — flagged in the design-implementer summary; components.md
   still specs the black-pill treatment for this button. */
.store .store-btn-cart {
  display: flex; flex-flow: row; place-content: center; align-items: center; gap: var(--space-3);
  background-color: rgb(11, 63, 149); /* token-exempt: exact colour requested; close to but distinct from --blue-700 (#133196) */
  border-color: rgb(11, 63, 149); /* token-exempt: see above */
  border-radius: var(--radius-sm);
  height: 48px; /* token-exempt: exact 48px requested; nearest token --touch-target-min is 44px */
  padding: var(--space-3) var(--space-6);
  color: var(--color-on-action);
  font-weight: var(--weight-semibold); letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.store .store-btn-cart:hover { background-color: rgb(9, 51, 122); border-color: rgb(9, 51, 122); color: var(--color-on-action); } /* token-exempt: darker shade of the custom blue above, no token exists for it */
.store .store-btn-cart:disabled { background-color: var(--color-surface-subtle); border-color: var(--color-border); color: var(--color-text-disabled); }
.store .page-item.active .page-link { background-color: var(--color-action); border-color: var(--color-action); }
.store .page-link { color: var(--color-text); }

/* ── Promo band ───────────────────────────────────────────────────── */
.store-promo { padding: var(--space-10) var(--space-6); }
@media (min-width: 768px) {
  .store-promo {
    padding: var(--space-16);
    /* Centred like every .container section instead of stretching full-bleed
       on wide viewports (per request). Wider than the site's usual
       --container-max (1200px) — 1600px per request, so this band alone
       gets a dedicated width rather than reusing the shared token. */
    max-width: 1600px; /* token-exempt: this band intentionally exceeds --container-max (1200px) per request */
    margin-left: auto;
    margin-right: auto;
  }
}

/* Support band: text column left, supporter photo right — row layout at every
   breakpoint (per correction; not stacked on mobile). Text column is capped at
   55% so the heading/paragraph wrap; the image takes the remaining space and
   is nudged 30% further right so it bleeds off the edge. The section clips
   the overflow so that offset never forces a horizontal scrollbar. */
.store-promo--split {
  display: flex; flex-direction: row; align-items: center; gap: var(--space-6);
  padding: var(--space-8); /* 32px on mobile, per correction */
  overflow: hidden;
}
/* Mobile: text column hard-capped at 55% width (not just a flex-basis, so it
   truly can't grow into the image's space); heading + paragraph font sizes
   step down to fit that narrower column (per request). */
.store-promo-text { flex: 0 1 55%; max-width: 55%; }
.store-promo-title { margin-bottom: var(--space-2); }
.store-promo-text p { font-size: var(--text-sm); }
/* Mobile-only step-down from .dukungan-penuh's 56px base — must stay inside
   this query. A previous version of this rule had no media query, so its
   higher specificity (two classes vs. one) beat .dukungan-penuh on ALL
   viewports, leaving desktop stuck at 28px instead of the spec'd 56px. */
@media (max-width: 767.98px) {
  .store-promo-title.dukungan-penuh { font-size: var(--text-2xl); }
}
/* Image: fixed ~270px height on mobile (per request), pinned to the right via
   margin-left: auto, offset 30% further right so it bleeds off the edge. */
.store-promo-image { flex: 0 0 auto; width: auto; max-width: none; height: 337px; margin-left: -35px; margin-top: -52px;} /* token-exempt: no component height token exists for this photo; exact 270px requested */
@media (min-width: 768px) {
  .store-promo--split { padding: 0; gap: var(--space-8); overflow: visible; justify-content: space-between; }
  .store-promo-text { flex: 0 1 70%; max-width: 70%; }
  .store-promo-text p { font-size: var(--text-base); }
  .store-promo-image { flex: 0 0 auto; width: auto; max-width: 380px; height: auto; margin-left: 0; transform: none; } /* token-exempt: no component width token exists for this photo; arbitrary cap chosen for desktop */
}

/* ── Footer ───────────────────────────────────────────────────────── */
.store-footer { background: var(--color-surface-dark); color: var(--color-text-on-dark);}
.store-footer a { color: var(--color-text-on-dark); }
/* Footer content: full width instead of the centred .container, per request. */
.store-footer-inner { width: 100%; padding: var(--space-10) var(--space-10); }
/* Support column flush left, Contact Us column flush right (per request) —
   the ~20% gap left over between .store-footer-support (55%) and
   .store-footer-contact (25%) goes in the middle instead of trailing after
   both columns. */
@media (min-width: 768px) {
  .store-footer-row { justify-content: space-between; }
}
/* Footer support column ("#DUKUNGAN PENUH" + copy), per Framer export: a
   55%-wide flex column replacing Bootstrap's col-md-6 (50%) on desktop only.
   Mobile keeps the existing col-12 stacked behaviour — overridden back to
   100% below 768px so this doesn't fight the .col-12 Bootstrap class already
   on the element. */
.store-footer-support {
  height: min-content;
  overflow: clip; /* export's var(--overflow-clip-fallback,clip) — no such token/fallback exists in this project, `clip` is the export's own literal fallback value */
  display: flex;
  flex-flow: column;
  flex: none;
  place-content: center;
  align-items: flex-start; /* heading + paragraph both left-aligned, flush with each other (per request) — the export's `center` put them centred as a block, fighting the heading's own text-left */
  gap: var(--space-2); /* 8px */
  padding: 0;
  position: relative;
}
/* Contact Us column: sits beside the support column instead of dropping to
   its own row — both are now flex items in the same .row rather than
   Bootstrap col-12/col-md-6 pairs, since .store-footer-support's 55% custom
   width already broke out of the 12-column grid.
   Both columns keep the .col-12 class for its padding/mobile-stack behaviour,
   but .col-12 also sets flex: 0 0 100%; max-width: 100% — which outranks a
   plain `width` in a flex row, so both overrides are required here to
   actually shrink the columns at this breakpoint. */
@media (min-width: 768px) {
  .store-footer-support { flex: 0 0 55%; max-width: 55%; }
  .store-footer-contact { flex: 0 0 25%; max-width: 25%; } /* per Framer export; leaves the remaining ~20% of the row empty, matching the export's own layout */
}
/* Contact Us column layout, per Framer export. */
.store-footer-contact {
  display: flex;
  flex-flow: column;
  flex: none;
  place-content: flex-start;
  align-items: flex-start;
  height: min-content;
  padding: 0;
  position: relative;
  overflow: hidden;
}
/* Instagram button, per Framer export: the SVG data-URI already contains both
   the translucent circle (opacity 0.1 white) and the Instagram glyph, so the
   old CSS border/border-radius circle is dropped — the background image is
   the entire visual now. */
.store-footer-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 35px; height: 36px; /* token-exempt: exact size requested; below --touch-target-min (44px) — flagged as an a11y regression for a touch target, per design.md §7 */
  margin-right: var(--space-2);
  image-rendering: pixelated;
  flex-shrink: 0;
  background-size: 100% 100%;
  background-image: url("data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 xmlns:xlink=%22http://www.w3.org/1999/xlink%22 viewBox=%220 0 34.56 36%22><path d=%22M 0 18.521 C 0 8.977 7.737 1.241 17.28 1.241 C 26.823 1.241 34.56 8.977 34.56 18.521 C 34.56 28.064 26.823 35.801 17.28 35.801 C 7.737 35.801 0 28.064 0 18.521 Z%22 fill=%22rgb(255,255,255)%22 opacity=%220.1%22></path><path d=%22M 17.041 8.72 C 14.538 8.72 14.224 8.731 13.241 8.776 C 12.26 8.821 11.59 8.976 11.004 9.204 C 10.398 9.439 9.884 9.754 9.371 10.267 C 8.859 10.779 8.544 11.293 8.308 11.899 C 8.079 12.485 7.924 13.155 7.879 14.136 C 7.835 15.119 7.824 15.433 7.824 17.936 C 7.824 20.439 7.835 20.752 7.88 21.735 C 7.925 22.716 8.08 23.386 8.308 23.972 C 8.543 24.578 8.858 25.092 9.371 25.605 C 9.883 26.117 10.397 26.433 11.003 26.668 C 11.589 26.896 12.259 27.052 13.24 27.096 C 14.223 27.141 14.537 27.152 17.04 27.152 C 19.543 27.152 19.856 27.141 20.839 27.096 C 21.82 27.052 22.491 26.896 23.077 26.668 C 23.683 26.433 24.196 26.117 24.708 25.605 C 25.221 25.092 25.536 24.578 25.772 23.972 C 25.999 23.386 26.154 22.716 26.2 21.735 C 26.244 20.752 26.256 20.439 26.256 17.936 C 26.256 15.433 26.244 15.119 26.2 14.136 C 26.154 13.155 25.999 12.485 25.772 11.899 C 25.536 11.293 25.221 10.779 24.708 10.267 C 24.196 9.754 23.683 9.439 23.076 9.204 C 22.489 8.976 21.819 8.821 20.838 8.776 C 19.855 8.731 19.542 8.72 17.038 8.72 Z M 16.214 10.381 C 16.459 10.38 16.733 10.381 17.041 10.381 C 19.502 10.381 19.793 10.39 20.765 10.434 C 21.663 10.475 22.151 10.625 22.476 10.751 C 22.906 10.918 23.213 11.118 23.535 11.44 C 23.858 11.763 24.057 12.07 24.225 12.5 C 24.351 12.825 24.501 13.312 24.542 14.211 C 24.586 15.183 24.596 15.474 24.596 17.934 C 24.596 20.393 24.586 20.685 24.542 21.657 C 24.501 22.555 24.351 23.043 24.225 23.368 C 24.058 23.798 23.858 24.104 23.535 24.426 C 23.213 24.749 22.906 24.949 22.476 25.116 C 22.152 25.242 21.663 25.392 20.765 25.433 C 19.793 25.477 19.502 25.487 17.041 25.487 C 14.58 25.487 14.288 25.477 13.317 25.433 C 12.418 25.392 11.93 25.241 11.605 25.115 C 11.175 24.948 10.868 24.749 10.546 24.426 C 10.223 24.104 10.023 23.797 9.856 23.367 C 9.73 23.042 9.579 22.555 9.539 21.656 C 9.494 20.685 9.486 20.393 9.486 17.932 C 9.486 15.471 9.494 15.18 9.539 14.209 C 9.58 13.31 9.73 12.822 9.856 12.498 C 10.023 12.068 10.223 11.76 10.546 11.438 C 10.868 11.115 11.175 10.916 11.605 10.748 C 11.93 10.621 12.418 10.472 13.317 10.43 C 14.167 10.392 14.496 10.38 16.214 10.379 Z M 21.96 11.911 C 21.35 11.911 20.854 12.406 20.854 13.017 C 20.854 13.627 21.35 14.123 21.96 14.123 C 22.571 14.123 23.066 13.627 23.066 13.017 C 23.066 12.406 22.571 11.911 21.96 11.911 Z M 17.041 13.203 C 14.427 13.203 12.308 15.322 12.308 17.936 C 12.308 20.55 14.427 22.668 17.041 22.668 C 19.655 22.668 21.773 20.55 21.773 17.936 C 21.773 15.322 19.655 13.203 17.041 13.203 Z M 17.041 14.864 C 18.737 14.864 20.113 16.239 20.113 17.936 C 20.113 19.633 18.737 21.008 17.041 21.008 C 15.344 21.008 13.969 19.633 13.969 17.936 C 13.969 16.239 15.344 14.864 17.041 14.864 Z%22 fill=%22rgb(255,255,255)%22></path></svg>");
  opacity: 1;
  transition: background var(--duration-fast) var(--ease-out);
}
.store-footer-icon:hover { background-color: rgba(255, 255, 255, 0.08); text-decoration: none; }
.store-copyright { background: var(--color-surface-darker); color: var(--color-text-on-dark-muted); padding: var(--space-3) 0; font-size: var(--text-xs); text-align: center; }

/* ── Store nav overrides (scoped) ──────────────────────────────────────
   The storefront reuses main.css's .main-nav markup, but main.css positions
   .logo / .menu / .search-toggle absolutely, which does not fit the store's
   desired layout: logo left, menu link block centred at 75% width, cart +
   search icons right. These rules are scoped to body.store so the main site
   is untouched, and only apply on desktop (matching main.css's 768px cut,
   where it hides .menu and shows the horizontal nav). */
/* token-exempt: media query — CSS var() cannot be used in a media condition; mirrors --bp-md (768px) */
@media (min-width: 769px) {
  body.store .main-nav .nav-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
  }

  /* Logo: 57px as requested, back into normal flow (not absolute). */
  body.store .main-nav .logo {
    position: static;
    top: auto;
    flex: 0 0 auto;
  }
  body.store .main-nav .logo img { width: 57px; height: auto; align-self: center; } /* token-exempt: exact 57px logo width requested; no matching size token */

  /* "OFFICIAL STORE" lockup next to the logo, with a vertical divider.
     DEVIATION: font is "Clash Grotesk" (already @font-face'd in main.css) per
     the user's spec, overriding the store's --font-body (Schibsted Grotesk).
     Colour stays on tokens. */
  body.store .main-nav .store-logo { align-items: stretch; gap: var(--space-3); }
  body.store .main-nav .store-logo-official {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-self: stretch; /* divider spans the full logo height */
    padding-left: var(--space-3);
    border-left: var(--border-width) solid var(--color-text-on-dark); /* divider: 1px solid white per spec */
    color: var(--color-text-on-dark);
  }
  body.store .main-nav .store-logo-official-a,
  body.store .main-nav .store-logo-official-b {
    font-family: "Clash Grotesk", "Clash Grotesk Placeholder", sans-serif; /* token-exempt: user-mandated font, overrides --font-body */
    font-feature-settings: 'blwf' 1, 'cv09' 1, 'cv03' 1, 'cv04' 1, 'cv11' 1;
    font-size: var(--text-sm); /* 14px */
    letter-spacing: 0.5px; /* token-exempt: exact 0.5px requested; no matching --tracking-* token */
    line-height: 1;
  }
  body.store .main-nav .store-logo-official-a { font-weight: var(--weight-medium); } /* OFFICIAL: 500 per spec */

  /* Menu link block: centred, 75% of the nav width, back into flow. */
  body.store .main-nav .menu {
    position: static;
    left: auto;
    top: auto;
    transform: none;
    flex: 0 1 75%;
    justify-content: center;
    gap: var(--space-8);
  }

  /* Menu link typography.
     DEVIATION: uses "Plus Jakarta Sans", overriding the store's --font-body
     (Schibsted Grotesk). Requested explicitly by the user for the nav links;
     it contradicts tokens.css §Type (design.md v2.0: "adds NO font family").
     Colour and everything else stay on tokens. */
  body.store .main-nav .menu .nav-link {
    font-family: "Plus Jakarta Sans", "Plus Jakarta Sans Placeholder", sans-serif; /* token-exempt: user-mandated nav font, overrides --font-body per request */
    letter-spacing: 0.5px; /* token-exempt: exact 0.5px requested; no matching --tracking-* token (nearest --tracking-wide 0.06em) */
    line-height: 100%;
    color: var(--color-text-on-dark);
    text-transform: uppercase;
  }

  /* Icons: right side, proportional to the 57px logo. */
  body.store .main-nav .store-nav-actions {
    position: static;
    display: flex;
    align-items: center;
    gap: var(--space-5);
    flex: 0 0 auto;
  }
  body.store .main-nav .store-nav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    padding: 0;
    cursor: pointer;
    color: var(--color-text-on-dark);
    line-height: 1;
  }
  body.store .main-nav .store-nav-icon svg { width: var(--text-xl); height: var(--text-xl); }
  body.store .main-nav .store-nav-icon .bi { font-size: var(--text-xl); }

  /* Desktop shows the OFFICIAL STORE lockup, not the mobile name lockup. */
  body.store .main-nav .store-logo-name { display: none; }
}

/* ── Store nav — MOBILE (≤768px) ───────────────────────────────────────
   Single row: ☰  ·  logo + "AREMA FC / EST 1987"  ·  search  ·  cart.
   The desktop "OFFICIAL STORE" lockup is hidden; the icon actions row is
   shown inline (it is only hidden on the desktop-drawer variant). */
@media (max-width: 768px) {
  /* Desktop-only lockup off, mobile name lockup on. */
  body.store .main-nav .store-logo-official { display: none; }
  body.store .main-nav .store-logo-name {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-1); /* jarak antara AREMA FC dan EST 1987 */
    color: var(--color-text-on-dark);
  }
  /* DEVIATION: "Plus Jakarta Sans" per user spec, overrides --font-body (Schibsted Grotesk). */
  body.store .main-nav .store-logo-name-a,
  body.store .main-nav .store-logo-name-b {
    font-family: "Plus Jakarta Sans", "Plus Jakarta Sans Placeholder", sans-serif; /* token-exempt: user-mandated font, overrides --font-body */
    line-height: 1;
    color: var(--color-text-on-dark);
    text-transform: uppercase;
  }
  body.store .main-nav .store-logo-name-a {
    font-size: var(--text-lg); /* 20px */
    font-weight: var(--weight-semibold); /* 600 per spec */
    letter-spacing: 0.5px; /* token-exempt: exact 0.5px requested; no matching --tracking-* token */
  }
  body.store .main-nav .store-logo-name-b {
    font-size: var(--text-sm); /* 14px */
    letter-spacing: 3px; /* token-exempt: exact 3px requested; no matching --tracking-* token */
  }

  /* Show the search + cart icons inline on the nav row, pushed to the right
     (main.css uses flex `order`/margin-left:auto for the mobile nav row). */
  body.store .main-nav .store-nav-actions {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    order: 3;
    margin-left: auto;
  }
  body.store .main-nav .store-nav-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    padding: 0;
    cursor: pointer;
    color: var(--color-text-on-dark);
    line-height: 1;
  }
  body.store .main-nav .store-nav-icon svg { width: var(--text-xl); height: var(--text-xl); }

  /* Search + cart already live on the nav row, so drop the duplicate pair
     inside the drawer to avoid two sets of controls. */
  body.store .mobile-menu .py-3 { display: none !important; }
}

/* ── SALE nav highlight ────────────────────────────────────────────────
   The SALE entry in the store nav (desktop .menu and the mobile drawer)
   renders as a red pill that bobs gently up and down to pull the eye.
   Mirrors main.css's .nav-badge treatment (same red, same 6px radius) but
   is scoped to body.store so the main site header is untouched.
   `!important` on padding is needed because the markup carries Bootstrap's
   .px-0 utility on the nav links. */
body.store .main-nav .menu .nav-link.store-nav-sale,
body.store .mobile-menu .nav-link.store-nav-sale {
  /* Layout: shrink-to-fit pill, contents centred. */
  display: flex;
  position: relative;
  flex-flow: row;
  flex: none;
  place-content: center;
  align-items: center;
  gap: 0;
  width: min-content;
  height: min-content;
  padding: var(--space-2) !important; /* 8px per spec; !important beats Bootstrap .px-0 on the markup */
  overflow: hidden;
  text-decoration: none;
  /* Skin */
  background-color: rgb(209, 5, 42); /* token-exempt: exact brand red requested; matches main.css .nav-badge */
  color: var(--color-text-on-brand);
  border-radius: 6px; /* token-exempt: exact 6px requested; nearest --radius-sm is 8px */
  opacity: 1;
  transform: translateY(-2.048px); /* resting offset per spec (also the reduced-motion fallback) */
  /* --framer-will-change-override is not defined in this project, so this
     resolves to the `transform` fallback; kept as given in the spec. */
  will-change: var(--framer-will-change-override, transform);
  animation: store-sale-bob 1.8s var(--ease-in-out) infinite;
}

body.store .main-nav .menu .nav-link.store-nav-sale:hover,
body.store .mobile-menu .nav-link.store-nav-sale:hover {
  color: var(--color-text-on-brand);
  text-decoration: none;
}

@keyframes store-sale-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-4px); }
}

/* Respect the OS "reduce motion" setting: keep the pill, drop the bobbing. */
@media (prefers-reduced-motion: reduce) {
  body.store .main-nav .menu .nav-link.store-nav-sale,
  body.store .mobile-menu .nav-link.store-nav-sale {
    animation: none;
    transform: translateY(-2.048px);
  }
}

/* ── Store nav texture layer ───────────────────────────────────────────
   main.css paints .main-nav::before as a bg-menu.png stripe at opacity .5,
   multiply-blended over the brand blue. The storefront replaces that layer
   with a tiled texture at 0.075 so the nav reads as near-flat blue with only
   a whisper of grain. Scoped to body.store — the main site keeps its own
   treatment. background-color / background-blend-mode are explicitly reset
   because main.css sets them on the same pseudo-element. */
body.store .main-nav::before {
  content: "";
  position: absolute;
  border-radius: inherit;
  corner-shape: inherit; /* per spec; ignored by browsers without CSS corner-shape */
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  border: 0;
  background-color: transparent;
  background-image: url("../../new-assets/images/store/nav-texture.webp");
  background-repeat: repeat;
  background-position: center;
  background-size: 512px auto; /* token-exempt: exact tile size requested; matches the 512px source 1:1 */
  background-blend-mode: normal;
  opacity: 0.075;
  pointer-events: none; /* keeps the overlay from swallowing nav clicks */
}

/* Collection band background texture — same nav-texture.webp asset and
   object-fit treatment as the nav bar overlay above, at a fainter 0.1 opacity
   (per request) since it sits behind body copy, not the brand-blue nav. */
.store-collection { position: relative; overflow: hidden; }
.store-collection-bg {
  position: absolute; inset: 0; z-index: 0;
  display: block; width: 100%; height: 100%;
  border-radius: inherit;
  object-position: center; object-fit: cover;
  opacity: 0.1;
  pointer-events: none;
}
.store-collection .container { position: relative; z-index: 1; }

/* "...untuk kesejahteraan Arema FC" heading override on the promo band —
   larger + brand-blue variant of .store-heading (per Framer export). */
.dukungan-penuh {
  font-family: var(--font-clash); /* export said "Clash Display", but only Clash Grotesk is @font-face'd in this project */
  font-size: var(--text-4xl); /* 56px, matches the export exactly */
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-1); /* 1px */
  color: var(--heading-tone-a); /* nearest brand blue token; export's rgb(9,55,129) has no matching token */
}

/* ---------------------------------------------------------------------------
   Add-to-cart drawer (produk.php). Not in components.md — built per an
   explicit rendered reference (see produk.php's file header). Slides in from
   the right over a scrim; the confirm button reuses .store-btn-cart so its
   colour stays in sync with the page's main add-to-cart button.
   --------------------------------------------------------------------------- */
.store-drawer {
  position: fixed; inset: 0; z-index: var(--z-modal);
  visibility: hidden;
}
.store-drawer.is-open { visibility: visible; }

.store-drawer-backdrop {
  position: absolute; inset: 0;
  background: var(--color-scrim);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-out);
}
.store-drawer.is-open .store-drawer-backdrop { opacity: 1; }

.store-drawer-panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(400px, 100vw); /* token-exempt: drawer panel width has no matching size token — 400px is a standard sidebar-drawer width, capped at viewport width on mobile */
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--duration-base) var(--ease-out);
}
.store-drawer.is-open .store-drawer-panel { transform: translateX(0); }

@media (prefers-reduced-motion: reduce) {
  .store-drawer-backdrop, .store-drawer-panel { transition: none; }
}

.store-drawer-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-4) var(--space-5);
  border-bottom: var(--border-width) solid var(--color-border);
}
.store-drawer-title { font-size: var(--text-xl); font-weight: var(--weight-semibold); margin: 0; }
.store-drawer-close {
  background: none; border: none; font-size: var(--text-2xl); line-height: 1;
  color: var(--color-text-muted); cursor: pointer;
  min-width: var(--touch-target-min); min-height: var(--touch-target-min);
}
.store-drawer-close:hover { color: var(--color-text); }

.store-drawer-body { flex: 1 1 auto; overflow-y: auto; padding: var(--space-5); }

.store-drawer-product { display: flex; gap: var(--space-4); margin-bottom: var(--space-5); }
.store-drawer-thumb {
  position: relative; flex: 0 0 auto;
  width: 80px; height: 80px; border-radius: var(--radius-md); /* token-exempt: fixed thumbnail size, no matching size token in this store's scale */
  overflow: hidden; background: var(--color-surface-subtle);
}
.store-drawer-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.store-drawer-badge {
  position: absolute; top: var(--space-2); left: var(--space-2);
  background: var(--color-sale-accent); color: var(--color-on-action);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  padding: 2px var(--space-2); border-radius: var(--radius-sm); /* token-exempt: 2px vertical padding is sub-scale, smallest space token (--space-1, 4px) is too tall for this pill's font-size */
}
.store-drawer-nama { font-weight: var(--weight-semibold); margin: 0 0 var(--space-1); }
.store-drawer-varian { color: var(--color-text-muted); font-size: var(--text-sm); margin: 0; }

.store-drawer-field { margin-bottom: var(--space-4); }
.store-drawer-label { display: block; font-weight: var(--weight-semibold); margin-bottom: var(--space-2); }

.store-drawer-stepper { display: inline-flex; align-items: stretch; border: var(--border-width) solid var(--color-border); border-radius: var(--radius-sm); }
.store-drawer-stepper button {
  width: var(--touch-target-min); background: var(--color-surface-subtle); border: none;
  font-size: var(--text-lg); cursor: pointer; color: var(--color-text);
}
.store-drawer-stepper button:disabled { color: var(--color-text-disabled); cursor: not-allowed; }
.store-drawer-stepper input {
  width: 56px; /* token-exempt: fixed qty-input width sized to fit 2-3 digits, no matching size token */
  border: none; border-left: var(--border-width) solid var(--color-border); border-right: var(--border-width) solid var(--color-border);
  text-align: center; font-size: var(--text-base);
  -moz-appearance: textfield;
  appearance: textfield;
}
.store-drawer-stepper input::-webkit-outer-spin-button,
.store-drawer-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.store-drawer-textarea {
  width: 100%; border: var(--border-width) solid var(--color-border); border-radius: var(--radius-sm);
  padding: var(--space-3); font-family: inherit; /* token-exempt: `inherit` is a CSS keyword, not a raw font stack — see .store-heading-a above */
  font-size: var(--text-sm); resize: vertical;
}

.store-drawer-error { color: var(--color-sale-accent); font-size: var(--text-sm); }

.store-drawer-footer { border-top: var(--border-width) solid var(--color-border); }
.store-drawer-price { margin: 0 0 var(--space-1); }
.store-drawer-total { font-weight: var(--weight-semibold); }

.store-drawer-success { padding: var(--space-5); border-top: var(--border-width) solid var(--color-border); }
.store-drawer-success-actions { display: flex; gap: var(--space-3); }
.store-drawer-success-actions > * { flex: 1 1 0; text-align: center; }

.search-result-thumb {
  width: 48px; /* token-exempt: fixed small thumbnail size, no matching size token */
  height: 48px; /* token-exempt: see above */
  object-fit: cover; border-radius: var(--radius-sm);
  margin-right: var(--space-3); flex-shrink: 0;
}

.store-cart-item-thumb {
  width: 56px; /* token-exempt: fixed small thumbnail size, no matching size token */
  height: 56px; /* token-exempt: see above */
  object-fit: cover; border-radius: var(--radius-sm);
  border: var(--border-width) solid var(--color-border); background: var(--color-surface-subtle);
  margin-right: var(--space-3); flex-shrink: 0;
}
.store-cart-item-thumb--empty { object-fit: contain; padding: var(--space-2); opacity: 0.35; }

/* unspecified: checkout order-summary line spacing — design.md §1 scopes
   cart/checkout out of this package; composed from existing tokens/card
   conventions, review needed. */
.store-summary-line:not(:last-child) {
  padding-bottom: var(--space-3); border-bottom: var(--border-width) solid var(--color-border);
}

/* unspecified: JNE destination cascade autocomplete (checkout address) —
   same out-of-scope note as above; composed from existing tokens + Bootstrap
   list-group. */
.store-jne-cascade-field { position: relative; }
.store-jne-cascade-results {
  display: none; position: absolute; z-index: 20; left: var(--space-3); right: var(--space-3);
  max-height: 220px; overflow-y: auto; box-shadow: var(--shadow-md);
  background: var(--color-surface, #fff); border-radius: var(--radius-sm);
}
.store-jne-cascade-results .list-group-item { cursor: pointer; padding: var(--space-2) var(--space-3); }

/* unspecified: ongkir-loading alert spinner — same out-of-scope note as
   above; composed from existing tokens + Bootstrap Icons already used
   elsewhere in this view (produk.php, landing.php). */
.store-alert-loading { display: flex; align-items: center; gap: var(--space-2); }
.store-spin { display: inline-block; animation: store-spin 800ms linear infinite; }
@keyframes store-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .store-spin { animation: none; }
}