/* ==========================================================================
   LIVSDO — Shared components
   Header, drawers, footer, buttons, forms, product card, accordion, states.
   ========================================================================== */

/* ==========================================================================
   Buttons
   Four roles only: primary (navy), accent (blue), ghost (outline), quiet (link).
   Square by design — radius is spent on pills and chips, not on every control.
   ========================================================================== */

.btn-ls {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  border: 1px solid transparent;
  border-radius: var(--radius-0);
  padding: 0.95rem 1.75rem;
  font-family: var(--font-body);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  line-height: 1;
  text-align: center;
  cursor: pointer;
  transition: background-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease);
}
.btn-ls:disabled,
.btn-ls[aria-disabled='true'] { opacity: 0.45; cursor: not-allowed; }

.btn-ls--primary { background: var(--c-navy); color: var(--c-white); }
.btn-ls--primary:hover:not(:disabled) { background: var(--c-navy-deep); color: var(--c-white); }

.btn-ls--accent { background: var(--c-blue); color: var(--c-white); }
.btn-ls--accent:hover:not(:disabled) { background: var(--c-blue-deep); color: var(--c-white); }

/* The one place lime carries a whole control: the add-to-bag action, where it
   should be the single loudest thing on the page. 11.26:1 on navy. */
.btn-ls--lime { background: var(--c-lime); color: var(--c-navy); }
.btn-ls--lime:hover:not(:disabled) { background: #A9DE1B; color: var(--c-navy); }

.btn-ls--ghost { background: transparent; color: var(--c-ink); border-color: var(--c-navy); }
.btn-ls--ghost:hover:not(:disabled) { background: var(--c-navy); color: var(--c-white); }

.btn-ls--on-dark { background: transparent; color: var(--c-white); border-color: rgba(255,255,255,0.45); }
.btn-ls--on-dark:hover:not(:disabled) { background: var(--c-white); color: var(--c-navy); }

.btn-ls--block { display: flex; width: 100%; }
.btn-ls--sm { padding: 0.7rem 1.15rem; font-size: var(--fs-2xs); }

/* Text link with a rule that grows on hover. */
.link-rule {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink);
  padding-bottom: 3px;
  border-bottom: 1px solid currentColor;
}
.link-rule:hover { color: var(--c-blue); }
.link-rule .arw { transition: transform var(--t-fast) var(--ease); }
.link-rule:hover .arw { transform: translateX(3px); }

/* Icon-only control (header utilities, gallery arrows, drawer close). */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: transparent;
  border: 0;
  color: var(--c-ink);
  position: relative;
  transition: color var(--t-fast) var(--ease);
}
.icon-btn:hover { color: var(--c-blue); }
.icon-btn__count {
  position: absolute;
  top: 3px;
  right: 1px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--c-blue);
  color: var(--c-white);
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.icon-btn__count[data-count='0'] { display: none; }

/* ==========================================================================
   Section heading
   ========================================================================== */

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-5);
  margin-bottom: var(--s-6);
}
.section-head__text { min-width: 0; }
.section-head__rule {
  width: 40px;
  height: 3px;
  background: var(--c-lime);
  margin-bottom: var(--s-3);
}
/* Major section headings sit in the display layer. */
.section-head__title {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  font-size: var(--fs-h2);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-display);
}
.section-head__sub {
  margin-top: var(--s-3);
  font-size: var(--fs-sm);
  color: var(--c-muted);
  max-width: 52ch;
}
.section-head__action { flex: none; }

@media (max-width: 575.98px) {
  .section-head { flex-direction: column; align-items: flex-start; gap: var(--s-4); }
}

/* ==========================================================================
   Breadcrumbs
   ========================================================================== */

.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--c-muted);
  padding-block: var(--s-5) 0;
}
.crumbs a:hover { color: var(--c-blue); }
.crumbs .sep { color: var(--c-muted-soft); }
.crumbs [aria-current='page'] { color: var(--c-ink); font-weight: 600; }

/* ==========================================================================
   Header
   Sticky, and condenses after the first scroll step. The announcement bar
   scrolls away with the page; only the bar itself stays pinned.
   ========================================================================== */

.announce {
  background: var(--c-navy);
  color: var(--c-on-dark);
  text-align: center;
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  padding: var(--s-2) var(--gutter);
}
.announce a { color: var(--c-lime); text-decoration: underline; text-underline-offset: 3px; }
.announce a:hover { color: var(--c-lime); opacity: 0.8; }

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--c-white);
  border-bottom: var(--border);
  transition: box-shadow var(--t-med) var(--ease);
}
.site-header.is-stuck { box-shadow: var(--shadow-raise); }

.site-header__bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s-4);
  height: 84px;
  transition: height var(--t-med) var(--ease);
}
.site-header.is-stuck .site-header__bar { height: 68px; }

.site-header__left  { display: flex; align-items: center; gap: var(--s-6); min-width: 0; }
.site-header__brand { justify-self: center; }
.site-header__right { display: flex; align-items: center; gap: var(--s-1); justify-self: end; }

.brand-logo img {
  height: 22px;
  width: auto;
  transition: height var(--t-med) var(--ease);
}
.site-header.is-stuck .brand-logo img { height: 19px; }

.nav-primary { display: flex; align-items: center; gap: var(--s-6); }
.nav-primary__link {
  position: relative;
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--c-ink);
  padding-block: var(--s-2);
  white-space: nowrap;
}
.nav-primary__link::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1.5px;
  background: var(--c-blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-med) var(--ease);
}
.nav-primary__link:hover::after,
.nav-primary__link[aria-current='page']::after { transform: scaleX(1); }
.nav-primary__link[aria-current='page'] { color: var(--c-blue); }

/* ---- Long menus: nav on its own row --------------------------------------
   Added by ui.fitPrimaryNav() when the links are wider than the left column
   (seven categories side by side are). Logo and icons keep the top row; the
   menu moves to a centred row beneath, so nothing runs under the logo. */
@media (min-width: 992px) {
  .site-header--stacked .site-header__bar {
    grid-template-rows: 72px auto;
    height: auto;
    row-gap: 0;
  }
  .site-header--stacked.is-stuck .site-header__bar { height: auto; grid-template-rows: 58px auto; }
  .site-header--stacked .site-header__left { display: contents; }
  .site-header--stacked .site-header__brand { grid-column: 2; grid-row: 1; }
  .site-header--stacked .site-header__right { grid-column: 3; grid-row: 1; }
  .site-header--stacked .nav-primary {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-content: center;
    flex-wrap: wrap;
    column-gap: var(--s-7);
    row-gap: var(--s-2);
    padding-bottom: var(--s-3);
  }
}

/* ---- Dropdowns ---------------------------------------------------------
   A top-level menu item with children (Appearance → Menus) opens a panel
   on hover or keyboard focus. CSS only: :focus-within keeps it open while
   focus is anywhere inside, and a "#" parent is a <button>, which takes
   focus on a tap so touch screens open it too. */
.nav-primary__item { position: relative; display: flex; align-items: center; }
button.nav-primary__link {
  background: none;
  border: 0;
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--c-ink);
  cursor: pointer;
}
.nav-primary__link--parent { display: inline-flex; align-items: center; gap: 7px; }
.nav-primary__link--parent::before {
  content: '';
  order: 2;
  width: 6px; height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform var(--t-fast) var(--ease);
}
.nav-primary__item:hover .nav-primary__link--parent::after,
.nav-primary__item:focus-within .nav-primary__link--parent::after { transform: scaleX(1); }
.nav-primary__item:hover .nav-primary__link--parent::before,
.nav-primary__item:focus-within .nav-primary__link--parent::before { transform: translateY(1px) rotate(225deg); }

.nav-primary__menu {
  position: absolute;
  top: 100%;
  left: calc(var(--s-5) * -1);
  z-index: calc(var(--z-header) + 1);
  min-width: 240px;
  padding: var(--s-3) 0;
  margin-top: var(--s-2);
  background: var(--c-white);
  border: var(--border);
  box-shadow: var(--shadow-raise);
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease), visibility 0s linear var(--t-fast);
}
/* A bridge over the gap between the link and the panel, so the pointer
   crossing it does not close the menu. */
.nav-primary__menu::before { content: ''; position: absolute; left: 0; right: 0; bottom: 100%; height: var(--s-4); }
.nav-primary__item:hover .nav-primary__menu,
.nav-primary__item:focus-within .nav-primary__menu {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}
.nav-primary__sublink {
  display: block;
  padding: var(--s-2) var(--s-5);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--c-ink);
  white-space: nowrap;
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.nav-primary__sublink:hover,
.nav-primary__sublink:focus-visible { background: var(--c-tint); color: var(--c-blue); }
.nav-primary__sublink[aria-current='page'] { color: var(--c-blue); }

.nav-toggle { display: none; }

@media (max-width: 991.98px) {
  .nav-primary { display: none; }
  .nav-toggle { display: inline-flex; }
  .site-header__bar { height: 64px; }
  .site-header.is-stuck .site-header__bar { height: 60px; }
}

/* ==========================================================================
   Overlay + drawers (mobile nav, cart, search)
   One overlay element serves all three.
   ========================================================================== */

.overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background: rgba(2, 24, 77, 0.42);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-med) var(--ease);
}
.overlay.is-open { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  z-index: var(--z-drawer);
  width: min(420px, 90vw);
  background: var(--c-white);
  display: flex;
  flex-direction: column;
  transition: transform var(--t-med) var(--ease);
  will-change: transform;
}
.drawer--left  { left: 0;  transform: translateX(-100%); }
.drawer--right { right: 0; transform: translateX(100%); }
.drawer.is-open { transform: translateX(0); }
.drawer[hidden] { display: flex !important; }  /* animate instead of vanishing */
.drawer:not(.is-open) { visibility: hidden; transition: transform var(--t-med) var(--ease), visibility 0s linear var(--t-med); }
.drawer.is-open { visibility: visible; transition: transform var(--t-med) var(--ease), visibility 0s; }

/* ---- Empty state inside a drawer ------------------------------------------
   The page-level empty state is a bordered, tinted panel, which reads correctly
   in the middle of a wide page. Inside a 420px drawer that already has its own
   padding it becomes a box inside a box, floating against the top edge with the
   rest of the drawer blank beneath it. In here it is plain, centred in the space
   available, and its buttons run the full width. */
.drawer .state {
  border: 0;
  background: none;
  padding: var(--s-5) 0;
}
.drawer__body:has(.state) {
  display: grid;
  align-content: center;
}
.drawer .state__action {
  flex-direction: column;
  align-items: stretch;
  gap: var(--s-2);
}
.drawer .state__action .btn-ls { width: 100%; }

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-5);
  border-bottom: var(--border);
  flex: none;
}
.drawer__title { font-size: var(--fs-2xs); font-weight: 600; letter-spacing: var(--ls-label); text-transform: uppercase; }
.drawer__body { flex: 1 1 auto; overflow-y: auto; overscroll-behavior: contain; padding: var(--s-5); }
.drawer__foot { flex: none; border-top: var(--border); padding: var(--s-5); background: var(--c-white); }

/* Mobile nav list */
.nav-drawer__list { list-style: none; }
.nav-drawer__list a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--s-4) 0;
  border-bottom: var(--border);
  font-size: var(--fs-lg);
  font-weight: 500;
}
/* A group in the drawer: its heading, then its children indented beneath. */
.nav-drawer__heading {
  display: block;
  padding: var(--s-4) 0 var(--s-2);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-muted);
}
.nav-drawer__sub { list-style: none; padding-left: var(--s-4); border-bottom: var(--border); }
.nav-drawer__sub a { font-size: var(--fs-base); padding: var(--s-3) 0; }
.nav-drawer__sub li:last-child a { border-bottom: 0; }

.nav-drawer__meta { margin-top: var(--s-6); display: flex; flex-direction: column; gap: var(--s-3); }
.nav-drawer__meta a { font-size: var(--fs-sm); color: var(--c-muted); }

/* Cart lines */
.cart-line {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  gap: var(--s-4);
  padding-block: var(--s-4);
  border-bottom: var(--border);
}
.cart-line__media { width: 72px; }
.cart-line__name { font-size: var(--fs-sm); font-weight: 600; line-height: 1.4; }
.cart-line__variant { font-size: var(--fs-xs); color: var(--c-muted); margin-top: 2px; }
.cart-line__price { font-size: var(--fs-sm); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cart-line__controls { display: flex; align-items: center; gap: var(--s-4); margin-top: var(--s-3); }
.cart-line__remove {
  background: none; border: 0; padding: 0;
  font-size: var(--fs-xs); color: var(--c-muted);
  text-decoration: underline; text-underline-offset: 3px;
}
.cart-line__remove:hover { color: var(--c-danger); }

.cart-summary { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--s-4); }
.cart-summary__label { font-size: var(--fs-2xs); font-weight: 600; letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--c-muted); }
.cart-summary__value { font-size: var(--fs-h3); font-weight: 600; font-variant-numeric: tabular-nums; }
.cart-note { font-size: var(--fs-xs); color: var(--c-muted); margin-top: var(--s-3); text-align: center; }

/* Quantity stepper */
.qty {
  display: inline-flex;
  align-items: center;
  border: var(--border);
  height: 40px;
}
.qty__btn {
  width: 36px; height: 100%;
  background: none; border: 0;
  color: var(--c-ink);
  font-size: var(--fs-lg);
  line-height: 1;
  display: grid; place-items: center;
  transition: background-color var(--t-fast) var(--ease);
}
.qty__btn:hover:not(:disabled) { background: var(--c-tint); }
.qty__btn:disabled { color: var(--c-muted-soft); cursor: not-allowed; }
.qty__input {
  width: 44px; height: 100%;
  border: 0;
  border-inline: var(--border);
  text-align: center;
  font-size: var(--fs-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--c-ink);
  background: var(--c-white);
  -moz-appearance: textfield;
}
.qty__input::-webkit-outer-spin-button,
.qty__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.qty--sm { height: 32px; }
.qty--sm .qty__btn { width: 30px; }
.qty--sm .qty__input { width: 36px; font-size: var(--fs-xs); }

/* Search drawer */
.search-panel__form { display: flex; gap: var(--s-2); }
.search-panel__input {
  flex: 1;
  border: 0;
  border-bottom: var(--border-strong);
  padding: var(--s-3) 0;
  font-size: var(--fs-h3);
  font-family: var(--font-display);
  color: var(--c-ink);
  background: transparent;
}
.search-panel__input::placeholder { color: var(--c-muted-soft); }
.search-panel__input:focus { outline: none; border-bottom-color: var(--c-blue); }
.search-results { list-style: none; margin-top: var(--s-5); }
.search-results li + li { margin-top: var(--s-1); }
.search-results a {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: var(--s-4);
  align-items: center;
  padding: var(--s-2);
  transition: background-color var(--t-fast) var(--ease);
}
.search-results a:hover { background: var(--c-tint); }
.search-results__name { font-size: var(--fs-sm); font-weight: 600; }
.search-results__cat { font-size: var(--fs-xs); color: var(--c-muted); }
.search-results__price { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Product card
   Primary image swaps to the styled/detail shot on hover. No badges, no
   swatches, no quick-add, no ratings — name and price only.
   ========================================================================== */

.pcard { display: block; position: relative; }
.pcard__media { position: relative; overflow: hidden; background: var(--c-tint); }
.pcard__img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: opacity var(--t-med) var(--ease), transform var(--t-slow) var(--ease);
}
.pcard__img--hover {
  position: absolute;
  inset: 0;
  opacity: 0;
}
/* Hover swap on pointer devices only — on touch there is no hover state to
   enter or leave, and a card stuck on its second image reads as a bug. */
@media (hover: hover) and (pointer: fine) {
  .pcard:hover .pcard__img--primary { opacity: 0; }
  .pcard:hover .pcard__img--hover { opacity: 1; }
  /* Products with no second shot get a gentle scale instead, so every card
     still answers the pointer. */
  .pcard:hover .pcard__img--solo { transform: scale(1.035); }
}
.pcard:focus-visible { outline-offset: 4px; }

.pcard__body {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-top: var(--s-4);
}
/* Name and price share a size and weight so the pair reads as one line of
   information rather than as a label with a shouted number after it. */
.pcard__name {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--c-ink);
  line-height: 1.45;
}
.pcard__price {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pcard__was {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 400;
  color: var(--c-muted);
  text-decoration: line-through;
}
.pcard:hover .pcard__name { color: var(--c-blue); }

/* Tinted section band. Lives here rather than in home.css because the framed
   card below depends on it, and framed rows appear on pages that do not load
   the homepage stylesheet. */
.band-tint { background: var(--c-tint); }

/* --- Framed variant -------------------------------------------------------
   Opt-in via ui.productCard(p, { framed: true }). Used on the homepage product
   rows, which sit on the tinted band.

   Deliberately NOT the default: the collection grid follows the borderless
   editorial pattern the brief specifies for it — image, name, price, nothing
   else — and putting every product in a bordered card would fight that. The
   frame exists to solve a different problem, the same one the category tiles
   have: on the tinted band a white card gives product cut-outs shot on white an
   edge to sit on, so they and the lifestyle shots read as one set. */
.pcard--framed {
  background: var(--c-white);
  border: 1px solid var(--c-hairline);
  transition: border-color var(--t-med) var(--ease);
}
.pcard--framed:hover { border-color: var(--c-navy); }
.pcard--framed:focus-visible { outline-offset: 2px; }

.pcard--framed .pcard__body {
  position: relative;
  align-items: center;
  padding: var(--s-4);
  border-top: 1px solid var(--c-hairline);
  margin-top: auto;
  /* Room for a two-line price block, so a product with a compare-at price and
     one without end up the same height. Without this, a single sale price in a
     row makes that whole row taller than the rows around it.

     Derived from the type scale rather than hard-coded: padding, plus a price
     line, plus a struck-through compare-at line. A fixed rem value silently
     stops matching the moment the type scale is adjusted. */
  min-height: calc(
    (var(--s-4) * 2) +
    (var(--fs-sm) * var(--lh-body)) +
    (var(--fs-xs) * var(--lh-body)) +
    1px   /* slack: line boxes round to whole pixels, the calc does not */
  );
}
/* Lime keyline drawing across the label, matching the category tiles. */
.pcard--framed .pcard__body::before {
  content: '';
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 2px;
  background: var(--c-lime);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-med) var(--ease);
}
.pcard--framed:hover .pcard__body::before,
.pcard--framed:focus-visible .pcard__body::before { transform: scaleX(1); }

.pcard--framed .pcard__name {
  font-family: var(--font-display);
  font-weight: var(--fw-display);
  font-size: var(--fs-base);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-display);
}
.pcard--framed .pcard__price { font-weight: 600; }

@media (max-width: 575.98px) {
  .pcard--framed .pcard__body { padding: var(--s-3); }
  .pcard--framed .pcard__name { font-size: var(--fs-sm); }
}

/* Ranked variant — used on Best Sellers, where the position is the point. */
.pcard__rank {
  position: absolute;
  top: var(--s-3);
  left: var(--s-3);
  z-index: 2;
  background: var(--c-white);
  color: var(--c-blue);
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 5px 9px;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Product grid
   ========================================================================== */

.pgrid {
  display: grid;
  gap: var(--s-6) var(--s-5);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 768px)  { .pgrid--4 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 992px)  { .pgrid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* Collection grid tops out at 3 across — wider cards, more breathing room. */
@media (min-width: 768px)  { .pgrid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 992px)  { .pgrid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-8) var(--s-6); } }

/* ==========================================================================
   Accordion
   Header is a real <button> so it is keyboard operable. Height animates via
   grid-template-rows, which needs no max-height guess and so cannot clip.
   ========================================================================== */

.acc { border-top: var(--border); }
.acc:last-of-type { border-bottom: var(--border); }

.acc__btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  width: 100%;
  padding: var(--s-4) 0;
  background: none;
  border: 0;
  text-align: left;
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink);
}
.acc__btn:hover { color: var(--c-blue); }
.acc__icon {
  flex: none;
  position: relative;
  width: 12px; height: 12px;
  color: var(--c-blue);
}
.acc__icon::before,
.acc__icon::after {
  content: '';
  position: absolute;
  background: currentColor;
  transition: transform var(--t-med) var(--ease), opacity var(--t-med) var(--ease);
}
.acc__icon::before { top: 50%; left: 0; width: 100%; height: 1.5px; margin-top: -0.75px; }
.acc__icon::after  { left: 50%; top: 0; height: 100%; width: 1.5px; margin-left: -0.75px; }
.acc__btn[aria-expanded='true'] .acc__icon::after { transform: scaleY(0); opacity: 0; }

/* Height is measured and set by JS (see setAccordionOpen in core/ui.js), then
   released to `auto` once the transition finishes so the panel can still
   reflow afterwards.
   Deliberately NOT a max-height guess: any panel taller than the guessed
   max-height is silently clipped, which is the usual way this component
   breaks once real copy replaces placeholder copy. */
.acc__panel {
  height: 0;
  overflow: hidden;
  transition: height var(--t-med) var(--ease);
}
.acc__content {
  padding-bottom: var(--s-5);
  font-size: var(--fs-sm);
  color: var(--c-muted);
  line-height: var(--lh-body);
}
.acc__content ul { padding-left: 1.1rem; list-style: disc; }
.acc__content li + li { margin-top: var(--s-2); }
.acc__content dl { display: grid; grid-template-columns: auto 1fr; gap: var(--s-2) var(--s-5); margin: 0; }
.acc__content dt { font-weight: 600; color: var(--c-ink); }
.acc__content dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }

/* FAQ uses the same mechanics with a heavier, sentence-case question. */
.faq__btn { font-size: var(--fs-base); font-weight: 500; letter-spacing: 0; text-transform: none; padding: var(--s-5) 0; }
.faq__btn .acc__icon { width: 14px; height: 14px; }

/* ==========================================================================
   Forms
   ========================================================================== */

.field { display: block; }
.field__label {
  display: block;
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink);
  margin-bottom: var(--s-2);
}
.field__input {
  width: 100%;
  height: 48px;
  padding: 0 var(--s-4);
  border: var(--border-strong);
  border-radius: var(--radius-0);
  background: var(--c-white);
  color: var(--c-ink);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.field__input::placeholder { color: var(--c-muted-soft); }
.field__input:focus {
  outline: none;
  border-color: var(--c-blue);
  box-shadow: 0 0 0 3px rgba(1, 80, 234, 0.16);
}
.field__input[aria-invalid='true'] { border-color: var(--c-danger); }
.field__input[aria-invalid='true']:focus { box-shadow: 0 0 0 3px rgba(192, 38, 55, 0.16); }

.field__msg { display: block; margin-top: var(--s-2); font-size: var(--fs-xs); line-height: 1.5; }
.field__msg--error   { color: var(--c-danger); }
.field__msg--success { color: var(--c-success); }
.field__msg:empty { display: none; }

/* Inline form: input + button joined into one control. */
.inline-form { display: flex; flex-wrap: wrap; gap: 0; }
.inline-form .field__input { flex: 1 1 220px; border-right-width: 0; min-width: 0; }
.inline-form .btn-ls { flex: none; height: 48px; padding-inline: var(--s-5); }
.inline-form .field__input:focus { border-right-width: 1px; margin-right: -1px; }
@media (max-width: 479.98px) {
  .inline-form { flex-direction: column; gap: var(--s-3); }
  .inline-form .field__input { border-right-width: 1px; }
  .inline-form .btn-ls { width: 100%; }
}

/* Selectable option chips (variants, filters) */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 0.55rem 1.1rem;
  border: var(--border);
  border-radius: var(--radius-pill);
  background: var(--c-white);
  color: var(--c-ink);
  font-size: var(--fs-xs);
  font-weight: 500;
  white-space: nowrap;
  transition: background-color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}
.chip:hover { border-color: var(--c-navy); color: var(--c-ink); }
.chip[aria-pressed='true'],
.chip[aria-selected='true'] {
  background: var(--c-navy);
  border-color: var(--c-navy);
  color: var(--c-white);
}
.chip__count { font-size: var(--fs-2xs); opacity: 0.6; font-variant-numeric: tabular-nums; }

/* Native select, restyled to match the chips rather than the OS. */
.select-ls {
  height: 40px;
  padding: 0 2.25rem 0 var(--s-4);
  border: var(--border);
  border-radius: var(--radius-pill);
  background-color: var(--c-white);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%23021F63' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-4) center;
  color: var(--c-ink);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  appearance: none;
  cursor: pointer;
}
.select-ls:focus { outline: none; border-color: var(--c-blue); box-shadow: 0 0 0 3px rgba(1,80,234,0.16); }

/* ==========================================================================
   States: loading, empty, error
   ========================================================================== */

.state {
  text-align: center;
  padding: var(--s-8) var(--s-5);
  border: 1px dashed var(--c-hairline);
  background: var(--c-tint);
}
.state__title { font-size: var(--fs-h3); font-weight: 600; margin-bottom: var(--s-2); }
.state__text { font-size: var(--fs-sm); color: var(--c-muted); max-width: 44ch; margin-inline: auto; }
/* These two belong here, not in pages.css: the cart and wishlist drawers render
   an empty state on EVERY page, including index/collection/product, which do
   not load pages.css. Left there, the icon rendered unstyled and flush left. */
.state__icon {
  display: grid;
  place-items: center;
  width: 56px; height: 56px;
  margin: 0 auto var(--s-4);
  border: var(--border);
  background: var(--c-white);
  color: var(--c-blue);
}
.state__action {
  margin-top: var(--s-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  justify-content: center;
}

/* Skeleton placeholders, sized by the same ratio utilities as the real card so
   swapping one for the other cannot shift the grid. */
.skeleton { background: var(--c-tint-deep); position: relative; overflow: hidden; }
.skeleton::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.65), transparent);
  transform: translateX(-100%);
  animation: sk 1.3s infinite;
}
@keyframes sk { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .skeleton::after { animation: none; } }
.skeleton__line { height: 11px; background: var(--c-tint-deep); margin-top: var(--s-3); }
.skeleton__line--short { width: 40%; }

/* ==========================================================================
   Toast
   ========================================================================== */

.toast-stack {
  position: fixed;
  left: 50%;
  bottom: var(--s-6);
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  width: min(460px, calc(100vw - 2 * var(--gutter)));
  pointer-events: none;
}
.toast {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  background: var(--c-navy);
  color: var(--c-white);
  padding: var(--s-4) var(--s-5);
  font-size: var(--fs-sm);
  box-shadow: var(--shadow-pop);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity var(--t-med) var(--ease), transform var(--t-med) var(--ease);
}
.toast.is-in { opacity: 1; transform: translateY(0); }
.toast__dot { width: 6px; height: 6px; background: var(--c-lime); flex: none; }
.toast--error .toast__dot { background: #FF8A95; }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  background: var(--c-tint);
  border-top: var(--border);
  padding-top: var(--section-y);
}
.site-footer__label {
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-ink);
  margin-bottom: var(--s-4);
}

/* ---- Menu columns ---------------------------------------------------------
   Four grouped link lists. Two across on a phone so the columns do not become
   a single very long stack. */
.footer-menu {
  display: grid;
  gap: var(--s-6) var(--s-5);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding-bottom: var(--s-7);
}
@media (min-width: 992px) {
  .footer-menu { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-7); }
}
.footer-menu__links { list-style: none; display: flex; flex-direction: column; gap: var(--s-3); }
.footer-menu__links a { font-size: var(--fs-sm); color: var(--c-muted); }
.footer-menu__links a:hover { color: var(--c-blue); }

/* ---- Link clouds ----------------------------------------------------------
   Comma-separated inline lists rather than stacked columns, so a long set of
   categories, products and cities stays compact. The separators are marked
   aria-hidden: a screen reader gets the links, not a recital of commas. */
.footer-clouds {
  display: grid;
  gap: var(--s-6) var(--s-7);
  grid-template-columns: minmax(0, 1fr);
  padding-bottom: var(--s-7);
  padding-top: var(--s-7);
  border-top: var(--border);
}
@media (min-width: 768px)  { .footer-clouds { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .footer-clouds { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.footer-cloud__links {
  font-size: var(--fs-sm);
  line-height: 1.9;
  color: var(--c-muted);
}
.footer-cloud__links a { color: var(--c-muted); }
.footer-cloud__links a:hover { color: var(--c-blue); text-decoration: underline; text-underline-offset: 3px; }
.footer-cloud__sep { color: var(--c-muted-soft); }

/* ---- Payments + social ----------------------------------------------------- */

.footer-meta {
  display: grid;
  gap: var(--s-6);
  align-items: start;
  padding-block: var(--s-6);
  border-top: var(--border);
}
@media (min-width: 768px) {
  .footer-meta { grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-7); }
}

/* Method names set as text. Card-scheme logos are trademarked artwork and must
   come from the payment provider's own brand kit — never a look-alike. */
.pay-list { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s-2); }
.pay-list__item {
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 var(--s-3);
  background: var(--c-white);
  border: 1px solid var(--c-hairline);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--c-ink);
  white-space: nowrap;
}

.social-list { list-style: none; display: flex; flex-wrap: wrap; gap: var(--s-3); }
.social-list__link {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--c-white);
  border: 1px solid var(--c-hairline);
  color: var(--c-navy);
  transition: background-color var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}
/* Restrained by default, platform colour on hover — the colour is a response
   to the pointer rather than six competing brand colours at rest. */
.social-list__link:hover,
.social-list__link:focus-visible {
  background: var(--brand, var(--c-navy));
  border-color: var(--brand, var(--c-navy));
  color: var(--c-white);
}
@media (min-width: 768px) {
  .footer-social-block { justify-self: end; text-align: right; }
  .footer-social-block .social-list { justify-content: flex-end; }
}

/* ---- Base row -------------------------------------------------------------- */

.footer-base {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-4);
  padding-block: var(--s-6) var(--s-7);
  border-top: var(--border);
  text-align: center;
}
.site-footer__wordmark img { height: 24px; width: auto; }
.footer-base__links {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-3) var(--s-5);
}
.footer-base__links a { font-size: var(--fs-sm); color: var(--c-muted); }
.footer-base__links a:hover { color: var(--c-blue); }
.site-footer__legal {
  font-size: var(--fs-2xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--c-muted);
}

/* ==========================================================================
   WhatsApp chat button
   ==========================================================================
   The glyph is navy on the platform green, not white: white on #25D366
   measures 1.98:1, below even the 3:1 minimum for a non-text UI element.
   Navy on the same green is 7.68:1, so the mark stays recognisable and the
   glyph is actually legible. The green circle itself is low contrast against
   a white page, so the shadow is what gives its edge definition. */

.wa-fab {
  position: fixed;
  right: var(--gutter);
  bottom: var(--gutter);
  z-index: var(--z-sticky-bar);
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  height: 56px;
  padding: 0 var(--s-4);
  border-radius: var(--radius-pill);
  background: #25D366;
  color: var(--c-navy);
  box-shadow: 0 6px 20px rgba(2, 31, 99, 0.28);
  transition: transform var(--t-med) var(--ease), bottom var(--t-med) var(--ease);
}
.wa-fab:hover { color: var(--c-navy); transform: translateY(-2px); }
.wa-fab:focus-visible { outline: 2px solid var(--c-navy); outline-offset: 3px; }
.wa-fab__icon { display: grid; place-items: center; flex: none; }
.wa-fab__label {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  white-space: nowrap;
}

/* The product page's sticky add-to-bag bar owns the bottom edge, so lift the
   button clear of it rather than letting the two overlap. */
body.has-sticky-bar .wa-fab { bottom: calc(var(--gutter) + 76px); }

@media (max-width: 575.98px) {
  /* Icon only on a phone — the label costs width the page needs, and the
     glyph alone is understood. */
  .wa-fab { width: 52px; height: 52px; padding: 0; justify-content: center; }
  .wa-fab__label { display: none; }
  body.has-sticky-bar .wa-fab { bottom: calc(var(--gutter) + 72px); }
}
