/*!
 * AimsCraft — Multi-purpose Ecommerce Frontend
 * File:      assets/css/layout.css
 * Developer: Shahid Malla <https://shahidmalla.com>
 * Company:   AimsCraft — owner of this source code
 * Copyright: © ElySpace. All rights reserved.
 */
/* ==========================================================================
   AimsCraft — layout.css
   Site chrome + page-section scaffolding.
   Mobile-first. Semantic tokens only (tokens.css is the source of truth).
   --------------------------------------------------------------------------
   TABLE OF CONTENTS
   00  Layout primitives (container, main, section, stacking guard)
   01  Announcement bar          .announce
   01b Promise line + locale     .promise .locale
   02  Header                    .site-header
   03  Primary nav               .nav
   04  Mega menu                 .mega
   05  Mobile off-canvas nav     .mobile-nav / .nav-acc
   06  Bottom tab bar            .tabbar
   07  Search overlay            .search-overlay
   08  Footer                    .site-footer
   09  Page head                 .page-head
   10  Hero                      .hero
   11  Section head              .section-head
   12  Shop layout               .shop-layout
   13  Account layout            .account-layout
   14  Auth layout               .auth-layout
   15  Checkout layout           .checkout-layout
   16  Blog layout               .blog-layout
   17  Grids                     .grid--*
   18  Rails                     .rail-section / .rail
   19  Utility layout            .sticky-atc .filter-bar .toolbar .backdrop
                                 .scroll-lock .page-progress .fab
   20  Reduced motion
   21  Print (order / invoice)
   ========================================================================== */


/* ==========================================================================
   00a  STACKING GUARD — why every stacking grid needs minmax(0, 1fr)
   --------------------------------------------------------------------------
   Each layout below declares its multi-column template inside a media query
   and stacks at small sizes. A stacked grid with no template falls back to one
   implicit `auto` track, and an `auto` track is floored at the widest
   min-content in it. One wide descendant — a data table, an uppercase tracked
   label, an unbreakable support address — therefore pushes the track past its
   container and the whole document scrolls sideways on a phone.

   Declaring the single column as minmax(0, 1fr) gives that track a zero
   minimum, so a too-wide child overflows its own scroll wrapper (where it
   belongs) instead of the page. These are :where() so they carry no
   specificity: every rule below, media queries included, still wins.
   ========================================================================== */

:where(.shop-layout,
       .account-layout,
       .auth-layout,
       .checkout-layout,
       .checkout-layout__main,
       .blog-layout,
       .blog-layout__main,
       .section-head,
       .oc-grid,
       .stat,
       .tile,
       .review-item) {
  grid-template-columns: minmax(0, 1fr);
}

/* Steppers flow into implicit *columns*, so they need the same zero minimum on
   the auto-column track instead — otherwise four 174px step labels demand
   720px and the mobile checkout scrolls sideways. */
:where(.progress--steps) {
  grid-auto-columns: minmax(0, 1fr);
}

/* ==========================================================================
   00  LAYOUT PRIMITIVES
   ========================================================================== */

.container {
  width: 100%;
  max-inline-size: var(--container);
  margin-inline: auto;
  padding-inline: var(--sp-5);
}

@media (min-width: 768px) {
  .container { padding-inline: var(--sp-8); }
}

@media (min-width: 1280px) {
  .container { padding-inline: var(--sp-10); }
}

.container--wide   { max-inline-size: var(--container-wide); }
.container--narrow { max-inline-size: var(--container-narrow); }
.container--flush  { max-inline-size: none; padding-inline: 0; }

/* Page landmark. Reserves room for the mobile tab bar + iOS home indicator. */
.site-main {
  display: block;
  min-block-size: 40vh;
}

@media (max-width: 1023.98px) {
  /* The tab bar is fixed over the whole DOCUMENT, so the document is what has
     to reserve room for it. This reservation used to sit on .site-main, and the
     footer comes after <main>: the last 65px of every page — the legal row with
     Privacy, Terms, Cookies, Shipping and Returns — sat permanently underneath
     the bar with no way to scroll it clear. */
  body {
    padding-block-end: calc(var(--tabbar-h) + var(--safe-b));
  }
  /* The sticky add-to-cart bar floats above the tab bar and only overlays the
     main column, so its extra room stays on <main>. */
  .site-main.has-sticky-atc {
    padding-block-end: var(--sp-20);   /* was 76px, off the spacing grid */
  }
}

/* Vertical rhythm for top-level page bands. */
.section {
  padding-block: var(--sp-12);
}

@media (min-width: 768px)  { .section { padding-block: var(--sp-16); } }
@media (min-width: 1280px) { .section { padding-block: var(--sp-20); } }

.section--tight  { padding-block: var(--sp-8); }
.section--loose  { padding-block: var(--sp-20); }
.section--flush  { padding-block: 0; }
.section--soft   { background: var(--bg-soft); }
.section--surface{ background: var(--surface); }

/* Far-down sections opt into cheap skipping. */
.section--defer {
  content-visibility: auto;
  contain-intrinsic-size: auto 720px;
}

.section__divider {
  border: 0;
  block-size: 1px;
  background: var(--line);
  margin-block: var(--sp-12);
}


/* ==========================================================================
   01  ANNOUNCEMENT BAR
   ========================================================================== */

.announce {
  position: relative;
  z-index: calc(var(--z-header) + 1);
  background: var(--ink);
  color: var(--ink-inv);
  font-size: var(--fs-xs);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-wide);
}

.announce--brand {
  background: var(--brand);
  color: var(--brand-ink);
}

.announce--soft {
  background: var(--brand-soft);
  color: var(--ink);
  border-block-end: 1px solid var(--line);
}

.announce.is-dismissed {
  display: none;
}

.announce__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-block-size: 40px;
  padding-block: var(--sp-2);
}

/* Rotating viewport: items are stacked, only .is-active is visible.
   Height is locked by the tallest item so rotation never shifts the page. */
.announce__viewport {
  position: relative;
  flex: 1 1 auto;
  min-inline-size: 0;
  display: grid;
  align-items: center;
  min-block-size: 24px;
}

.announce__track {
  display: grid;
  grid-template-areas: "slide";
  align-items: center;
}

.announce__item {
  grid-area: slide;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  text-align: center;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition:
    opacity var(--dur-3) var(--ease),
    transform var(--dur-3) var(--ease),
    visibility 0s linear var(--dur-3);
}

.announce__item.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.announce__item .icon {
  flex: none;
  opacity: .85;
}

.announce__link {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  white-space: nowrap;
}

.announce__link:hover { text-decoration-thickness: 2px; }

.announce__nav {
  display: none;
  flex: none;
  gap: var(--sp-1);
}

@media (min-width: 768px) {
  .announce__nav { display: inline-flex; }
}

.announce__dot {
  inline-size: 6px;
  block-size: 6px;
  border-radius: var(--r-full);
  border: 0;
  padding: 0;
  background: currentColor;
  opacity: .35;
  cursor: pointer;
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease);
}

.announce__dot.is-active { opacity: 1; transform: scale(1.25); }

.announce__close {
  flex: none;
  display: inline-grid;
  place-items: center;
  inline-size: 28px;
  block-size: 28px;
  margin-inline-end: calc(var(--sp-2) * -1);
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: .7;
  transition: opacity var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease);
}

.announce__close:hover {
  opacity: 1;
  background: color-mix(in oklab, currentColor 16%, transparent);
}


/* ==========================================================================
   01b  PROMISE LINE  .promise  +  LOCALE  .locale

   One quiet sentence above the header. Not a dark utility strip and not
   dismissible: it is a standing shipping promise, so it is set like body copy
   on the page's own paper rather than like a campaign banner.
   ========================================================================== */

.promise {
  background: var(--bg-soft);
  border-block-end: 1px solid var(--line);
  color: var(--ink-2);
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
}
.promise__text {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  margin: 0;
  padding-block: var(--sp-2);
  text-align: center;
}
.promise__dot { color: var(--line-2); }

/* Narrow screens keep the first promise only. Wrapping the second clause
   under the first put the separator dot at the head of a line, which reads
   as a bullet rather than as punctuation. */
@media (max-width: 767.98px) {
  .promise__dot,
  .promise__item--wide { display: none; }
}

/* Locale sits at the far left of the header bar, deliberately small: it is a
   preference, not navigation. */
.locale { display: flex; align-items: center; gap: var(--sp-3); }
.locale__rule { inline-size: 1px; block-size: 14px; background: var(--line-2); }
.locale__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-block-size: 32px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-3);
  font: inherit;
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
  cursor: pointer;
}
.locale__toggle:hover { color: var(--ink); }
.locale__toggle:focus-visible {
  outline: none;
  border-radius: var(--r-xs);
  box-shadow: 0 0 0 3px var(--brand-ring);
}

/* ==========================================================================
   02  HEADER
   --------------------------------------------------------------------------
   Sticky, three-row-capable (announce / main bar / optional sub bar).
   Shrink is layout-shift-free: the block the header occupies in flow stays
   constant because the height lost on shrink is handed back as margin-block-end.
   ========================================================================== */

.site-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-header);
  /* Two rows now — the bar and the category rail — so the height comes from
     the content rather than a fixed token. */
  block-size: auto;
  margin-block-end: 0;
  background: var(--surface);
  border-block-end: 1px solid var(--line);
  transition:
    block-size var(--dur-3) var(--ease),
    margin-block-end var(--dur-3) var(--ease),
    background-color var(--dur-3) var(--ease),
    box-shadow var(--dur-3) var(--ease),
    transform var(--dur-3) var(--ease);
}

/* Three tracks with the OUTER TWO EQUAL, so the wordmark is centred against
   the viewport and not merely placed between two differently-sized groups.
   That symmetry is what makes the header read as a brand mark rather than a
   toolbar, and it is why locale and actions are balanced rather than crammed. */
.site-header__bar {
  display: grid;
  /* minmax(0, 1fr): a plain 1fr floors at min-content, so at 320px the action
     cluster could not shrink and the bag button sat 5.4px off-screen. */
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--sp-4);
  min-block-size: var(--header-h);
}
.site-header__left  { display: flex; align-items: center; gap: var(--sp-3); justify-content: flex-start; min-inline-size: 0; }
.site-header__right { display: flex; align-items: center; justify-content: flex-end; min-inline-size: 0; }

/* --- the category rail ---------------------------------------------------- */
/* At 320px the bar simply runs out of room: 20px of container padding a side
   plus two 16px gaps plus a 114.8px wordmark plus a 44px burger plus a 92px
   action cluster needs 325px. The buttons stay 44px (touch target); the
   padding, the gaps and the wordmark give the width back instead. */
@media (max-width: 379.98px) {
  .site-header > .container,
  .promise > .container { padding-inline: var(--sp-3); }
  .site-header__bar { gap: var(--sp-2); }
  .brand__name { font-size: 1rem; letter-spacing: .08em; }
}

.site-header__rail {
  display: none;
  border-block-start: 1px solid var(--line);
}
@media (min-width: 1024px) { .site-header__rail { display: block; } }

.site-header__rail .nav__list {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--sp-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* --- sticky / shrunk ---------------------------------------------------- */

/* Deliberately no size change on scroll. The old header shrank and paid for it
   with a compensating margin to avoid CLS; a header that simply stays put has
   no such maths to get wrong, and the stillness suits the treatment. */
.site-header.is-sticky {
  background: color-mix(in oklab, var(--surface) 92%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  box-shadow: var(--sh-2);
  border-block-end-color: transparent;
}

@supports not (backdrop-filter: blur(1px)) {
  .site-header.is-sticky { background: var(--surface); }
}

/* --- scroll-down hide / scroll-up show ---------------------------------- */

.site-header.is-hidden {
  /* -100% alone left the floating pill headers (top: 12px + shadow) showing a
     12px sliver along the top edge; the extra clears any offset and shadow */
  transform: translateY(calc(-100% - 48px));
}

.site-header.is-mega-open,
.site-header.is-search-open {
  transform: none;          /* never hide while a panel is attached to it */
}

/* Sub bar (category strip / delivery promise / breadcrumb rail). */
.site-header__sub {
  display: none;
  border-block-start: 1px solid var(--line);
  block-size: 44px;
}

@media (min-width: 1024px) {
  .site-header--three-row { block-size: calc(var(--header-h) + 44px); }
  .site-header--three-row.is-sticky {
    block-size: var(--header-h-sm);
    margin-block-end: calc(var(--header-h) + 44px - var(--header-h-sm));
  }
  .site-header--three-row .site-header__sub { display: block; }
  .site-header--three-row.is-sticky .site-header__sub { display: none; }
  .site-header--three-row .site-header__bar { block-size: var(--header-h); }
  .site-header--three-row.is-sticky .site-header__bar { block-size: 100%; }
}

.site-header__sub-inner {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  block-size: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-inline: contain;
}

.site-header__sub-inner::-webkit-scrollbar { display: none; }

/* --- header slots -------------------------------------------------------- */

.site-header__left,
.site-header__right {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  flex: none;
}

.site-header__right { margin-inline-start: auto; }

.site-header__center {
  display: none;
  flex: 1 1 auto;
  /* Never shrink the nav below its own content: a flex item with min-inline-size:0
     lets .nav__list spill out of this track and collide with the brand tagline and
     the inline search. The search (flex-shrink:1) absorbs the slack instead. */
  min-inline-size: max-content;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
}

@media (min-width: 1024px) {
  .site-header__center { display: flex; }
  .site-header__left,
  .site-header__right { gap: var(--sp-2); }
}

/* --- burger -------------------------------------------------------------- */

.header-burger {
  display: inline-grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  margin-inline-start: calc(var(--sp-3) * -1);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

.header-burger:hover { background: var(--surface-2); }

@media (min-width: 1024px) {
  .header-burger { display: none; }
}

/* --- brand / logo -------------------------------------------------------- */

/* The wordmark is the centre of the header, stacked and centred: name over
   tagline, both tracked. No logo glyph beside it — a mark plus a name plus a
   tagline in a row is the toolbar arrangement this treatment is trying not to
   be, and stacking them is what buys the mark its own space. */
.brand {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 3px;
  /* The mark is the way home from every page, so it is a control, not prose —
     WCAG 2.5.8's in-a-sentence exception does not cover it. On the pages where
     the wordmark alone carries it (no tagline beneath) the link measured
     77x18px. Alignment is centred so the extra height does not shift the
     wordmark off the row's optical centre. */
  min-block-size: 24px;
  color: var(--ink);
  text-decoration: none;
  text-align: center;
  white-space: nowrap;
}

/* The mark as an image, sized by height so a replaced logo of any width
   keeps the header row the same height. */
.brand__logo {
  display: block;
  inline-size: auto;
  block-size: 30px;
  max-inline-size: 180px;
  object-fit: contain;
}
@media (min-width: 768px) { .brand__logo { block-size: 36px; } }

.brand__name {
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 0.95rem + 0.75vw, 1.625rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.brand__tag {
  /* --fs-2xs (12px) is the floor; 9px was below the minimum type size.
     The tracking carries the micro-label feel that the small size used to. */
  font-size: var(--fs-2xs);
  line-height: 1;
  color: var(--ink-3);
  letter-spacing: .22em;
  text-transform: uppercase;
}

@media (max-width: 639.98px) {
  .brand__name { letter-spacing: .1em; }
  .brand__tag { display: none; }
}


/* --- inline search (desktop) --------------------------------------------- */

.header-search {
  display: none;
  position: relative;
  /* Shrinks first, so the nav keeps its full width. Below 1440px there is not
     enough room for brand + tagline + nav + a usable field, so the header falls
     back to the search icon button in .site-header__right.

     min-inline-size is the important half. With min:0 the field collapsed to
     ~144px once the nav and the six action buttons had taken their share —
     after the 40px icon inset and the 48px kbd inset that left 53px of room,
     so the placeholder was always cut off mid-word. 280px is the narrowest
     box the placeholder actually fits in; the nav gives up the difference. */
  flex: 1 1 280px;
  max-inline-size: 520px;
  min-inline-size: 280px;
}

@media (min-width: 1440px) {
  .header-search { display: block; }
}

.header-search__input {
  inline-size: 100%;
  block-size: 42px;
  /* the trailing inset clears the absolutely-positioned kbd hint (12px inset +
     ~28px wide); at sp-4 the placeholder ran underneath it */
  padding-inline: var(--sp-10) var(--sp-12);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface-2);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-sm);
  transition:
    border-color var(--dur-2) var(--ease),
    background-color var(--dur-2) var(--ease),
    box-shadow var(--dur-2) var(--ease);
}

.header-search__input::placeholder { color: var(--ink-3); }

.header-search__input:hover { border-color: var(--line-2); }

.header-search__input:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--brand);
  box-shadow: 0 0 0 4px var(--brand-ring);
}

.header-search__icon {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: var(--sp-4);
  transform: translateY(-50%);
  color: var(--ink-3);
  pointer-events: none;
}

.header-search__kbd {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: var(--sp-3);
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--ink-3);
  padding: 2px var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  background: var(--surface);
  pointer-events: none;
}

/* --- icon actions -------------------------------------------------------- */

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}

.header-action {
  position: relative;
  display: inline-grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

.header-action:hover { background: var(--surface-2); }

.header-action.is-active { color: var(--brand-text); }

.header-action__label {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (min-width: 1480px) {
  .header-action--labelled {
    inline-size: auto;
    gap: var(--sp-2);
    grid-auto-flow: column;
    padding-inline: var(--sp-3);
    border-radius: var(--r-full);
  }
  .header-action--labelled .header-action__label {
    position: static;
    inline-size: auto;
    block-size: auto;
    clip-path: none;
    font-size: var(--fs-sm);
  }
}

/* count bubble */
.header-action__badge {
  position: absolute;
  inset-block-start: 4px;
  inset-inline-end: 4px;
  min-inline-size: 18px;
  block-size: 18px;
  padding-inline: var(--sp-1);   /* was 5px, off the spacing grid */
  display: grid;
  place-items: center;
  border-radius: var(--r-full);
  background: var(--brand);
  color: var(--brand-ink);
  font-size: var(--fs-2xs);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px var(--surface);
  transform: scale(1);
  transition: transform var(--dur-2) var(--ease-out-back);
}

.header-action__badge:empty,
.header-action__badge[hidden],
.header-action__badge[data-count="0"] { display: none; }

.header-action__badge.is-bump { transform: scale(1.28); }

.header-action__badge--alt { background: var(--accent-2); color: var(--ink-inv); }

/* theme toggle */
.theme-toggle {
  position: relative;
  overflow: hidden;
}

.theme-toggle .icon {
  transition: transform var(--dur-3) var(--ease-out-back), opacity var(--dur-2) var(--ease);
}

.theme-toggle__sun,
.theme-toggle__moon {
  grid-area: 1 / 1;
}

.theme-toggle { display: inline-grid; place-items: center; }

:root:not([data-theme="dark"]) .theme-toggle__moon { opacity: 0; transform: rotate(-90deg) scale(.5); }
:root:not([data-theme="dark"]) .theme-toggle__sun  { opacity: 1; transform: none; }
[data-theme="dark"] .theme-toggle__sun  { opacity: 0; transform: rotate(90deg) scale(.5); }
[data-theme="dark"] .theme-toggle__moon { opacity: 1; transform: none; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle__sun  { opacity: 0; transform: rotate(90deg) scale(.5); }
  :root:not([data-theme="light"]) .theme-toggle__moon { opacity: 1; transform: none; }
}


/* ==========================================================================
   03  PRIMARY NAV (desktop)
   ========================================================================== */

.nav {
  display: none;
}

@media (min-width: 1024px) {
  .nav { display: block; }
}

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* static so a full-bleed .mega resolves against .site-header */
.nav__item { position: static; }

/* short dropdowns anchor to the item instead */
.nav__item--anchor { position: relative; }

.nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  /* Small, tracked and quiet. The rail is a list of departments, not a set of
     buttons, so there is no pill, no fill and no weight competing with the
     wordmark above it — only a hairline that draws itself on hover. */
  min-block-size: 44px;
  padding-inline: var(--sp-4);
  border: 0;
  background: transparent;
  color: var(--ink-2);
  font-size: var(--fs-2xs);
  font-weight: 500;
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-2) var(--ease);
}
.nav__link::after {
  content: "";
  position: absolute;
  inset-block-end: 12px;
  inset-inline: var(--sp-4);
  block-size: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--dur-2) var(--ease);
}
.nav__link:hover,
.nav__link[aria-expanded="true"],
.nav__link[aria-current="page"] { color: var(--ink); }
.nav__link:hover::after,
.nav__link[aria-expanded="true"]::after,
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

.nav__link:hover,
.nav__item:focus-within > .nav__link,
.nav__item.is-open > .nav__link { color: var(--ink); background: var(--surface-2); }

.nav__link[aria-current="page"],
.nav__link.is-active { color: var(--brand-text); }

.nav__link--sale { color: var(--danger); }

/* The six uppercase nav labels only fit beside the brand and the full action
   row from about 1320px. Between 1024 (where the desktop nav appears) and
   there, the bar measured 1152-1226px of children inside a 965-1189px box and
   pushed the whole document sideways. In that band the nav drops its glyphs
   and tightens, and the two secondary actions step out — the labels and every
   primary action stay. */
@media (max-width: 1319.98px) {
  .nav__icon { display: none; }
  .nav__link { padding-inline: var(--sp-2); gap: var(--sp-1); }
  .header-action--extra { display: none; }
}

/* The small outline glyph that leads every nav label. */
.nav__icon {
  flex: none;
  inline-size: 15px;
  block-size: 15px;
  color: var(--ink-3);
  transition: color var(--dur-2) var(--ease);
}
.nav__link:hover .nav__icon,
.nav__link[aria-current="page"] .nav__icon { color: var(--brand-text); }

.nav__chev {
  transition: transform var(--dur-2) var(--ease);
  opacity: .7;
}

.nav__item.is-open > .nav__link .nav__chev,
.nav__item:hover > .nav__link .nav__chev { transform: rotate(180deg); }

.nav__badge {
  margin-inline-start: var(--sp-1);
  padding: 2px var(--sp-2);
  border-radius: var(--r-full);
  background: var(--brand-soft);
  color: var(--brand-text);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}


/* ==========================================================================
   04  MEGA MENU
   --------------------------------------------------------------------------
   Lives INSIDE .site-header so it re-anchors for free when the header shrinks.
   Opens on hover, on focus-within and on .is-open (click / keyboard).
   The panel's own top padding doubles as the invisible pointer bridge.
   ========================================================================== */

.mega {
  position: absolute;
  inset-block-start: 100%;
  inset-inline: 0;
  z-index: var(--z-sticky);
  padding-block-start: var(--sp-2);   /* hover bridge */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-8px);
  clip-path: inset(0 0 100% 0 round 0 0 var(--r-xl) var(--r-xl));
  transition:
    opacity var(--dur-2) var(--ease),
    transform var(--dur-3) var(--ease),
    clip-path var(--dur-3) var(--ease),
    visibility 0s linear var(--dur-3);
}

/* explicit bridge for authors who need a wider travel corridor */
.mega__bridge {
  position: absolute;
  inset-block-end: 100%;
  inset-inline: 0;
  block-size: var(--sp-4);
  content: "";
}

.mega__inner {
  background: var(--surface);
  border: 1px solid var(--line);
  border-block-start: 0;
  border-end-start-radius: var(--r-xl);
  border-end-end-radius: var(--r-xl);
  box-shadow: var(--sh-4);
  overflow: hidden;
}

/* open states */
.nav__item:hover > .mega,
.nav__item:focus-within > .mega,
.nav__item.is-open > .mega,
.mega.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: none;
  clip-path: inset(0 0 0 0 round 0 0 var(--r-xl) var(--r-xl));
  transition-delay: 0s;
}

/* Pointer-only opening: keyboard users get it via focus-within / .is-open. */
@media (hover: none) {
  .nav__item:hover > .mega { opacity: 0; visibility: hidden; pointer-events: none; }
  .nav__item.is-open > .mega { opacity: 1; visibility: visible; pointer-events: auto; }
}

/* --- grid ---------------------------------------------------------------- */

/* minmax(0, 1fr) on the link columns let them collapse to whatever was left
   over: at 1024px the four middle columns measured 56.75px each and every
   two-word label wrapped onto three lines. A link column has a real minimum —
   it has to hold "Honey & Preserves" — so state it, and below 1280px move the
   promo card onto its own row rather than steal width from the links. */
.mega__grid {
  display: grid;
  gap: var(--sp-8);
  padding: var(--sp-8);
  grid-template-columns: minmax(180px, 220px) repeat(3, minmax(150px, 1fr)) minmax(240px, 300px);
  align-items: start;
}

.mega--wide .mega__grid {
  grid-template-columns: minmax(200px, 240px) repeat(4, minmax(150px, 1fr)) minmax(260px, 320px);
}

@media (max-width: 1279.98px) {
  .mega__grid,
  .mega--wide .mega__grid {
    grid-template-columns: minmax(170px, 200px) repeat(3, minmax(150px, 1fr));
  }
  /* the promo is the last child and drops full width underneath */
  .mega__grid > .mega__promo { grid-column: 1 / -1; }
  .mega--wide .mega__grid > .mega__col:nth-of-type(4) { grid-column: 2 / -1; }
}

.mega--split .mega__grid {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-10);
}

.mega--simple {
  inset-inline: auto;
  inline-size: max-content;
  min-inline-size: 240px;
}

.mega--simple .mega__inner {
  border-radius: var(--r-lg);
  border-block-start: 1px solid var(--line);
}

.mega--simple .mega__grid {
  grid-template-columns: minmax(0, 1fr);
  padding: var(--sp-3);
  gap: var(--sp-1);
}

/* left category column */
.mega__cats {
  display: grid;
  gap: 2px;
  padding-inline-end: var(--sp-6);
  border-inline-end: 1px solid var(--line);
  align-self: stretch;
}

.mega--simple .mega__cats,
.mega--split .mega__cats {
  border-inline-end: 0;
  padding-inline-end: 0;
}

.mega__cat {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

.mega__cat .icon { flex: none; color: var(--ink-3); transition: color var(--dur-2) var(--ease); }

.mega__cat:hover,
.mega__cat.is-active {
  background: var(--brand-soft);
  color: var(--brand-text);
}

.mega__cat:hover .icon,
.mega__cat.is-active .icon { color: var(--brand-text); }

.mega__cat-arrow { margin-inline-start: auto; opacity: 0; transform: translateX(-4px); transition: opacity var(--dur-2) var(--ease), transform var(--dur-2) var(--ease); }

.mega__cat:hover .mega__cat-arrow { opacity: 1; transform: none; }

/* subcategory columns */
.mega__col {
  min-inline-size: 0;
}

.mega__heading {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.mega__list {
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mega__link {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2);
  margin-inline: calc(var(--sp-2) * -1);
  border-radius: var(--r-xs);
  color: var(--ink-2);
  font-size: var(--fs-sm);
  text-decoration: none;
  transition: color var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease);
}

.mega__link:hover { color: var(--brand-text); background: var(--surface-2); }

.mega__link .icon { color: var(--ink-3); flex: none; }

.mega__tag {
  padding: 1px var(--sp-2);
  border-radius: var(--r-full);
  background: var(--danger-soft);
  color: var(--danger);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

.mega__tag--new { background: var(--success-soft); color: var(--success); }
.mega__tag--hot { background: var(--warning-soft); color: var(--warning-ink); }

/* promo card */
.mega__promo {
  display: block;
  position: relative;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--surface-2);
  color: var(--ink);
  text-decoration: none;
  isolation: isolate;
}

.mega__promo-media {
  display: block;
  inline-size: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform var(--dur-4) var(--ease);
}

.mega__promo:hover .mega__promo-media { transform: scale(1.05); }

.mega__promo-body {
  padding: var(--sp-4);
  display: grid;
  gap: var(--sp-2);
}

/* The scrim IS the contrast here: the text block is four lines tall and the
   artwork behind it is light at the top, so a single 46% wash left the eyebrow
   at about 1.2:1. Step the alpha instead, and hold it high for the full height
   of the copy. */
.mega__promo--overlay .mega__promo-body {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  padding-block-start: var(--sp-10);
  background: linear-gradient(to top,
    rgb(var(--scrim-rgb) / .94) 0%,
    rgb(var(--scrim-rgb) / .88) 60%,
    rgb(var(--scrim-rgb) / .58) 84%,
    rgb(var(--scrim-rgb) / 0) 100%);
  color: var(--on-scrim);
}

.mega__promo-eyebrow {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--brand-text);
}

.mega__promo--overlay .mega__promo-eyebrow { color: inherit; opacity: 1; }

.mega__promo-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
}

.mega__promo-text {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

.mega__promo--overlay .mega__promo-title,
.mega__promo--overlay .mega__promo-cta { color: var(--on-scrim); }
.mega__promo--overlay .mega__promo-text { color: inherit; opacity: .88; }

.mega__promo-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--brand-text);
}

.mega__promo--overlay .mega__promo-cta { color: inherit; }

.mega__promo:hover .mega__promo-cta .icon { transform: translateX(3px); }
.mega__promo-cta .icon { transition: transform var(--dur-2) var(--ease); }

/* footer strips */
.mega__foot {
  display: grid;
  gap: var(--sp-4);
  padding: var(--sp-5) var(--sp-8);
  border-block-start: 1px solid var(--line);
  background: var(--bg-soft);
}

@media (min-width: 1280px) {
  .mega__foot {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--sp-8);
  }
}

.mega__brands {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  flex-wrap: wrap;
}

.mega__brands-label,
.mega__trending-label {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-3);
  flex: none;
}

.mega__brand {
  display: inline-flex;
  align-items: center;
  block-size: 28px;
  opacity: .6;
  filter: grayscale(1);
  transition: opacity var(--dur-2) var(--ease), filter var(--dur-2) var(--ease);
}

.mega__brand:hover { opacity: 1; filter: none; }

.mega__brand img { block-size: 100%; inline-size: auto; display: block; }

.mega__trending {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

.mega__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--ink-2);
  font-size: var(--fs-xs);
  text-decoration: none;
  white-space: nowrap;
  transition: border-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease);
}

.mega__chip:hover {
  border-color: var(--brand);
  color: var(--brand-text);
  background: var(--brand-soft);
}

/* backdrop dim behind an open mega */
.mega-backdrop {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-header) - 1);
  background: var(--overlay);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-3) var(--ease), visibility 0s linear var(--dur-3);
}

.mega-backdrop.is-open,
body.has-mega .mega-backdrop {
  opacity: .5;
  visibility: visible;
  transition-delay: 0s;
}


/* ==========================================================================
   05  MOBILE OFF-CANVAS NAV
   ========================================================================== */

.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  visibility: hidden;
  pointer-events: none;
}

.mobile-nav.is-open {
  visibility: visible;
  pointer-events: auto;
}

.mobile-nav__scrim {
  position: absolute;
  inset: 0;
  background: var(--overlay);
  opacity: 0;
  transition: opacity var(--dur-3) var(--ease);
}

.mobile-nav.is-open .mobile-nav__scrim { opacity: .6; }

.mobile-nav__panel {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: min(92vw, 400px);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  box-shadow: var(--sh-4);
  transform: translateX(-100%);
  transition: transform var(--dur-4) var(--ease);
  will-change: transform;
}

.mobile-nav.is-open .mobile-nav__panel { transform: none; }

.mobile-nav--end .mobile-nav__panel {
  inset-inline-start: auto;
  inset-inline-end: 0;
  transform: translateX(100%);
}

.mobile-nav__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex: none;
  padding: var(--sp-4) var(--sp-5);
  padding-block-start: calc(var(--sp-4) + var(--safe-t, 0px));
  border-block-end: 1px solid var(--line);
}

.mobile-nav__close {
  margin-inline-start: auto;
  inline-size: 44px;
  block-size: 44px;
  display: inline-grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-full);
  background: var(--surface-2);
  color: var(--ink);
  cursor: pointer;
}

.mobile-nav__close:hover { background: var(--surface-3); }

.mobile-nav__search {
  flex: none;
  padding: var(--sp-4) var(--sp-5);
  border-block-end: 1px solid var(--line);
}

.mobile-nav__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding-block: var(--sp-2) var(--sp-6);
}

.mobile-nav__section {
  padding: var(--sp-4) var(--sp-5);
  border-block-end: 1px solid var(--line);
}

.mobile-nav__section:last-child { border-block-end: 0; }

.mobile-nav__section-title {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.mobile-nav__foot {
  flex: none;
  padding: var(--sp-4) var(--sp-5);
  padding-block-end: calc(var(--sp-4) + var(--safe-b));
  border-block-start: 1px solid var(--line);
  background: var(--bg-soft);
}

/* --- accordion tree (2 levels) ------------------------------------------- */

.nav-acc {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-acc__item {
  border-block-end: 1px solid var(--line);
}

.nav-acc__item:last-child { border-block-end: 0; }

.nav-acc__btn,
.nav-acc__top {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  inline-size: 100%;
  min-block-size: 52px;
  padding: var(--sp-3) var(--sp-5);
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-base);
  font-weight: 600;
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

.nav-acc__btn:hover,
.nav-acc__top:hover { background: var(--surface-2); }

.nav-acc__btn .icon:first-child,
.nav-acc__top .icon:first-child { color: var(--ink-3); flex: none; }

.nav-acc__chev {
  margin-inline-start: auto;
  flex: none;
  color: var(--ink-3);
  transition: transform var(--dur-3) var(--ease);
}

.nav-acc__btn[aria-expanded="true"] { color: var(--brand-text); }
.nav-acc__btn[aria-expanded="true"] .nav-acc__chev { transform: rotate(180deg); color: var(--brand-text); }
.nav-acc__btn[aria-expanded="true"] .icon:first-child { color: var(--brand-text); }

/* height animation without measuring: 0fr -> 1fr */
.nav-acc__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-3) var(--ease);
}

.nav-acc__panel.is-open,
.nav-acc__btn[aria-expanded="true"] + .nav-acc__panel { grid-template-rows: 1fr; }

.nav-acc__inner {
  overflow: hidden;
  min-block-size: 0;
}

.nav-acc__list {
  display: grid;
  margin: 0;
  padding: 0 0 var(--sp-3);
  list-style: none;
  background: var(--bg-soft);
}

.nav-acc__link {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-block-size: 44px;
  padding: var(--sp-2) var(--sp-5) var(--sp-2) var(--sp-12);
  color: var(--ink-2);
  font-size: var(--fs-sm);
  text-decoration: none;
}

.nav-acc__link:hover { color: var(--brand-text); background: var(--surface-2); }

.nav-acc__link[aria-current="page"] { color: var(--brand-text); font-weight: 600; }

.nav-acc__all {
  font-weight: 600;
  color: var(--brand-text);
}

/* level 2 nested group */
.nav-acc__sub {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-acc__sub .nav-acc__link {
  padding-inline-start: var(--sp-16);
  font-size: var(--fs-xs);
  color: var(--ink-3);
}

.nav-acc__sub-title {
  padding: var(--sp-3) var(--sp-5) var(--sp-1) var(--sp-12);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* --- quick tiles --------------------------------------------------------- */

.quick-tiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-2);
}

.quick-tile {
  display: grid;
  justify-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-1);
  min-block-size: 76px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink-2);
  text-decoration: none;
  text-align: center;
  transition: border-color var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

.quick-tile:hover,
.quick-tile:active {
  border-color: var(--brand);
  background: var(--brand-soft);
  color: var(--brand-text);
}

.quick-tile__icon { color: var(--brand-text); }

.quick-tile__label {
  font-size: var(--fs-2xs);
  font-weight: 600;
  line-height: var(--lh-tight);
}

/* --- account CTA block --------------------------------------------------- */

.mobile-nav__account {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-5);
  margin: var(--sp-4) var(--sp-5);
  border-radius: var(--r-lg);
  background: var(--brand-soft);
  color: var(--ink);
}

.mobile-nav__account-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
}

.mobile-nav__account-text {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--ink-2);
}

.mobile-nav__account-actions {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

/* --- prefs (currency / language) ----------------------------------------- */

.mobile-nav__prefs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-3);
}

.mobile-nav__pref {
  display: grid;
  gap: var(--sp-1);
}

.mobile-nav__pref-label {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* --- social row ---------------------------------------------------------- */

.social-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

.social-row__link {
  display: inline-grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  color: var(--ink-2);
  text-decoration: none;
  transition: border-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease), transform var(--dur-2) var(--ease-out-back);
}

.social-row__link:hover {
  border-color: var(--brand);
  color: var(--brand-text);
  background: var(--brand-soft);
  transform: translateY(-2px);
}


/* ==========================================================================
   06  BOTTOM TAB BAR (mobile only)
   ========================================================================== */

.tabbar {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: var(--z-sticky);
  background: color-mix(in oklab, var(--surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-block-start: 1px solid var(--line);
  padding-block-end: var(--safe-b);
  transform: translateY(0);
  transition: transform var(--dur-3) var(--ease), opacity var(--dur-2) var(--ease);
}

@supports not (backdrop-filter: blur(1px)) {
  .tabbar { background: var(--surface); }
}

@media (min-width: 1024px) {
  .tabbar { display: none; }
}

.tabbar__inner {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  align-items: stretch;
  block-size: var(--tabbar-h);
  max-inline-size: var(--container-narrow);
  margin-inline: auto;
}

.tabbar__item {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 3px;
  min-inline-size: 0;
  padding: var(--sp-1);
  border: 0;
  background: transparent;
  color: var(--ink-3);
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-2) var(--ease);
}

.tabbar__item.is-active { color: var(--brand-text); }

.tabbar__icon-wrap {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: 26px;
  block-size: 26px;
}

/* line icon by default, -fill variant when active */
.tabbar__icon      { grid-area: 1 / 1; transition: transform var(--dur-2) var(--ease-out-back), opacity var(--dur-1) var(--ease); }
.tabbar__icon--fill { opacity: 0; transform: scale(.8); }
.tabbar__item.is-active .tabbar__icon--line { opacity: 0; transform: scale(.8); }
.tabbar__item.is-active .tabbar__icon--fill { opacity: 1; transform: scale(1); }

.tabbar__label {
  max-inline-size: 100%;
  overflow: hidden;
  font-size: var(--fs-2xs);
  font-weight: 600;
  line-height: 1;
  letter-spacing: var(--ls-tight);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tabbar__badge {
  position: absolute;
  inset-block-start: -4px;
  inset-inline-start: 60%;
  min-inline-size: 16px;
  block-size: 16px;
  padding-inline: 4px;
  display: grid;
  place-items: center;
  border-radius: var(--r-full);
  background: var(--brand);
  color: var(--brand-ink);
  font-size: var(--fs-2xs);   /* was 10px — below the 12px floor */
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px var(--surface);
}

.tabbar__badge:empty,
.tabbar__badge[hidden],
.tabbar__badge[data-count="0"] { display: none; }

.tabbar__badge--dot {
  min-inline-size: 8px;
  inline-size: 8px;
  block-size: 8px;
  padding: 0;
}

/* small active indicator */
.tabbar__indicator {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 50%;
  translate: -50% 0;
  inline-size: 20px;
  block-size: 3px;
  border-radius: 0 0 var(--r-full) var(--r-full);
  background: var(--brand);
  opacity: 0;
  scale: 0 1;
  transition: opacity var(--dur-2) var(--ease), scale var(--dur-3) var(--ease-out-back);
}

.tabbar__item.is-active .tabbar__indicator { opacity: 1; scale: 1 1; }

/* centre prominent slot */
.tabbar__item--prominent {
  gap: 0;
}

.tabbar__prominent {
  display: grid;
  place-items: center;
  inline-size: 52px;
  block-size: 52px;
  margin-block-start: -22px;
  border-radius: var(--r-full);
  background: var(--brand);
  color: var(--brand-ink);
  box-shadow: var(--sh-brand);
  transition: transform var(--dur-2) var(--ease-out-back);
}

.tabbar__item--prominent:active .tabbar__prominent { transform: scale(.94); }

.tabbar__item--prominent .tabbar__label { margin-block-start: 2px; }

/* hide while a drawer / sheet / modal owns the screen */
/* app.js puts both of these on document.documentElement, never on <body>
   ("html.classList.add('has-overlay')"), so the body-scoped selectors matched
   nothing and the mobile tab bar stayed put underneath every open drawer. */
html.scroll-lock .tabbar,
html.has-overlay .tabbar,
body.scroll-lock .tabbar,
body.has-overlay .tabbar,
.tabbar.is-hidden {
  transform: translateY(100%);
  opacity: 0;
  pointer-events: none;
}


/* ==========================================================================
   07  SEARCH OVERLAY
   ========================================================================== */

.search-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  visibility: hidden;
  pointer-events: none;
}

.search-overlay.is-open {
  visibility: visible;
  pointer-events: auto;
}

.search-overlay__scrim {
  position: absolute;
  inset: 0;
  background: var(--overlay);
  opacity: 0;
  transition: opacity var(--dur-3) var(--ease);
}

.search-overlay.is-open .search-overlay__scrim { opacity: .6; }

.search-overlay__panel {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 100%;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  transform: translateY(-2%);
  opacity: 0;
  transition: transform var(--dur-3) var(--ease), opacity var(--dur-2) var(--ease);
}

.search-overlay.is-open .search-overlay__panel { transform: none; opacity: 1; }

@media (min-width: 768px) {
  .search-overlay__panel {
    inset-block-start: var(--sp-10);
    inset-inline: 50%;
    translate: -50% 0;
    inline-size: min(760px, calc(100vw - var(--sp-10)));
    block-size: auto;
    max-block-size: min(76vh, 720px);
    max-block-size: min(76dvh, 720px);
    border-radius: var(--r-xl);
    border: 1px solid var(--line);
    box-shadow: var(--sh-4);
    overflow: hidden;
  }
}

.search-overlay__head {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5);
  padding-block-start: calc(var(--sp-4) + var(--safe-t, 0px));
  border-block-end: 1px solid var(--line);
}

@media (min-width: 768px) {
  .search-overlay__head { padding: var(--sp-4); padding-block-start: var(--sp-4); }
}

.search-overlay__field {
  position: relative;
  flex: 1 1 auto;
  min-inline-size: 0;
  display: flex;
  align-items: center;
}

.search-overlay__field .icon {
  position: absolute;
  inset-inline-start: var(--sp-4);
  color: var(--ink-3);
  pointer-events: none;
}

.search-overlay__input {
  inline-size: 100%;
  block-size: 52px;
  padding-inline: var(--sp-12) var(--sp-12);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface-2);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-lg);
}

.search-overlay__input::placeholder { color: var(--ink-3); }

.search-overlay__input:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--brand);
  box-shadow: 0 0 0 4px var(--brand-ring);
}

.search-overlay__clear {
  position: absolute;
  inset-inline-end: var(--sp-2);
  inline-size: 36px;
  block-size: 36px;
  display: inline-grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-full);
  background: var(--surface-3);
  color: var(--ink-2);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-2) var(--ease);
}

.search-overlay.has-query .search-overlay__clear { opacity: 1; pointer-events: auto; }

.search-overlay__close {
  flex: none;
  inline-size: 44px;
  block-size: 44px;
  display: inline-grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}

.search-overlay__close:hover { background: var(--surface-2); }

@media (min-width: 768px) {
  .search-overlay__close {
    inline-size: auto;
    padding-inline: var(--sp-3);
    font-size: var(--fs-sm);
    font-weight: 600;
    border-radius: var(--r-sm);
  }
}

.search-overlay__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: var(--sp-5);
  padding-block-end: calc(var(--sp-8) + var(--safe-b));
  display: grid;
  gap: var(--sp-6);
  align-content: start;
}

.search-overlay__section { display: grid; gap: var(--sp-3); }

.search-overlay__title {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.search-overlay__title-action {
  margin-inline-start: auto;
  border: 0;
  background: transparent;
  color: var(--brand-text);
  font: inherit;
  font-size: var(--fs-2xs);
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
  cursor: pointer;
}

/* recent searches */
.search-recents { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }

.search-recent {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-block-size: 44px;
  padding: var(--sp-2) var(--sp-3);
  margin-inline: calc(var(--sp-3) * -1);
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: var(--fs-sm);
  text-decoration: none;
  cursor: pointer;
}

.search-recent:hover { background: var(--surface-2); color: var(--ink); }

.search-recent .icon { color: var(--ink-3); flex: none; }

.search-recent__remove {
  margin-inline-start: auto;
  inline-size: 32px;
  block-size: 32px;
  display: inline-grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
}

.search-recent__remove:hover { background: var(--surface-3); color: var(--danger); }

/* trending chips */
.search-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

.search-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-block-size: 36px;
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--ink-2);
  font: inherit;
  font-size: var(--fs-sm);
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

.search-chip:hover { border-color: var(--brand); background: var(--brand-soft); color: var(--brand-text); }

.search-chip .icon { color: var(--brand-text); }

/* live suggestions */
.search-suggestions { display: grid; gap: var(--sp-1); margin: 0; padding: 0; list-style: none; }

.search-suggestion {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2);
  border-radius: var(--r-md);
  color: var(--ink);
  text-decoration: none;
  transition: background-color var(--dur-2) var(--ease);
}

.search-suggestion:hover,
.search-suggestion.is-active,
.search-suggestion.is-selected { background: var(--surface-2); }

.search-suggestion__thumb {
  inline-size: 56px;
  block-size: 56px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  object-fit: cover;
  display: block;
}

.search-suggestion__body { min-inline-size: 0; display: grid; gap: 2px; }

.search-suggestion__name {
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: var(--lh-snug);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-suggestion__name mark {
  background: var(--brand-soft);
  color: var(--brand-text);
  border-radius: 3px;
  padding-inline: 2px;
}

.search-suggestion__meta {
  font-size: var(--fs-xs);
  color: var(--ink-3);
}

.search-suggestion__price {
  font-size: var(--fs-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* category shortcuts */
.search-shortcuts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}

@media (min-width: 560px) {
  .search-shortcuts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.search-shortcut {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-block-size: 48px;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--ink-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  transition: border-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

.search-shortcut:hover { border-color: var(--brand); color: var(--brand-text); }

.search-shortcut .icon { color: var(--brand-text); flex: none; }

.search-overlay__empty {
  display: grid;
  justify-items: center;
  gap: var(--sp-3);
  padding-block: var(--sp-12);
  text-align: center;
  color: var(--ink-3);
}

.search-overlay__foot {
  flex: none;
  display: none;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-block-start: 1px solid var(--line);
  background: var(--bg-soft);
  font-size: var(--fs-2xs);
  color: var(--ink-3);
}

@media (min-width: 768px) {
  .search-overlay__foot { display: flex; }
}

.search-overlay__hint { display: inline-flex; align-items: center; gap: var(--sp-1); }

.search-overlay__key {
  font-family: var(--font-mono);
  padding: 1px var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  background: var(--surface);
}


/* ==========================================================================
   08  FOOTER  .site-footer

   Three bands on the page's own paper: the letter sign-up, the link columns,
   then the legal line. Deliberately not a dark full-bleed slab — a shop's
   footer is a directory, and setting it in the same ink and paper as the rest
   of the page is what stops it reading as a second, louder site.

     .footer-join   sign-up.  bg-soft, hairline top and bottom
     .footer-main   brand column + three link columns + the shop address
     .footer-legal  copyright, payment marks, fine links

   Every colour comes from a token, so the whole footer inverts correctly in
   dark mode with no per-band overrides.
   ========================================================================== */

.site-footer {
  border-block-start: 1px solid var(--line);
  background: var(--bg);
  color: var(--ink);
}


/* --- 08a · the letter ----------------------------------------------------- */

.footer-join {
  border-block-end: 1px solid var(--line);
  background: var(--bg-soft);
}

.footer-join__inner {
  display: grid;
  gap: var(--sp-6);
  padding-block: var(--sp-10);
}

@media (min-width: 900px) {
  .footer-join__inner {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    align-items: center;
    gap: var(--sp-12);
    padding-block: var(--sp-12);
  }
}

.footer-join__eyebrow {
  margin: 0 0 var(--sp-2);
  color: var(--ink-3);
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
}

.footer-join__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 1.1rem + 1.1vw, 1.875rem);
  font-weight: 400;
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
  text-wrap: balance;
}

.footer-join__text {
  max-inline-size: 54ch;
  margin: var(--sp-3) 0 0;
  color: var(--ink-2);
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
}

.footer-join__form { margin: 0; }

/* A rule, not a box. The field is the underline: no fill, no radius, nothing
   that would make a sign-up look like a search bar. */
.footer-join__row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  border-block-end: 1px solid var(--line-2);
  transition: border-color var(--dur-2) var(--ease);
}
.footer-join__row:focus-within { border-block-end-color: var(--ink); }

.footer-join__input {
  flex: 1 1 auto;
  min-inline-size: 0;
  min-block-size: 48px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-sm);
}
.footer-join__input::placeholder { color: var(--ink-3); }
.footer-join__input:focus-visible { outline-offset: 4px; }

.footer-join__submit {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-block-size: 48px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}
.footer-join__submit .icon { transition: transform var(--dur-2) var(--ease); }
.footer-join__submit:hover .icon { transform: translateX(3px); }

.footer-join__ok {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: var(--sp-4) 0 0;
  color: var(--success);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

.footer-join__note {
  margin: var(--sp-3) 0 0;
  color: var(--ink-3);
  font-size: var(--fs-2xs);
  line-height: var(--lh-relaxed);
}
.footer-join__note a { color: var(--ink-2); text-underline-offset: .2em; }
.footer-join__note a:hover { color: var(--ink); }


/* --- 08b · the columns ---------------------------------------------------- */

.footer-main__inner {
  display: grid;
  gap: var(--sp-10) var(--sp-8);
  padding-block: var(--sp-10);
}

@media (min-width: 480px) {
  .footer-main__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* On a phone the single column stacked every link list and the address into
   a scroll of ~1.5 screens. The link lists only hold two or three words a
   row, so they pair up; the brand text and the address keep the full width. */
@media (max-width: 479.98px) {
  .footer-main__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-8) var(--sp-5); }
  .footer-brand,
  .footer-col:has(> .footer-visit) { grid-column: 1 / -1; }
}

@media (min-width: 1024px) {
  .footer-main__inner {
    /* Brand and address columns carry sentences, so they get the width; the
       three link columns only ever hold two or three words. */
    grid-template-columns:
      minmax(0, 1.9fr) repeat(3, minmax(0, 1fr)) minmax(0, 1.4fr);
    padding-block: var(--sp-12);
  }
}

.footer-brand { display: grid; align-content: start; gap: var(--sp-4); }

@media (min-width: 480px) and (max-width: 1023.98px) {
  .footer-brand { grid-column: 1 / -1; }
}

.footer-brand__mark {
  display: grid;
  justify-items: start;
  gap: 3px;
  color: var(--ink);
  text-decoration: none;
}
.footer-brand__name {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  line-height: 1;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.footer-brand__tag {
  color: var(--ink-3);
  font-size: var(--fs-2xs);   /* was 9px — below the 12px floor */
  line-height: 1;
  letter-spacing: .22em;
  text-transform: uppercase;
}

.footer-brand__text {
  max-inline-size: 42ch;
  margin: 0;
  color: var(--ink-2);
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
}

/* Bordered discs, not bare glyphs. A 16px icon floating in a 40px hit area with
   nothing around it reads as an accident rather than a control — the ring gives
   the row a shape, and the icon can then be sized to fill it properly. */
.footer-social {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: var(--sp-1) 0 0;
  padding: 0;
  list-style: none;
}
.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 40px;
  block-size: 40px;
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  color: var(--ink-2);
  transition: color var(--dur-2) var(--ease),
              background-color var(--dur-2) var(--ease),
              border-color var(--dur-2) var(--ease);
}
/* explicit, because .icon--sm is 1em and would track the 14px body size */
.footer-social a > .icon { inline-size: var(--icon-md); block-size: var(--icon-md); }
.footer-social a:hover,
.footer-social a:focus-visible {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--ink-inv);
}

.footer-col { min-inline-size: 0; }

.footer-col__title {
  margin: 0 0 var(--sp-4);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
}

.footer-col__list {
  display: grid;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.footer-col__list a {
  display: inline-flex;
  align-items: center;
  min-block-size: 24px;
  color: var(--ink-2);
  font-size: var(--fs-sm);
  text-decoration: none;
  transition: color var(--dur-2) var(--ease);
}
.footer-col__list a:hover {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: .25em;
}

.footer-visit {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--fs-sm);
  font-style: normal;
  line-height: var(--lh-relaxed);
}
.footer-visit__hours {
  margin: var(--sp-2) 0 var(--sp-4);
  color: var(--ink-3);
  font-size: var(--fs-xs);
}

.footer-contact {
  display: grid;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.footer-contact li {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-inline-size: 0;
}
.footer-contact .icon { flex: none; color: var(--ink-3); }
.footer-contact a {
  min-block-size: 24px;
  display: inline-flex;
  align-items: center;
  color: var(--ink-2);
  font-size: var(--fs-sm);
  text-decoration: none;
  /* break-word, not anywhere: `anywhere` let the break land mid-domain
     ("care@aimscraftkash" / "mir.com"). break-word only breaks a token
     that cannot fit on a line of its own. */
  overflow-wrap: break-word;
}
.footer-contact a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: .25em; }


/* --- 08c · the legal line ------------------------------------------------- */

.footer-legal {
  border-block-start: 1px solid var(--line);
  background: var(--bg-soft);
}

/* The back-to-top FAB is fixed to the bottom-right corner, and it is MOST
   useful at the bottom of the page — so unlike the sticky add-to-cart bar it
   cannot simply stand down there. Reserve the corner instead: the legal row
   keeps its last link ("Cookies") clear of the button. */
.footer-legal__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4) var(--sp-6);
  padding-block: var(--sp-5);
  padding-inline-end: var(--sp-16);   /* clear of the fixed back-to-top button */
  color: var(--ink-3);
  font-size: var(--fs-2xs);
}

.footer-legal__copy { margin: 0; }
.footer-legal__copy a {
  color: var(--ink-2);
  text-decoration: none;
  text-underline-offset: .2em;
}
.footer-legal__copy a:hover { color: var(--ink); text-decoration: underline; }

.footer-pay {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* The payment row has TWO markup shapes. The footer writes a bare
   `.footer-pay__mark` svg; cart, checkout, order-confirmation and home-v3 wrap
   each mark in a `.footer-pay__item` <li> holding its own 48x32 svg. Only the
   first shape survived the §08 rewrite, so those four pages lost their sizing
   and painted the artwork at its raw 48x32. Both shapes are sized here.

   No border, no plate, no radius: every i-pay-* symbol already draws its own
   rounded card outline, so a CSS border around it renders a second edge just
   inside the first. Let the artwork be the card. */
.footer-pay__mark,
.footer-pay__item {
  display: block;
  inline-size: 38px;
  /* aspect-ratio, not `block-size: auto`: the bare shape's outer <svg> carries
     no viewBox of its own (the viewBox lives on the symbol it pulls in), so an
     auto height falls back to the 150px replaced-element default. */
  aspect-ratio: 48 / 32;
  block-size: auto;
  color: var(--ink-2);
}
.footer-pay__item > svg,
.footer-pay__item > img {
  display: block;
  inline-size: 100%;
  block-size: auto;
}

.footer-legal__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
}
.footer-legal__links a {
  display: inline-flex;
  align-items: center;
  min-block-size: 24px;
  color: var(--ink-3);
  text-decoration: none;
}
.footer-legal__links a:hover { color: var(--ink); text-decoration: underline; text-underline-offset: .2em; }

@media (max-width: 767.98px) {
  .footer-legal__inner { justify-content: flex-start; }
}


/* ==========================================================================
   09  PAGE HEAD
   ========================================================================== */

.page-head {
  padding-block: var(--sp-6) var(--sp-8);
  border-block-end: 1px solid var(--line);
  background: var(--bg-soft);
}

.page-head--plain { background: transparent; border-block-end: 0; }
.page-head--center { text-align: center; }

.page-head__inner {
  display: grid;
  gap: var(--sp-4);
}

@media (min-width: 1024px) {
  .page-head { padding-block: var(--sp-8) var(--sp-10); }
  .page-head__inner {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--sp-8);
  }
  .page-head--center .page-head__inner { grid-template-columns: minmax(0, 1fr); justify-items: center; }
}

.page-head__main { display: grid; gap: var(--sp-2); min-inline-size: 0; }

.page-head__crumbs { margin-block-end: var(--sp-1); }

.page-head__eyebrow {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--brand-text);
}

.page-head__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-4xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  color: var(--ink);
  text-wrap: balance;
}

.page-head__sub {
  margin: 0;
  font-size: var(--fs-base);
  color: var(--ink-3);
  max-inline-size: 68ch;
}

.page-head__meta {
  display: flex;
  align-items: center;
  gap: var(--sp-2) var(--sp-4);
  flex-wrap: wrap;
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

.page-head__count { font-variant-numeric: tabular-nums; }

.page-head__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

.page-head__media {
  display: none;
}

@media (min-width: 1024px) {
  .page-head--media .page-head__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 340px); align-items: center; }
  .page-head--media .page-head__media { display: block; }
  .page-head__media img { inline-size: 100%; block-size: auto; border-radius: var(--r-lg); display: block; }
}


/* ==========================================================================
   10  HERO
   ========================================================================== */

.hero {
  position: relative;
  background: var(--bg-soft);
  overflow: hidden;
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--sp-8);
  padding-block: var(--sp-10);
  align-items: center;
}

@media (min-width: 1024px) {
  .hero__inner { padding-block: var(--sp-16); gap: var(--sp-12); }
}

.hero__body {
  display: grid;
  gap: var(--sp-4);
  align-content: center;
  justify-items: start;
  max-inline-size: 60ch;
}

.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--r-full);
  background: var(--brand-soft);
  color: var(--brand-text);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

.hero__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-5xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  color: var(--ink);
  text-wrap: balance;
}

.hero__title em {
  font-style: italic;
  color: var(--brand-text);
}

.hero__text {
  margin: 0;
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
  color: var(--ink-2);
  max-inline-size: 54ch;
}

.hero__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-block-start: var(--sp-2);
}

.hero__stats {
  /* a grid, not a wrapping flex row: four stats wrapped 3 + 1 with an orphan */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  align-items: start;
  gap: var(--sp-6);
  margin-block-start: var(--sp-4);
  padding-block-start: var(--sp-5);
  border-block-start: 1px solid var(--line);
  inline-size: 100%;
}

.hero__stat { display: grid; gap: 2px; }

.hero__stat-value {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: 1;
  color: var(--ink);
}

.hero__stat-label {
  font-size: var(--fs-xs);
  color: var(--ink-3);
}

.hero__media {
  position: relative;
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--surface-2);
}

.hero__media img,
.hero__media video {
  inline-size: 100%;
  block-size: 100%;
  display: block;
  object-fit: cover;
  aspect-ratio: 4 / 5;
}

.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 30%, var(--overlay));
  pointer-events: none;
}

.hero__badge {
  position: absolute;
  inset-block-end: var(--sp-5);
  inset-inline-start: var(--sp-5);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-full);
  background: color-mix(in oklab, var(--surface) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--ink);
  font-size: var(--fs-xs);
  font-weight: 600;
  box-shadow: var(--sh-2);
}

/* --- hero--split --------------------------------------------------------- */

@media (min-width: 1024px) {
  .hero--split .hero__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .hero--split .hero__media img { aspect-ratio: 1 / 1; }
  /* the split hero is the one place with room for the display size */
  .hero--split .hero__title { font-size: var(--fs-6xl); }
  .hero--split.hero--reverse .hero__body { order: 2; }
}

/* --- hero--full ---------------------------------------------------------- */

.hero--full { background: var(--ink); color: var(--ink-inv); }

.hero--full .hero__inner {
  min-block-size: min(82svh, 760px);
  align-content: end;
  padding-block: var(--sp-16) var(--sp-12);
}

.hero--full .hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero--full .hero__bg img,
.hero--full .hero__bg video {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}

.hero--full .hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, color-mix(in oklab, var(--overlay) 40%, transparent) 0%, var(--overlay) 100%);
}

.hero--full .hero__title,
.hero--full .hero__text,
.hero--full .hero__stat-value { color: var(--ink-inv); }

.hero--full .hero__text { opacity: .88; }

.hero--full .hero__stats { border-block-start-color: color-mix(in oklab, var(--ink-inv) 24%, transparent); }

.hero--full .hero__stat-label { color: color-mix(in oklab, var(--ink-inv) 70%, transparent); }

.hero--full .hero__eyebrow {
  background: color-mix(in oklab, var(--ink-inv) 16%, transparent);
  color: var(--ink-inv);
}

/* --- hero--editorial ----------------------------------------------------- */

.hero--editorial { background: var(--bg); }

.hero--editorial .hero__inner {
  justify-items: center;
  text-align: center;
  gap: var(--sp-6);
}

.hero--editorial .hero__body {
  justify-items: center;
  text-align: center;
  max-inline-size: 68ch;
}

.hero--editorial .hero__title { font-size: var(--fs-6xl); }

.hero--editorial .hero__media {
  inline-size: 100%;
  border-radius: var(--r-2xl);
}

.hero--editorial .hero__media img { aspect-ratio: 16 / 9; }

/* --- hero--product (PDP top) --------------------------------------------- */

.hero--product { background: var(--bg); }

.hero--product .hero__inner {
  padding-block: var(--sp-6) var(--sp-10);
  gap: var(--sp-6);
  align-items: start;
}

@media (min-width: 1024px) {
  .hero--product .hero__inner {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: var(--sp-12);
    padding-block: var(--sp-8) var(--sp-12);
  }
  /* `.hero` sets overflow:hidden, which makes it the scrollport for anything
     inside — and a sticky element cannot stick to a box that never scrolls.
     That is why the original sticky on .hero__aside had no effect either.
     `clip` still contains any bleed but creates no scroll container. */
  .hero--product { overflow: clip; }

  /* The gallery is the SHORT column (≈645px) and the buy panel the tall one
     (≈1875px). Sticking the tall column does nothing — it never runs out of
     content — while the gallery scrolled away and left the whole left half of
     the PDP empty for most of the page. Stick the short column instead, which
     is what a product page wants anyway: the image stays with you while the
     specs, reviews and Q&A scroll past. */
  .hero--product .gallery {
    position: sticky;
    inset-block-start: calc(var(--header-h-sm) + var(--sp-6));
    align-self: start;
  }
}

.hero--product .hero__media { border-radius: var(--r-lg); }
.hero--product .hero__media img { aspect-ratio: 1 / 1; }

.hero--compact .hero__inner { padding-block: var(--sp-8); }


/* ==========================================================================
   11  SECTION HEAD
   ========================================================================== */

.section-head {
  display: grid;
  gap: var(--sp-3);
  margin-block-end: var(--sp-6);
}

@media (min-width: 768px) {
  .section-head {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: var(--sp-6);
    margin-block-end: var(--sp-8);
  }
}

.section-head__main { display: grid; gap: var(--sp-2); min-inline-size: 0; }

.section-head__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--brand-text);
}

.section-head__eyebrow::before {
  content: "";
  inline-size: 18px;
  block-size: 2px;
  border-radius: var(--r-full);
  background: currentColor;
}

.section-head__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-3xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  color: var(--ink);
  text-wrap: balance;
}

.section-head__text {
  margin: 0;
  font-size: var(--fs-base);
  color: var(--ink-3);
  max-inline-size: 62ch;
}

.section-head__link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--brand-text);
  text-decoration: none;
  white-space: nowrap;
}

.section-head__link .icon { transition: transform var(--dur-2) var(--ease); }
.section-head__link:hover .icon { transform: translateX(3px); }

.section-head__aside {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

.section-head--center {
  justify-items: center;
  text-align: center;
  grid-template-columns: minmax(0, 1fr);
}

.section-head--center .section-head__main { justify-items: center; }
.section-head--center .section-head__eyebrow::before { display: none; }
.section-head--center .section-head__text { margin-inline: auto; }


/* ==========================================================================
   12  SHOP LAYOUT
   --------------------------------------------------------------------------
   Sidebar is a sticky rail >= 1024px, and a bottom sheet below it.
   ========================================================================== */

.shop-layout {
  display: grid;
  gap: var(--sp-6);
  padding-block: var(--sp-6) var(--sp-12);
  align-items: start;
}

@media (min-width: 1024px) {
  .shop-layout {
    grid-template-columns: minmax(0, 264px) minmax(0, 1fr);
    gap: var(--sp-10);
    padding-block: var(--sp-8) var(--sp-16);
  }
  .shop-layout--wide-sidebar { grid-template-columns: minmax(0, 300px) minmax(0, 1fr); }
  .shop-layout--right-sidebar { grid-template-columns: minmax(0, 1fr) minmax(0, 264px); }
  .shop-layout--right-sidebar .shop-layout__sidebar { order: 2; }
}

.shop-layout__content { min-inline-size: 0; display: grid; gap: var(--sp-5); align-content: start; }

.shop-layout__sidebar { min-inline-size: 0; }

@media (min-width: 1024px) {
  .shop-layout__sidebar {
    position: sticky;
    inset-block-start: calc(var(--header-h-sm) + var(--sp-6));
    max-block-size: calc(100svh - var(--header-h-sm) - var(--sp-10));
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    padding-inline-end: var(--sp-2);
  }
}

/* sheet mode (< 1024px) */
@media (max-width: 1023.98px) {
  .shop-layout__sidebar {
    position: fixed;
    inset: 0;
    z-index: var(--z-drawer);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    visibility: hidden;
    pointer-events: none;
  }

  .shop-layout__sidebar.is-open { visibility: visible; pointer-events: auto; }

  .shop-layout__sidebar::before {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--overlay);
    opacity: 0;
    transition: opacity var(--dur-3) var(--ease);
  }

  .shop-layout__sidebar.is-open::before { opacity: .6; }

  .shop-sidebar {
    position: relative;
    max-block-size: 88svh;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border-start-start-radius: var(--r-xl);
    border-start-end-radius: var(--r-xl);
    box-shadow: var(--sh-4);
    transform: translateY(100%);
    transition: transform var(--dur-4) var(--ease);
    padding-block-end: var(--safe-b);
  }

  .shop-layout__sidebar.is-open .shop-sidebar { transform: none; }

  /* Scoped to the sheet so these beat the `display: none` defaults that are
     declared LATER in this file. As bare class selectors they tied on
     specificity and lost on source order, so the bottom sheet opened with no
     drag handle, no title, no close button and no Clear/Show footer — just a
     bare scrolling list. */
  .shop-layout__sidebar .shop-sidebar__handle { display: block; }
  .shop-layout__sidebar .shop-sidebar__head { display: flex; }
  .shop-layout__sidebar .shop-sidebar__foot { display: flex; }
}

.shop-sidebar { display: grid; gap: var(--sp-5); }

.shop-sidebar__handle {
  display: none;
  flex: none;
  inline-size: 44px;
  block-size: 5px;
  margin: var(--sp-3) auto var(--sp-1);
  border-radius: var(--r-full);
  background: var(--line-2);
  cursor: grab;
}

.shop-sidebar__head {
  display: none;
  align-items: center;
  gap: var(--sp-3);
  flex: none;
  padding: var(--sp-3) var(--sp-5);
  border-block-end: 1px solid var(--line);
}

.shop-sidebar__title {
  margin: 0;
  font-size: var(--fs-lg);
  font-weight: 700;
}

.shop-sidebar__close {
  margin-inline-start: auto;
  inline-size: 40px;
  block-size: 40px;
  display: inline-grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-full);
  background: var(--surface-2);
  color: var(--ink);
  cursor: pointer;
}

.shop-sidebar__body {
  display: grid;
  gap: var(--sp-5);
  align-content: start;
  min-block-size: 0;
}

@media (max-width: 1023.98px) {
  .shop-sidebar__body {
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: var(--sp-5);
  }
}

.shop-sidebar__foot {
  display: none;
  gap: var(--sp-3);
  flex: none;
  padding: var(--sp-4) var(--sp-5);
  padding-block-end: calc(var(--sp-4) + var(--safe-b));
  border-block-start: 1px solid var(--line);
  background: var(--surface);
}

.shop-sidebar__foot > * { flex: 1 1 0; }

.shop-layout__empty {
  display: grid;
  justify-items: center;
  gap: var(--sp-4);
  padding-block: var(--sp-16);
  text-align: center;
}

.shop-layout__pagination {
  display: flex;
  justify-content: center;
  padding-block-start: var(--sp-8);
}


/* ==========================================================================
   13  ACCOUNT LAYOUT
   ========================================================================== */

.account-layout {
  display: grid;
  gap: var(--sp-6);
  padding-block: var(--sp-6) var(--sp-12);
  align-items: start;
}

@media (min-width: 1024px) {
  .account-layout {
    grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
    gap: var(--sp-10);
    padding-block: var(--sp-8) var(--sp-16);
  }
}

.account-layout__side { min-inline-size: 0; }

@media (min-width: 1024px) {
  .account-layout__side {
    position: sticky;
    inset-block-start: calc(var(--header-h-sm) + var(--sp-6));
  }
}

.account-layout__main {
  min-inline-size: 0;
  display: grid;
  gap: var(--sp-6);
  align-content: start;
}

.account-card {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4);
  margin-block-end: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}

/* The plate is a stand-in until a real profile photo is uploaded, so it carries
   the account holder's initials rather than reading as a missing image. Swap
   the inner <img> for the photo and the label simply sits behind it. */
.account-card__avatar {
  position: relative;
  display: inline-grid;
  place-items: center;
  inline-size: 48px;
  block-size: 48px;
  flex: none;
  border-radius: var(--r-full);
  overflow: hidden;
  background: var(--surface-2);
  color: var(--avatar-ink);
  /* clamped at the 12px floor: the small avatar computed 9.1px */
  font-size: max(var(--fs-2xs), calc(48px * .34));
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-wide);
  user-select: none;
}
.account-card__avatar > * { grid-area: 1 / 1; }
/* --avatar-ink is fixed for a photo's backdrop; with no photo on the dark theme the initials are the whole plate and
   need the theme's own ink, or they vanish into it */
[data-theme="dark"] .account-card__avatar { color: var(--ink-2); }
.account-card__avatar-img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}

.account-card__body { min-inline-size: 0; display: grid; gap: 2px; }

.account-card__name {
  font-size: var(--fs-sm);
  font-weight: 700;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-card__meta { font-size: var(--fs-xs); color: var(--ink-3); }

.account-nav {
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* horizontal scroller on mobile */
@media (max-width: 1023.98px) {
  .account-nav {
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    gap: var(--sp-2);
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-inline: contain;
    scroll-snap-type: x proximity;
    padding-block-end: var(--sp-2);
    /* Bleed to exactly the container gutter, and snap to it. A fixed sp-5
       bleed overshot the 16px phone gutter, and with no scroll-padding the
       snap parked the first/current pill hard against the screen edge,
       out of line with every card below it. */
    margin-inline: calc(var(--container-pad) * -1);
    padding-inline: var(--container-pad);
    scroll-padding-inline: var(--container-pad);
  }
  .account-nav::-webkit-scrollbar { display: none; }
  .account-nav__link {
    border: 1px solid var(--line);
    border-radius: var(--r-full);
    scroll-snap-align: start;
    white-space: nowrap;
  }
}

.account-nav__link {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-block-size: 44px;
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

.account-nav__link .icon { color: var(--ink-3); flex: none; }

.account-nav__link:hover { background: var(--surface-2); color: var(--ink); }

.account-nav__link.is-active,
.account-nav__link[aria-current="page"] {
  background: var(--brand-soft);
  color: var(--brand-text);
  border-color: var(--brand);
}

.account-nav__link.is-active .icon,
.account-nav__link[aria-current="page"] .icon { color: var(--brand-text); }

.account-nav__count {
  margin-inline-start: auto;
  font-size: var(--fs-2xs);
  font-weight: 700;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.account-nav__sep {
  block-size: 1px;
  background: var(--line);
  margin-block: var(--sp-2);
}

@media (max-width: 1023.98px) {
  .account-nav__sep,
  .account-nav__count { display: none; }
}

.account-panel {
  display: grid;
  /* Two panels side by side (wallet's points + gift card) are stretched to
     the taller one; without this the shorter panel shared its spare height
     out between its rows, so its head sat 2px taller than its neighbour's
     and its paragraphs drifted apart. */
  align-content: start;
  gap: var(--sp-5);
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}

@media (min-width: 768px) {
  .account-panel { padding: var(--sp-8); }
}

.account-panel__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding-block-end: var(--sp-4);
  border-block-end: 1px solid var(--line);
}

/* The title is an h2, so it sets in Instrument Serif — a condensed display
   face that ships in one weight (bold is never synthesised, see base.css).
   At --fs-xl it read smaller than the 15px sans paragraph under it, so the
   panel headings on every account page had no presence. A display step up
   restores the hierarchy; the 700 was a no-op and is dropped. */
.account-panel__title {
  margin: 0;
  font-size: var(--fs-2xl);
  font-weight: var(--fw-regular);
  line-height: var(--lh-snug);
  color: var(--ink);
}
@media (min-width: 768px) {
  .account-panel__title { font-size: var(--fs-3xl); line-height: var(--lh-tight); }
}

.account-panel__actions { margin-inline-start: auto; display: flex; align-items: center; gap: var(--sp-2); }

/* A ghost button has no visible box, so its label is what the eye aligns —
   and --btn-px of padding set that label in from the content edge. Pull the
   padding back out so the words sit on the same edge as the rule under the
   head (right-hand end on desktop, left-hand start once the head wraps).
   The desktop pull sits on the container, not the button: a flex item's
   negative margin is dropped from its parent's max-content width, so a lone
   ghost button never moved. Every button in these heads is .btn--sm, whose
   --btn-px is --sp-3. */
.account-panel__actions:has(> .btn--ghost:last-child) { margin-inline-end: calc(var(--sp-3) * -1); }
@media (max-width: 639.98px) {
  .account-panel__actions { flex-wrap: wrap; }
  .account-panel__actions > .btn--ghost:first-child { margin-inline-start: calc(var(--btn-px) * -1); }
}


/* ==========================================================================
   14  AUTH LAYOUT
   ========================================================================== */

.auth-layout {
  display: grid;
  min-block-size: calc(100svh - var(--header-h));
}

@media (min-width: 1024px) {
  .auth-layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .auth-layout--reverse .auth-layout__form { order: 2; }
}

.auth-layout__form {
  display: grid;
  place-items: center;
  padding: var(--sp-8) var(--sp-5);
}

@media (min-width: 768px) {
  .auth-layout__form { padding: var(--sp-12) var(--sp-10); }
}

/* Below the split the column still fills the viewport, and centring a short
   card in it (the OTP page) dropped its breadcrumb 74px under the header
   while the login breadcrumb sat at 44px. Hang every card from the top. */
@media (max-width: 1023.98px) {
  .auth-layout__form { place-items: start center; }
}

.auth-card {
  inline-size: 100%;
  max-inline-size: 420px;
  display: grid;
  gap: var(--sp-5);
  align-content: start;
}

.auth-card__head { display: grid; gap: var(--sp-2); }

.auth-card__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-3xl);
  line-height: var(--lh-tight);
  color: var(--ink);
}

.auth-card__text { margin: 0; font-size: var(--fs-sm); color: var(--ink-3); }

.auth-card__form { display: grid; gap: var(--sp-4); }

.auth-card__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  font-size: var(--fs-sm);
}

.auth-card__divider {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--ink-3);
}

.auth-card__divider::before,
.auth-card__divider::after {
  content: "";
  flex: 1 1 auto;
  block-size: 1px;
  background: var(--line);
}

.auth-card__socials { display: grid; gap: var(--sp-2); }

@media (min-width: 480px) {
  .auth-card__socials { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.auth-card__foot {
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

/* sentence-case fine print: --fs-xs; --fs-2xs is for badges and caps labels */
.auth-card__legal {
  font-size: var(--fs-xs);
  color: var(--ink-3);
  text-align: center;
}

/* An icon-led .hint carries its icon in the text flow, so the second line of
   a wrapped hint ran back under the icon instead of under the words. Hang the
   icon in a gutter the width of icon + its --sp-1 margin. */
.auth-card .hint:has(> .icon:first-child) {
  padding-inline-start: calc(var(--icon-sm) + var(--sp-1));
  text-indent: calc((var(--icon-sm) + var(--sp-1)) * -1);
}
/* ...a centred hint has no left edge to hang from; keep it centred. */
.auth-card .hint.u-justify-center:has(> .icon:first-child),
.auth-card .hint.u-text-center:has(> .icon:first-child) { padding-inline-start: 0; text-indent: 0; text-align: center; }

/* "Back to sign in", "Not your number?": the leading icon in a text link sat
   hard against the first letter. */
.auth-card :is(p, span) > a:not(.btn) > .icon:first-child {
  margin-inline-end: var(--sp-1);
  vertical-align: -0.15em;
}

/* brand artwork panel */
.auth-layout__art {
  display: none;
  position: relative;
  overflow: hidden;
  background: var(--brand-soft);
  isolation: isolate;
}

@media (min-width: 1024px) {
  .auth-layout__art { display: block; }
}

.auth-layout__art img,
.auth-layout__art video {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}

.auth-art__body {
  position: relative;
  z-index: 1;
  display: grid;
  align-content: end;
  gap: var(--sp-3);
  block-size: 100%;
  padding: var(--sp-12);
  color: var(--ink-inv);
  /* The scrim has to carry the quote and the byline over whatever artwork the
     page ships. Starting the ramp at 40% left the lower third too light on the
     paler panels — the byline measured 4.4:1 there — so it starts earlier and
     ends on a solid dark. */
  background: linear-gradient(180deg,
    transparent 25%,
    color-mix(in oklab, var(--ink) 45%, transparent) 62%,
    color-mix(in oklab, var(--ink) 82%, transparent) 100%);
}

.auth-art__quote {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-3xl);
  line-height: var(--lh-snug);
  text-wrap: balance;
}

.auth-art__cite {
  font-size: var(--fs-sm);
  /* The art behind this byline ranges from mid-tan to near-black across the
     four auth pages. At .8 the lighter panels dropped the caption to 3.5:1, so
     it is softened only slightly — enough to read as secondary, never enough
     to stop being readable. */
  opacity: .92;
  font-style: normal;
}

.auth-art__marks {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  margin-block-start: var(--sp-4);
  opacity: .8;
}


/* ==========================================================================
   15  CHECKOUT LAYOUT
   ========================================================================== */

.checkout-layout {
  display: grid;
  gap: var(--sp-6);
  padding-block: var(--sp-6) var(--sp-12);
  align-items: start;
}

@media (min-width: 1024px) {
  .checkout-layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
    gap: var(--sp-12);
    padding-block: var(--sp-10) var(--sp-16);
  }
}

.checkout-layout__main {
  min-inline-size: 0;
  display: grid;
  gap: var(--sp-6);
  align-content: start;
  max-inline-size: 680px;
}

.checkout-layout__aside { min-inline-size: 0; }

@media (min-width: 1024px) {
  .checkout-layout__aside {
    position: sticky;
    inset-block-start: calc(var(--header-h-sm) + var(--sp-6));
  }
}

/* summary collapses to a disclosure on mobile */
.checkout-summary {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: hidden;
}

.checkout-summary__toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  inline-size: 100%;
  min-block-size: 56px;
  padding: var(--sp-4);
  border: 0;
  background: var(--bg-soft);
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
}

.checkout-summary__toggle .icon:first-child { color: var(--brand-text); }

.checkout-summary__toggle-total {
  margin-inline-start: auto;
  font-size: var(--fs-lg);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.checkout-summary__chev { transition: transform var(--dur-3) var(--ease); }
.checkout-summary__toggle[aria-expanded="true"] .checkout-summary__chev { transform: rotate(180deg); }

.checkout-summary__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-3) var(--ease);
}

.checkout-summary__panel.is-open,
.checkout-summary__toggle[aria-expanded="true"] + .checkout-summary__panel { grid-template-rows: 1fr; }

.checkout-summary__inner { overflow: hidden; min-block-size: 0; }

.checkout-summary__body { display: grid; gap: var(--sp-4); padding: var(--sp-5); }

.checkout-summary__foot {
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-5);
  border-block-start: 1px solid var(--line);
  background: var(--bg-soft);
}

@media (min-width: 1024px) {
  .checkout-summary__toggle { display: none; }
  .checkout-summary__panel { grid-template-rows: 1fr; }
}

/* progress steps */
.checkout-steps {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
}

.checkout-steps::-webkit-scrollbar { display: none; }

.checkout-steps__item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--ink-3);
  white-space: nowrap;
}

.checkout-steps__item::after {
  content: "";
  inline-size: var(--sp-8);
  block-size: 1px;
  background: var(--line);
}

.checkout-steps__item:last-child::after { display: none; }

.checkout-steps__num {
  display: grid;
  place-items: center;
  inline-size: 26px;
  block-size: 26px;
  border-radius: var(--r-full);
  border: 1px solid var(--line-2);
  font-size: var(--fs-xs);
  font-weight: 700;
}

.checkout-steps__item.is-active { color: var(--ink); font-weight: 600; }
.checkout-steps__item.is-active .checkout-steps__num {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-ink);
}

.checkout-steps__item.is-done { color: var(--ink-2); }
.checkout-steps__item.is-done .checkout-steps__num {
  background: var(--success-soft);
  border-color: var(--success);
  color: var(--success);
}

/* minimal chrome variant for the checkout page header */
.site-header--checkout .site-header__center,
.site-header--checkout .header-burger,
.site-header--checkout .header-search { display: none; }


/* ==========================================================================
   16  BLOG LAYOUT
   ========================================================================== */

.blog-layout {
  display: grid;
  gap: var(--sp-8);
  padding-block: var(--sp-6) var(--sp-12);
  align-items: start;
}

@media (min-width: 1024px) {
  .blog-layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 300px);
    gap: var(--sp-12);
    padding-block: var(--sp-8) var(--sp-16);
  }
}

.blog-layout__main { min-inline-size: 0; display: grid; gap: var(--sp-8); align-content: start; }

.blog-layout__aside { min-inline-size: 0; display: grid; gap: var(--sp-6); align-content: start; }

@media (min-width: 1024px) {
  .blog-layout__aside {
    position: sticky;
    inset-block-start: calc(var(--header-h-sm) + var(--sp-6));
  }
}

/* article body: readable measure with full-bleed escapes */
.blog-article {
  display: grid;
  grid-template-columns:
    minmax(0, 1fr)
    min(var(--container-narrow), 100%)
    minmax(0, 1fr);
}

.blog-article > * { grid-column: 2; }

.blog-article > .blog-article__bleed {
  grid-column: 1 / -1;
  inline-size: 100%;
}

.blog-article > .blog-article__wide {
  grid-column: 1 / -1;
  inline-size: min(var(--container), 100%);
  margin-inline: auto;
}

/* Beside the 300px aside the main column is already a reading width. Centring
   the 820px measure inside it only pushed the copy 16px in from the container
   edge that the cover image and the article header sit on. */
.blog-layout__main > .blog-article { grid-template-columns: 0 minmax(0, 1fr) 0; }

/* Prose rhythm for HTML bodies: 18px copy at ~70 characters, and headings that
   open a section instead of sitting glued to the paragraph above. */
.blog-article > p { color: var(--ink-2); font-size: var(--fs-lg); line-height: var(--lh-relaxed); }
.blog-article > :is(p, ul, ol, blockquote) { max-inline-size: 38em; }
.blog-article > h2:not(:first-child) { margin-block: var(--sp-12) var(--sp-2); }
.blog-article > h3:not(:first-child) { margin-block: var(--sp-8) var(--sp-1); }

/* Admin journal posts are stored as plain text (paragraphs split by blank lines)
   and content-live.js injects the body as one bare text run. In a grid a text
   run becomes an anonymous item that auto-places into the first — zero-width —
   column: one word per line down the page. With no element children, set it as
   prose and let the blank lines stand as paragraph breaks. */
.blog-article:not(:has(> *)) {
  display: block;
  max-inline-size: 38em;
  white-space: pre-line;
  color: var(--ink-2);
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
}

.blog-article__figure { display: grid; gap: var(--sp-2); margin-block: var(--sp-8); }

.blog-article__figure img {
  inline-size: 100%;
  block-size: auto;
  display: block;
  border-radius: var(--r-lg);
}

.blog-article__caption {
  font-size: var(--fs-xs);
  color: var(--ink-3);
  text-align: center;
}

.blog-article__meta {
  display: flex;
  align-items: center;
  gap: var(--sp-2) var(--sp-4);
  flex-wrap: wrap;
  font-size: var(--fs-sm);
  color: var(--ink-3);
  padding-block: var(--sp-4);
  border-block: 1px solid var(--line);
  margin-block: var(--sp-6);
}

.blog-article__share {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-inline-start: auto;
}

.blog-toc {
  display: grid;
  gap: var(--sp-2);
  padding: var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}

.blog-toc__title {
  margin: 0;
  /* pages mark this up as an h2 as often as a p; without a family it inherited
     the h2 display serif and a 13px uppercase serif label is barely legible */
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.blog-toc__list { display: grid; gap: var(--sp-1); margin: 0; padding: 0; list-style: none; }

.blog-toc__link {
  display: block;
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-3);
  border-inline-start: 2px solid var(--line);
  color: var(--ink-3);
  font-size: var(--fs-sm);
  text-decoration: none;
  transition: color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}

.blog-toc__link:hover,
.blog-toc__link.is-active { color: var(--brand-text); border-inline-start-color: var(--brand); }

/* On a touch screen every entry is a tap target: 12px above and below takes a
   one-line row from 31px to the 44px a thumb needs. */
@media (pointer: coarse) {
  .blog-toc__link { padding-block: var(--sp-3); }
}


/* ==========================================================================
   17  GRIDS
   ========================================================================== */

/* THE COLUMN COUNT FOLLOWS THE GRID, NOT THE WINDOW.

   This used to be repeat(4) at 1024px and repeat(5) at 1480px, keyed off the
   VIEWPORT. But this same grid is used both full width (category, offers) and
   beside a 300px filter sidebar (shop, search), so on shop.html the viewport
   said "five columns" while the grid itself only had 896px to give them:

     shop.html at 1024px   645px of grid  ->  4 columns  ->  143px cards
     shop.html at 1920px   896px of grid  ->  5 columns  ->  160px cards

   A 160px product card cannot hold a three-line title, a price and a rating.
   auto-fill + minmax asks the question the right way round: fit as many tracks
   of at least --card-min as the CONTAINER can take. The same rule now gives
   282px cards at 1440px+ whether or not there is a sidebar in the way. */
.grid--products {
  --card-min: 148px;   /* two up on a 390px phone, with the 16px gutter */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--card-min)), 1fr));
  gap: var(--sp-4);
}

@media (min-width: 640px)  { .grid--products { --card-min: 190px; gap: var(--sp-5); } }
@media (min-width: 1024px) { .grid--products { gap: var(--sp-6); } }
@media (min-width: 1280px) { .grid--products { --card-min: 230px; } }
@media (min-width: 1440px) { .grid--products { --card-min: 240px; } }

/* density modifiers */
.grid--products.is-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--products.is-cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--products.is-cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (min-width: 1024px) {
  .grid--products.is-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--products.is-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid--products.is-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* single-column list view */
.grid--products.is-list {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
}

.grid--collections {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
}

@media (min-width: 768px)  { .grid--collections { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-6); } }
@media (min-width: 1280px) { .grid--collections { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.grid--categories {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-3);
}

@media (min-width: 768px)  { .grid--categories { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--sp-5); } }

.grid--posts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-6);
}

@media (min-width: 640px)  { .grid--posts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .grid--posts { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-8); } }
/* One card per row on a phone leaves nothing to line up with, so the two-line
   title reserve (components.css) only put a blank line under one-line titles. */
@media (max-width: 639px) { .grid--posts .blog-card__title { min-block-size: 0; } }

.grid--features {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-5);
}

@media (min-width: 640px)  { .grid--features { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .grid--features { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.grid--gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}

@media (min-width: 768px) { .grid--gallery { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-3); } }

/* editorial bento: first cell spans 2x2 on wide screens */
.grid--bento {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4);
}

@media (min-width: 1024px) {
  .grid--bento {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-auto-rows: minmax(200px, auto);
    gap: var(--sp-5);
  }
  .grid--bento > .is-feature { grid-column: span 2; grid-row: span 2; }
  .grid--bento > .is-wide    { grid-column: span 2; }
  .grid--bento > .is-tall    { grid-row: span 2; }
}


/* ==========================================================================
   18  RAILS (horizontal snap scroll)
   ========================================================================== */

.rail-section { padding-block: var(--sp-10); }

@media (min-width: 1024px) { .rail-section { padding-block: var(--sp-14); } }

.rail-section--soft { background: var(--bg-soft); }

.rail-section__head {
  display: flex;
  align-items: end;
  gap: var(--sp-4);
  margin-block-end: var(--sp-5);
}

.rail-section__nav {
  display: none;
  gap: var(--sp-2);
  margin-inline-start: auto;
}

@media (min-width: 1024px) {
  .rail-section__nav { display: flex; }
}

.rail {
  position: relative;
  min-inline-size: 0;
}

.rail__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(72vw, 1fr);
  gap: var(--sp-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-inline: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  scroll-padding-inline: var(--sp-5);
  padding-block-end: var(--sp-2);
  /* bleed to the viewport edges so cards run off-screen like an app */
  margin-inline: calc(var(--sp-5) * -1);
  padding-inline: var(--sp-5);
}

.rail__track::-webkit-scrollbar { display: none; }

@media (min-width: 560px)  { .rail__track { grid-auto-columns: minmax(280px, 1fr); } }
@media (min-width: 768px)  { .rail__track { margin-inline: calc(var(--sp-8) * -1); padding-inline: var(--sp-8); scroll-padding-inline: var(--sp-8); } }
@media (min-width: 1024px) { .rail__track { grid-auto-columns: minmax(300px, 1fr); gap: var(--sp-6); margin-inline: 0; padding-inline: 0; scroll-padding-inline: 0; } }

.rail__item {
  scroll-snap-align: start;
  min-inline-size: 0;
}

.rail--narrow .rail__track { grid-auto-columns: minmax(160px, 1fr); }
.rail--wide   .rail__track { grid-auto-columns: minmax(86vw, 1fr); }

@media (min-width: 1024px) {
  .rail--narrow .rail__track { grid-auto-columns: minmax(190px, 1fr); }
  .rail--wide   .rail__track { grid-auto-columns: minmax(460px, 1fr); }
}

.rail__btn {
  display: inline-grid;
  place-items: center;
  inline-size: 40px;
  block-size: 40px;
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  transition: border-color var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease), opacity var(--dur-2) var(--ease);
}

.rail__btn:hover { border-color: var(--brand); color: var(--brand-text); }

.rail__btn:disabled,
.rail__btn.is-disabled { opacity: .35; pointer-events: none; }

.rail__dots {
  display: flex;
  justify-content: center;
  gap: var(--sp-2);
  margin-block-start: var(--sp-4);
}

@media (min-width: 1024px) { .rail__dots { display: none; } }

.rail__dot {
  inline-size: 6px;
  block-size: 6px;
  padding: 0;
  border: 0;
  border-radius: var(--r-full);
  background: var(--line-2);
  cursor: pointer;
  transition: inline-size var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease);
}

.rail__dot.is-active { inline-size: 20px; background: var(--brand); }

/* edge fades on desktop */
@media (min-width: 1024px) {
  .rail--fade::before,
  .rail--fade::after {
    content: "";
    position: absolute;
    inset-block: 0;
    inline-size: var(--sp-12);
    pointer-events: none;
    z-index: 1;
    transition: opacity var(--dur-2) var(--ease);
  }
  /* Fade only the edge that actually has content behind it. app.js sets these
     from the rail's scroll position. */
  .rail--fade.is-at-start::before { opacity: 0; }
  .rail--fade.is-at-end::after { opacity: 0; }
  .rail--fade::before {
    inset-inline-start: 0;
    background: linear-gradient(to right, var(--bg), transparent);
  }
  .rail--fade::after {
    inset-inline-end: 0;
    background: linear-gradient(to left, var(--bg), transparent);
  }
  .rail-section--soft .rail--fade::before { background: linear-gradient(to right, var(--bg-soft), transparent); }
  .rail-section--soft .rail--fade::after  { background: linear-gradient(to left,  var(--bg-soft), transparent); }
}


/* ==========================================================================
   19  UTILITY LAYOUT
   ========================================================================== */

/* --- sticky add-to-cart (mobile PDP) ------------------------------------- */

.sticky-atc {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: calc(var(--z-sticky) + 1);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  padding-block-end: calc(var(--sp-3) + var(--safe-b));
  background: color-mix(in oklab, var(--surface) 92%, transparent);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-block-start: 1px solid var(--line);
  box-shadow: var(--sh-3);
  /* Hidden = fully off-screen. translateY(110%) only moved it 80px, but from
     1024px up the bar floats var(--sp-5) above the edge, so a 13px strip of it
     (and its shadow) peeked over the Add to bag button on every PDP load
     (Sep 2026 audit). 100% + 40px clears the offset and the shadow; the
     delayed visibility also takes its buttons out of the tab order. */
  transform: translateY(calc(100% + var(--sp-10)));
  visibility: hidden;
  transition: transform var(--dur-3) var(--ease), opacity var(--dur-2) var(--ease), visibility 0s linear var(--dur-3);
}

@supports not (backdrop-filter: blur(1px)) {
  .sticky-atc { background: var(--surface); }
}

.sticky-atc.is-visible { transform: none; visibility: visible; transition-delay: 0s; }

/* when both exist on mobile the ATC bar sits on top of the tab bar.
   The :has() line is the one that matches today: the tab bar is rendered
   BEFORE <main> (so the ~ sibling form never matches) and .has-sticky-atc is
   on <main>, not <body>. With neither matching, the tab bar stayed up under
   the ATC bar and its raised Search button poked out above it on every PDP
   scroll at 390 (Sep 2026 audit). */
@media (max-width: 1023.98px) {
  .sticky-atc.is-visible ~ .tabbar,
  body.has-sticky-atc .tabbar,
  body:has(.sticky-atc.is-visible) .tabbar { transform: translateY(100%); opacity: 0; pointer-events: none; }
}

@media (min-width: 1024px) {
  .sticky-atc {
    inset-inline: 50%;
    translate: -50% 0;
    inline-size: min(var(--container), calc(100vw - var(--sp-10)));
    inset-block-end: var(--sp-5);
    border: 1px solid var(--line);
    border-radius: var(--r-full);
    padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-5);
  }
}

.sticky-atc__media {
  inline-size: 44px;
  block-size: 44px;
  flex: none;
  border-radius: var(--r-sm);
  object-fit: cover;
  background: var(--surface-2);
  display: none;
}

@media (min-width: 560px) { .sticky-atc__media { display: block; } }

.sticky-atc__info { min-inline-size: 0; flex: 1 1 auto; display: grid; gap: 2px; }

.sticky-atc__name {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sticky-atc__variant {
  font-size: var(--fs-xs);
  color: var(--ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sticky-atc__price {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  font-size: var(--fs-lg);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  white-space: nowrap;
}

.sticky-atc__price del { font-size: var(--fs-sm); font-weight: 400; color: var(--ink-3); }

.sticky-atc__actions { display: flex; align-items: center; gap: var(--sp-2); flex: none; }

@media (max-width: 559.98px) {
  .sticky-atc__actions { flex: 1 1 auto; }
  .sticky-atc__actions > .btn { flex: 1 1 auto; }
  .sticky-atc__info { display: none; }
  .sticky-atc__price { font-size: var(--fs-base); }
}

/* --- filter bar ---------------------------------------------------------- */

.filter-bar {
  position: sticky;
  /* Follows the header instead of a fixed 60px (Sep 2026 audit). The header
     is 118px on desktop, so while it showed it covered the bar completely,
     and once it hid on scroll-down the bar stayed 60px down with the results
     sliding through the gap above it. --header-h-actual is measured by
     app.js; with the header hidden the bar docks at the very top. */
  inset-block-start: var(--header-h-actual, var(--header-h-sm));
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding-block: var(--sp-3);
  background: var(--bg);
  border-block-end: 1px solid var(--line);
  transition: box-shadow var(--dur-2) var(--ease), inset-block-start var(--dur-3) var(--ease);
}
html:has(.site-header.is-hidden) .filter-bar { inset-block-start: 0; }

.filter-bar.is-stuck { box-shadow: var(--sh-1); }

.filter-bar__scroll {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex: 1 1 auto;
  min-inline-size: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-inline: contain;
  margin-inline: calc(var(--sp-5) * -1);
  padding-inline: var(--sp-5);
  /* The containing block for the chips' visually-hidden checkboxes. Without
     it they resolved against the sticky .filter-bar, escaped this scroller's
     clipping, and widened /search to 765px at 390: the phone page could be
     panned sideways and the fixed tab bar was laid out 765px wide. */
  position: relative;
}

.filter-bar__scroll::-webkit-scrollbar { display: none; }

@media (min-width: 768px) {
  .filter-bar__scroll { margin-inline: 0; padding-inline: 0; }
}

.filter-bar__group { display: flex; align-items: center; gap: var(--sp-2); flex: none; }

.filter-bar__spacer { flex: 1 1 auto; }

.filter-bar__count {
  font-size: var(--fs-sm);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex: none;
}

.filter-bar__clear {
  border: 0;
  background: transparent;
  color: var(--danger);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  flex: none;
}

@media (min-width: 1024px) {
  .filter-bar__mobile-only { display: none; }
}

/* --- toolbar ------------------------------------------------------------- */

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding-block: var(--sp-3);
}

.toolbar--bordered {
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
}

.toolbar__group { display: flex; align-items: center; gap: var(--sp-2); }

.toolbar__spacer { flex: 1 1 auto; }

.toolbar__label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.toolbar__view {
  display: none;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
}

@media (min-width: 1024px) { .toolbar__view { display: flex; } }

.toolbar__view-btn {
  inline-size: 34px;
  block-size: 30px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}

.toolbar__view-btn.is-active { background: var(--surface); color: var(--brand-text); box-shadow: var(--sh-1); }

/* --- backdrop ------------------------------------------------------------ */

.backdrop {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-drawer) - 1);
  background: var(--overlay);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-3) var(--ease), visibility 0s linear var(--dur-3);
}

.backdrop.is-open {
  opacity: .6;
  visibility: visible;
  transition-delay: 0s;
}

.backdrop--blur { backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.backdrop--modal { z-index: calc(var(--z-modal) - 1); }

/* --- body scroll lock ---------------------------------------------------- */

.scroll-lock {
  overflow: hidden;
  /* JS sets --scroll-lock-gap to the scrollbar width to prevent reflow */
  padding-inline-end: var(--scroll-lock-gap, 0px);
  touch-action: none;
  overscroll-behavior: none;
}

@supports (-webkit-touch-callout: none) {
  .scroll-lock { position: fixed; inline-size: 100%; }
}

/* --- page reading progress ----------------------------------------------- */

.page-progress {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: calc(var(--z-header) + 2);
  block-size: 3px;
  background: transparent;
  pointer-events: none;
}

.page-progress__bar {
  block-size: 100%;
  inline-size: 0%;
  border-radius: 0 var(--r-full) var(--r-full) 0;
  background: linear-gradient(90deg, var(--brand), var(--accent-2));
  transform-origin: 0 50%;
  transition: inline-size var(--dur-1) linear;
}

.page-progress--sticky-below {
  inset-block-start: var(--header-h-sm);
}

/* --- floating action button ---------------------------------------------- */

.fab {
  position: fixed;
  inset-block-end: calc(var(--tabbar-h) + var(--safe-b) + var(--sp-4));
  inset-inline-end: var(--sp-4);
  z-index: var(--z-sticky);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-block-size: 52px;
  padding-inline: var(--sp-4);
  border: 0;
  border-radius: var(--r-full);
  background: var(--brand);
  color: var(--brand-ink);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: 700;
  box-shadow: var(--sh-brand), var(--sh-3);
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px) scale(.9);
  pointer-events: none;
  transition: opacity var(--dur-2) var(--ease), transform var(--dur-3) var(--ease-out-back);
}

.fab.is-visible { opacity: 1; transform: none; pointer-events: auto; }
/* on a phone the back-to-top button sits on full-width buttons and 20px gutters — it collided with content on every page */
@media (max-width: 1023px) { .fab[data-back-to-top] { display: none; } }

.fab--icon { inline-size: 52px; padding-inline: 0; justify-content: center; }

.fab--start { inset-inline-end: auto; inset-inline-start: var(--sp-4); }

.fab--ghost {
  background: color-mix(in oklab, var(--surface) 90%, transparent);
  color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: var(--sh-3);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

@media (min-width: 1024px) {
  .fab { inset-block-end: var(--sp-6); inset-inline-end: var(--sp-6); }
}

body.scroll-lock .fab { opacity: 0; pointer-events: none; }


/* ==========================================================================
   20  REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .site-header,
  .mega,
  .mega__promo-media,
  .mobile-nav__panel,
  .mobile-nav__scrim,
  .nav-acc__panel,
  .nav-acc__chev,
  .footer-col__panel,
  .footer-col__chev,
  .checkout-summary__panel,
  .checkout-summary__chev,
  .tabbar,
  .tabbar__icon,
  .tabbar__indicator,
  .search-overlay__panel,
  .search-overlay__scrim,
  .sticky-atc,
  .shop-sidebar,
  .fab,
  .brand__mark,
  .announce__item,
  .rail__dot,
  .header-action__badge,
  .theme-toggle .icon {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
  }

  .site-header.is-hidden { transform: none; }

  .mega__promo:hover .mega__promo-media,
  .social-row__link:hover,
  .footer-apps__badge:hover { transform: none; }

  .rail__track { scroll-behavior: auto; scroll-snap-type: none; }
}


/* ==========================================================================
   21  PRINT (order confirmation / invoice)
   ========================================================================== */

@media print {
  .announce,
  .site-header,
  .mega,
  .mega-backdrop,
  .mobile-nav,
  .tabbar,
  .search-overlay,
  .site-footer,
  .sticky-atc,
  .fab,
  .backdrop,
  .page-progress,
  .filter-bar,
  .toolbar,
  .rail-section__nav,
  .rail__dots,
  .shop-layout__sidebar,
  .account-layout__side,
  .blog-layout__aside,
  .no-print {
    display: none !important;
  }

  .site-main { padding-block-end: 0 !important; }

  .container,
  .container--wide,
  .container--narrow {
    max-inline-size: none;
    padding-inline: 0;
  }

  .shop-layout,
  .account-layout,
  .checkout-layout,
  .blog-layout,
  .auth-layout {
    display: block;
    padding-block: 0;
  }

  .account-panel,
  .checkout-summary {
    border: 1px solid var(--line-2);
    border-radius: 0;
    box-shadow: none;
    padding: 12pt;
    break-inside: avoid;
  }

  .checkout-summary__panel,
  .checkout-summary__inner,
  .footer-col__panel { grid-template-rows: 1fr; overflow: visible; }

  .page-head {
    background: none;
    border-block-end: 1px solid var(--line-2);
    padding-block: 0 12pt;
    margin-block-end: 12pt;
  }

  .page-head__title { font-size: 20pt; }

  .print-only { display: revert !important; }

  .print-header {
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    gap: 12pt;
    padding-block-end: 12pt;
    border-block-end: 2px solid var(--ink);
    margin-block-end: 16pt;
  }

  .print-footer {
    display: block !important;
    padding-block-start: 12pt;
    border-block-start: 1px solid var(--line-2);
    margin-block-start: 16pt;
    font-size: 9pt;
  }

  .invoice-table { inline-size: 100%; border-collapse: collapse; }
  .invoice-table th,
  .invoice-table td {
    padding: 6pt 4pt;
    border-block-end: 1px solid var(--line);
    text-align: start;
  }
  .invoice-table tfoot td { font-weight: 700; border-block-end: 0; }

  tr, .grid--products > *, .account-panel { break-inside: avoid; }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 8pt;
    color: var(--ink-3);
  }
}

.print-only,
.print-header,
.print-footer { display: none; }


/* ══ UI AUDIT FIXES (layout) ═══════════════════════════════════════════════ */

/* #16 · .account-panel__head wraps on a phone, but .account-panel__actions kept
   `margin-inline-start: auto`, so the controls dropped onto their own line and
   then sat hard right, detached from the heading they belong to. */
@media (max-width: 639.98px) {
  .account-panel__actions { margin-inline-start: 0; inline-size: 100%; }
}

/* #34 · the search overlay's idle sections had exactly 0px between them — the
   last chip touched the next heading. .search-overlay__body lays out its
   children, but the idle wrapper is a single child, so the gap never applied. */
.search-overlay__body > [data-search-idle] {
  display: grid;
  gap: var(--sp-8);
}

/* #35 · "Follow along" sat hard against the chip grid above it: the u-mt-4
   utility is defined inside :where() and lost to the component rule. */
.mobile-nav__section-title + *,
.mobile-nav .mobile-nav__section-title { margin-block-start: var(--sp-6); }

/* #48 · a horizontally scrollable container is its own keyboard tab stop in
   Chrome, and .rail__track carried no focus style, so tabbing through a shelf
   landed on an invisible stop. */
.rail__track:focus-visible {
  outline: var(--ring-w) solid var(--focus-ink);
  outline-offset: -3px;
}

/* #50 · the shop toolbar's grid/list toggle had only a base and an .is-active
   rule — hovering an inactive button did nothing. */
.toolbar__view-btn:not(.is-active):hover { background: var(--surface-3); color: var(--ink); }


/* #12 · the three coupon cards stretch to a common height but their CTA cluster
   was not pinned to the card bottom, so the primary buttons sat at three
   different heights across the row. */
.offer-card,
[data-page="offers"] .offer-card { display: flex; flex-direction: column; }
.offer-card > .cluster:last-child,
[data-page="offers"] .offer-card > .cluster:last-child { margin-block-start: auto; }

/* #37/#47 · the .rt-facts label column is `max-content`, pinned at 97px at every
   width, so the value column was left too narrow and values like
   "UPI · aarav@okhdfcbank" wrapped with an orphan. Cap the label instead. */
[data-page="account-returns"] .rt-facts,
[data-page="home-v2"] .rt-facts {
  grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
}
[data-page="account-returns"] .rt-facts > dt { max-inline-size: 11ch; }

/* #42 · .hm-look__cap is bottom-anchored, so a 1-line vs 2-line product name
   pushed the "LOOK 01" eyebrow off a common baseline across the row. Give the
   name a fixed two-line box so every eyebrow starts level. */
[data-page="home-fashion"] .hm-look__name {
  min-block-size: calc(2 * var(--lh-snug) * 1em);
}
