/* ============================================================================
   FUNKY JUNQUE WHOLESALE — design system
   ----------------------------------------------------------------------------
   Borrows the consumer site's energy (FJ orange, Anton display type, bold
   uppercase rhythm, generous card treatments) but rebuilds the hierarchy around
   a retail buyer: proof first, product second, no cart anywhere.
   ========================================================================== */

:root {
  /* brand */
  --o:        #F26522;   /* FJ orange */
  --o-dark:   #C24E17;
  --o-soft:   #FDEBE0;
  --ink:      #16161A;
  --ink-2:    #2A2A31;
  --paper:    #FFFFFF;
  --surface:  #FAF8F4;
  --surface-2:#F2EEE6;
  --border:   #E4E0D7;
  --muted:    #6E6A62;
  --muted-2:  #97928A;
  /* semantic */
  --proof:    #12705A;   /* verified / performance green */
  --proof-bg: #E6F3EE;
  --gold:     #B8860B;
  --sale:     #C8102E;   /* markdown red — distinct from FJ orange */
  --aud-adult:#2563EB;   /* audience: Adults */
  --aud-kids: #16A34A;   /* audience: Kids & Baby */
  --aud-mm:   #DB2777;   /* audience: Mommy & Me — matches the demographic icon */
  --faire-y:  #FED815;   /* Faire's own button yellow, for the PDP order CTA */
  --faire-y-d:#E8C40C;

  --font-display: 'Anton', 'Arial Narrow', Impact, sans-serif;
  --font-script:  'Caveat', 'Segoe Script', cursive;
  --font-body:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --r:      12px;
  --r-sm:   8px;
  --shadow: 0 8px 28px rgba(22,22,26,.09);
  --shadow-lg: 0 20px 60px rgba(22,22,26,.16);
  --maxw:   1340px;
  --hdr:    78px;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--paper);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
svg { flex: 0 0 auto; }

/* Visible, high-contrast focus everywhere. Never remove without replacing. */
:focus-visible {
  outline: 3px solid var(--o);
  outline-offset: 2px;
  border-radius: 3px;
}

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }
.wrap--narrow { max-width: 880px; }
.display {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  letter-spacing: .015em; line-height: 1.03;
}
.script { font-family: var(--font-script); font-weight: 700; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 999; background: var(--ink);
  color: #fff; padding: 10px 18px; border-radius: 0 0 var(--r-sm) var(--r-sm); font-weight: 700;
  transition: top .15s;
}
.skip-link:focus { top: 0; }

/* ---------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 13px 24px; border-radius: 999px; font-weight: 800; font-size: 13.5px;
  letter-spacing: .05em; text-transform: uppercase; border: 2px solid transparent;
  transition: transform .12s ease, background .15s, color .15s, border-color .15s;
  text-align: center; line-height: 1.15;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn--faire   { background: var(--o); color: #fff; }
.btn--faire:hover { background: var(--o-dark); color: #fff; }
/* Not on Faire yet — see config/pending-products.js. Deliberately quieter than
   the Faire button: it is an email link, not an order, so it should not read as
   the same action. Dashed border says "provisional" without shouting. */
.btn--soon { background: transparent; color: var(--ink); border: 1.5px dashed var(--border); font-weight: 700; }
.btn--soon:hover { color: var(--o); border-color: var(--o); background: var(--o-soft); }
/* The PDP order button borrows Faire's own yellow so the hand-off to Faire is
   visually obvious. Black text — yellow on white needs the dark label to clear
   contrast, and it matches Faire's button exactly. */
.btn--faire-y { background: var(--faire-y); color: var(--ink); }
.btn--faire-y:hover { background: var(--faire-y-d); color: var(--ink); }
.btn--ink     { background: var(--ink); color: #fff; }
.btn--ink:hover { background: var(--ink-2); }
.btn--ghost   { border-color: currentColor; }
.btn--ghost:hover { background: var(--ink); color: #fff; border-color: var(--ink); }
/* Stays white with ink text on hover — the lift is the whole feedback. Tinting
   it orange washed the label out against the hero. */
.btn--light   { background: #fff; color: var(--ink); }
.btn--light:hover { background: #fff; color: var(--ink); }
.btn--sm { padding: 9px 16px; font-size: 12px; }
.btn--block { display: flex; width: 100%; }
.btn[aria-disabled="true"], .btn:disabled {
  background: var(--surface-2); color: var(--muted-2); border-color: var(--border);
  cursor: not-allowed; transform: none;
}
.ext { width: 14px; height: 14px; }

/* -------------------------------------------------------- announcement bar */
.marquee {
  background: var(--ink); color: #fff; overflow: hidden; white-space: nowrap;
  font-size: 11.5px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase;
}
.marquee__track { display: inline-flex; gap: 54px; padding: 8px 0; animation: mq 42s linear infinite; }
.marquee__track > span { display: inline-flex; align-items: center; gap: 10px; }
.marquee em { color: var(--o); font-style: normal; }
@keyframes mq { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; padding-left: 20px; }
}

/* ----------------------------------------------------------------- header */
.header { position: sticky; top: 0; z-index: 300; background: #fff; border-bottom: 1px solid var(--border); }
.header__bar {
  display: flex; align-items: center; gap: 22px; height: var(--hdr);
  max-width: var(--maxw); margin: 0 auto; padding: 0 20px;
}
.logo { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.logo img { height: 32px; width: auto; border-radius: 4px; }
.logo-txt { line-height: 1; }
.logo-txt b { display: block; font-family: var(--font-display); font-size: 19px; letter-spacing: .03em; font-weight: 400; text-transform: uppercase; }
/* Wordmark is a single solid color — inherits ink in the header, white in the
   footer — rather than splitting "Funky" and "Junque" across two colors. */
.logo-txt b em { color: inherit; font-style: normal; }
.logo-txt span { display: block; font-size: 9px; font-weight: 800; letter-spacing: .28em; color: var(--muted); text-transform: uppercase; margin-top: 2px; }
/* Footer wordmark and mark both go white. The white-logo JPG has a black
   background baked in, so `mix-blend-mode: screen` drops that black out and
   lets the footer's own ink show through instead of a hard black square. */
.logo--onDark .logo-txt b { color: #fff; }
.logo--onDark .logo-txt span { color: #8E8A82; }
.logo--onDark img { mix-blend-mode: screen; border-radius: 0; }

/* Items align to the bottom, so the "Shop by" caption can sit above its group
   without pushing that group out of line with Sale / Best Sellers / Reviews. */
.nav { display: flex; gap: 2px; margin-left: auto; align-items: flex-end; }
.nav li { position: relative; }
/* Depth-agnostic — the grouped items live one level deeper than the rest. */
.nav li > a, .nav li > .nav__top {
  display: flex; align-items: center; gap: 5px; padding: 20px 11px;
  font-weight: 800; font-size: 12.5px; letter-spacing: .05em; text-transform: uppercase;
  border-bottom: 3px solid transparent; white-space: nowrap;
}
.nav li:hover > a, .nav li:focus-within > a,
.nav li:hover > .nav__top, .nav li:focus-within > .nav__top { color: var(--o); border-bottom-color: var(--o); }
/* Between the mobile breakpoint and a wide desktop the eleven nav items plus
   the logo and the Faire button add up to more than the bar — the row then
   pushes past the viewport and gives the whole page a horizontal scrollbar.
   Tightening the item padding buys back the ~130px needed, which is cheaper
   than dropping an item or wrapping the row. */
@media (max-width: 1400px) {
  .nav li > a, .nav li > .nav__top { padding-left: 7px; padding-right: 7px; letter-spacing: .03em; }
  .header__bar { gap: 14px; }
}
/* Demographic / Season / Occasion open a panel and go nowhere on their own,
   so they are buttons — a link there pointed at an arbitrary first collection. */
/* No `font` shorthand here — it would reset the weight and size the shared
   rule above sets, and these would stop matching the real links. */
.nav li > .nav__top { font-family: inherit; color: inherit; cursor: default; }

/* Shop-by group. The caption is decoration: no hover, no focus, no hit area,
   and the group wrapper itself is never treated as a nav item. */
.shopby { display: flex; flex-direction: column; }
.shopby__items { display: flex; gap: 2px; }
/* Trim only the TOP padding on the grouped items. The nav is bottom-aligned,
   so their labels keep the same baseline as Sale / Reviews while the caption
   drops to sit right on top of them. */
.shopby__items > li > a, .shopby__items > li > .nav__top { padding-top: 0; }
/* Caveat, the same script the section eyebrows use — already loaded, and a
   cursive wants sentence case with no tracking. Sized up because a script's
   x-height runs small: 19px here reads about the weight of 12px Inter. */
.shopby__label {
  display: flex; align-items: center; gap: 9px; margin: 0 11px 0;
  font-family: var(--font-script); font-weight: 700; font-size: 19px; line-height: 1.18;
  letter-spacing: 0; text-transform: none;
  color: var(--o); pointer-events: none; user-select: none;
}
.shopby__label::before, .shopby__label::after {
  content: ''; flex: 1 1 auto; height: 1px; background: var(--o); opacity: .85;
}
.nav .caret { width: 9px; height: 9px; opacity: .5; }

.mega {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%) translateY(10px);
  opacity: 0; pointer-events: none; transition: opacity .16s, transform .16s;
  background: #fff; border: 1px solid var(--border); border-radius: var(--r);
  box-shadow: var(--shadow-lg); padding: 18px; min-width: 260px; z-index: 5;
}
/* Direct child, not descendant — the shop-by group is itself an <li>, so a
   descendant match opened every panel inside it at once. */
.nav li:hover > .mega, .nav li:focus-within > .mega { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
/* 4-column "Shop All" mega, mirroring the B2C menu */
.mega--wide {
  display: grid; grid-template-columns: repeat(4, minmax(180px, 1fr));
  gap: 8px 26px; padding: 20px 24px; max-width: min(960px, calc(100vw - 24px));
}
.mega__col { min-width: 0; }
.mega__all { grid-column: 1 / -1; margin-bottom: 6px; }
/* Body face, not Anton — condensed all-caps display type at this size read as
   a solid block rather than words. */
.mega__all a {
  display: flex; justify-content: center; align-items: baseline; gap: 10px;
  background: var(--ink); color: #fff; border-radius: var(--r-sm);
  font-weight: 700; letter-spacing: .04em; font-size: 13.5px; padding: 12px;
}
.mega__all a:hover { background: var(--o); color: #fff; }
.mega__all .count { color: rgba(255,255,255,.72); font-size: 12px; }
@media (max-width: 1240px) { .mega--wide { grid-template-columns: repeat(2, minmax(180px, 1fr)); } }
/* .mega--two and .mega--three lived here. They laid out the state and city
   columns that used to sit in the Occasion dropdown; the menu now carries a
   single Cities & States entry and the hub page is where a place is chosen. */
.mega h5 {
  font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--muted-2);
  margin: 0 6px 8px; padding-bottom: 7px; border-bottom: 1px solid var(--border);
}
.mega a {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 7px 8px; border-radius: var(--r-sm); font-size: 13.5px; font-weight: 600;
}
.mega a:hover { background: var(--o-soft); color: var(--o-dark); }
.nav__faire > a { color: var(--o); }

.hdr-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.icon-btn { padding: 9px; border-radius: 50%; display: grid; place-items: center; color: var(--ink); }
.icon-btn:hover { background: var(--surface); color: var(--o); }
.icon-btn svg { width: 20px; height: 20px; }
.burger { display: none; }

/* mobile nav */
.mnav { display: none; }
/* 1200, not 1080: the desktop nav needs about 1,200px to lay out its eleven
   items beside the logo and the Faire button. Below that it was still being
   shown and simply ran off the right edge, giving every page a horizontal
   scrollbar in the 1081-1199 band. The burger takes over where the row stops
   fitting rather than where a round number said it should. */
@media (max-width: 1200px) {
  .nav { display: none; }
  /* Reads as a button, not a hint: a bordered pill with a word in it. The old
     bare 24px glyph was easy to miss and a 38px tap target. */
  .burger {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 13px 9px 11px; min-height: 44px;
    border: 1.5px solid var(--ink); border-radius: 999px;
    background: #fff; color: var(--ink);
    transition: background .16s ease, color .16s ease, border-color .16s ease;
  }
  .burger__box { position: relative; width: 18px; height: 13px; display: block; flex: 0 0 auto; }
  .burger__box span {
    position: absolute; left: 0; width: 100%; height: 2.2px; border-radius: 2px;
    background: currentColor; transition: transform .24s ease, opacity .16s ease, top .24s ease;
  }
  .burger__box span:nth-child(1) { top: 0; }
  .burger__box span:nth-child(2) { top: 5.4px; }
  .burger__box span:nth-child(3) { top: 10.8px; }
  .burger__txt { font-size: 12px; font-weight: 900; letter-spacing: .1em; text-transform: uppercase; }
  .burger:hover { background: var(--ink); color: #fff; }
  .burger[aria-expanded="true"] { background: var(--o); border-color: var(--o); color: #fff; }
  .burger[aria-expanded="true"] .burger__box span:nth-child(1) { top: 5.4px; transform: rotate(45deg); }
  .burger[aria-expanded="true"] .burger__box span:nth-child(2) { opacity: 0; }
  .burger[aria-expanded="true"] .burger__box span:nth-child(3) { top: 5.4px; transform: rotate(-45deg); }
  /* The header is its own z-index:300 stacking context, so raising the button
     alone cannot lift it over the z-index:400 panel — the whole header has to
     move. Only while the nav is open: the PDP review drawer (401) is meant to
     cover the header, and a permanent raise would break that. */
  body.is-navopen .header { z-index: 420; }

  .mnav {
    display: block; position: fixed; inset: 0 0 0 auto; width: min(360px, 88vw);
    background: #fff; z-index: 400; transform: translateX(100%); transition: transform .22s ease;
    overflow-y: auto; box-shadow: var(--shadow-lg);
    /* Clears the notch, the home indicator and the header the panel slides under. */
    padding: calc(var(--hdr) + 12px) max(16px, env(safe-area-inset-right)) calc(60px + env(safe-area-inset-bottom)) 16px;
    overscroll-behavior: contain;
  }
  .mnav.is-open { transform: translateX(0); }
  /* Every row is a 48px target — these are read at arm's length with a thumb. */
  .mnav summary, .mnav > a { min-height: 48px; align-items: center; }
  .mnav details a { min-height: 44px; display: flex; align-items: center; }
  .mnav__scrim { position: fixed; inset: 0; background: rgba(22,22,26,.45); z-index: 390; opacity: 0; pointer-events: none; transition: opacity .2s; }
  .mnav__scrim.is-open { opacity: 1; pointer-events: auto; }
  .mnav details { border-bottom: 1px solid var(--border); }
  .mnav summary { padding: 14px 4px; font-weight: 800; font-size: 14px; text-transform: uppercase; letter-spacing: .04em; cursor: pointer; list-style: none; display: flex; justify-content: space-between; }
  .mnav summary::-webkit-details-marker { display: none; }
  .mnav summary::after { content: '+'; color: var(--o); font-size: 20px; line-height: 1; }
  .mnav details[open] summary::after { content: '–'; }
  .mnav__label { padding: 18px 4px 4px; font-size: 9px; font-weight: 900; letter-spacing: .22em; text-transform: uppercase; color: var(--muted-2); }
  .mnav details a, .mnav > a { display: block; padding: 10px 4px 10px 14px; font-size: 14px; font-weight: 600; color: var(--muted); }
  .mnav > a { padding: 14px 4px; font-weight: 800; text-transform: uppercase; font-size: 14px; color: var(--ink); border-bottom: 1px solid var(--border); letter-spacing: .04em; }
  .mnav .btn { margin-top: 18px; }
}

/* The header bar carries a logo, a Faire CTA and the menu button. On a 390px
   phone those three wanted 361px inside 350px of usable width and the row
   simply ran off the right edge, taking the whole page's horizontal scroll with
   it — visible as the burger sitting past the viewport. Everything narrows
   together rather than dropping any one of the three. */
@media (max-width: 620px) {
  .header__bar { gap: 12px; padding: 0 14px; }
  .hdr-actions { gap: 4px; }
  .u-wide { display: none; }               /* "Order on " — the button reads "Faire" */
  .logo { gap: 8px; }
  .logo img { height: 28px; }
  .logo-txt b { font-size: 17px; }
  .logo-txt span { font-size: 8px; letter-spacing: .2em; }
  .burger { padding: 9px 11px 9px 10px; gap: 6px; }
}
/* Below this the wordmark is what gives — the mark alone still identifies the
   brand, and the menu button has to stay legible. */
@media (max-width: 400px) {
  .logo-txt { display: none; }
}

/* ------------------------------------------------------------------- hero */
.hero { background: var(--ink); color: #fff; position: relative; overflow: hidden; }
.hero::after {
  content: ''; position: absolute; inset: auto -10% -55% 55%; height: 520px;
  background: radial-gradient(closest-side, rgba(242,101,34,.30), transparent 70%);
  pointer-events: none;
}
/* Hero scaled down ~20% — padding, headline and collage all step together so
   the composition keeps its proportions. */
.hero__inner {
  position: relative; z-index: 1; display: grid; grid-template-columns: minmax(0, .7fr) minmax(0, 1fr);
  gap: 28px; align-items: center; max-width: var(--maxw); margin: 0 auto; padding: 48px 20px 54px;
}
.eyebrow {
  display: inline-flex; align-items: center; gap: 9px; font-size: 11.5px; font-weight: 900;
  letter-spacing: .22em; text-transform: uppercase; color: var(--o);
}
.eyebrow::before { content: ''; width: 26px; height: 2px; background: var(--o); }
.hero h1 { font-size: clamp(32px, 4.5vw, 59px); margin: 11px 0 13px; }
.hero h1 em { font-style: normal; color: var(--o); }
.hero__lede { font-size: 15.5px; color: #D9D5CE; max-width: 470px; }
.hero__ctas { display: flex; gap: 10px; margin-top: 22px; flex-wrap: wrap; }
/* The copy column gave width to the coverflow, so the pair is trimmed to keep
   both CTAs on one desktop line rather than stacking. */
.hero__ctas .btn { padding: 12px 18px; font-size: 12.5px; }
.hero__trust {
  margin-top: 24px; font-size: 12.5px; font-weight: 700; color: #B7B2A9;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; letter-spacing: .02em;
}
/* A text link, not another button — the hero already has two and a third
   competing block is what made the orange band too much. */
.hero__offer { margin-top: 16px; }
.hero__offer button {
  background: none; padding: 0; color: #fff; font: inherit; font-size: 14px; font-weight: 700;
  border-bottom: 1.5px solid var(--o); transition: color .16s ease;
}
.hero__offer button:hover { color: var(--o); }

/* The colorway a card is showing, named under the style subtitle. Ink and
   medium weight so it reads as the specific thing you are buying, a step
   above the grey subtitle but below the price. */
.card__variant {
  font-size: 13px; font-weight: 700; color: var(--ink); margin-top: 4px;
  overflow-wrap: anywhere;
}

/* --------------------------------------------------- cities & states nav */
/* The "browse every place" block at the foot of each place page, and the whole
   body of the hub. Two columns of short names with their hat counts. */
.placehead__count { color: var(--muted); font-size: 15px; margin: 0 0 22px; }
.placenav__title,
.placesec__h {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(22px, 2.6vw, 30px); margin-bottom: 18px;
}
/* The demographic chips jump to these, and the header is sticky — without the
   offset the heading lands underneath it and the section looks like it starts
   at the second row of cards. */
.placesec__h { margin-bottom: 6px; scroll-margin-top: calc(var(--hdr) + 18px); }
.placenav { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 40px; }
/* Each group is a <details>. The summary is the whole affordance: a rule, a
   label, a count and a caret that rotates when it opens. */
.placenav__group { border-bottom: 1px solid var(--border); }
.placenav__sum {
  display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none;
  padding: 12px 2px; font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink); font-weight: 800;
}
.placenav__sum::-webkit-details-marker { display: none; }   /* Safari's own triangle */
.placenav__sum:hover { color: var(--o); }
.placenav__sum:focus-visible { outline: 2px solid var(--o); outline-offset: 3px; border-radius: var(--r-sm); }
.placenav__count {
  color: var(--muted-2); font-size: 11px; font-weight: 700; letter-spacing: .06em;
  font-variant-numeric: tabular-nums;
}
/* Caret drawn in CSS so it needs no markup and no icon request. */
.placenav__sum::after {
  content: ''; margin-left: auto; width: 8px; height: 8px; flex: 0 0 auto;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px); transition: transform .16s ease;
}
.placenav__group[open] > .placenav__sum::after { transform: rotate(-135deg) translate(-2px, -2px); }
.placenav__group[open] > .placenav__sum { color: var(--o); }
.placenav__list { padding-bottom: 14px; }
/* Hide the closed list explicitly instead of trusting the <details> default.
   The list sets `columns: 2`, and a multi-column formatting context escapes
   Chrome's own hiding of closed-details content — the caret said closed while
   all twenty-two cities stayed on screen. */
.placenav__group:not([open]) .placenav__list { display: none; }
@media (prefers-reduced-motion: reduce) { .placenav__sum::after { transition: none; } }
.placenav__list { list-style: none; columns: 2; column-gap: 26px; }
.placenav__list li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 6px 0; break-inside: avoid;
}
.placenav__list a { font-weight: 600; border-bottom: 1.5px solid transparent; }
.placenav__list a:hover { color: var(--o); border-bottom-color: var(--o); }
.placenav__list [aria-current="page"] { font-weight: 800; color: var(--o); }
@media (max-width: 720px) {
  .placenav { grid-template-columns: 1fr; gap: 22px; }
  .placenav__list { columns: 2; }
}

/* ------------------------------------------------------ page offer line */
/* The offer as a line of copy under a page's title and lede, replacing the
   dark strip that used to sit in the header. On light pages, so the label is
   ink rather than white — the two hero callouts sit on dark and keep theirs. */
.offer-line { margin-top: 16px; }
.offer-line__cta {
  background: none; border: 0; padding: 0; color: var(--ink); font: inherit;
  font-size: 14px; font-weight: 700;
  border-bottom: 1.5px solid var(--o); transition: color .16s ease;
}
.offer-line__cta:hover { color: var(--o); }
.offer-line__cta:hover .offer-arw { transform: translateX(3px); }

/* ------------------------------------------------- offer callout pointer */
/* Shared by the homepage hero and the decorators hero — the two callouts look
   the same and are meant to, so the pointer is defined once. Each callout is a
   flex row: chevron, then the underlined text button.

   The chevron travels toward the label rather than blinking or bouncing; slow
   horizontal motion reads as "look here" without hijacking the page. It stops
   entirely for anyone who asks for reduced motion. */
.hero__offer, .hb-hero__note, .offer-line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.offer-point {
  flex: 0 0 auto; display: inline-flex; color: var(--o);
  animation: offerPoint 1.5s ease-in-out infinite;
}
.offer-point svg { width: 22px; height: 22px; display: block; }
@keyframes offerPoint {
  0%, 100% { transform: translateX(-4px); opacity: .55; }
  50%      { transform: translateX(4px);  opacity: 1; }
}
/* inline-block so the nudge takes: transform does nothing on an inline box. */
.offer-arw { display: inline-block; transition: transform .16s ease; }
.hero__offer button:hover .offer-arw,
.hb-hero__cta:hover .offer-arw { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .offer-point { animation: none; transform: none; opacity: 1; }
}
/* Narrow screens: keep the chevron on the label's row. Left to wrap it lands
   above the text and points at empty space, which is worse than no pointer. */
@media (max-width: 640px) {
  .hero__offer, .hb-hero__note, .offer-line { flex-wrap: nowrap; }
  .hero__offer button, .hb-hero__cta, .offer-line__cta { min-width: 0; }
}
.hero__trust .sep { color: var(--o); }
.hero__trust .star { color: #F5B301; letter-spacing: .1em; }

/* Featured retailer quote under the proof line. Deliberately quiet — the hero
   already carries a headline, two buttons and the offer link, so this is set as
   evidence rather than a fourth thing competing for attention. The orange rule
   does the work a pair of big quote marks would, without the vertical cost. */
.hero__quote { margin: 20px 0 0; padding-left: 14px; border-left: 2px solid var(--o); max-width: 470px; }
.hero__quote blockquote { margin: 0; font-size: 13.5px; line-height: 1.6; color: #D9D5CE; }
.hero__quote figcaption {
  margin-top: 9px; font-size: 11px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: #97928A;
}
.hero__quote figcaption .sep { color: var(--o); }

/* hero coverflow — active card upright, neighbours tilted back in perspective */
.cflow {
  position: relative; width: 100%; height: 430px; display: flex;
  align-items: center; justify-content: center; overflow: hidden; outline: none;
}
.cflow:focus-visible { outline: 3px solid var(--o); outline-offset: -3px; }
.cflow__stage { position: relative; transform-style: preserve-3d; }
.cflow__card {
  position: absolute; left: 50%; top: 50%; overflow: hidden;
  transform-style: preserve-3d; transform-origin: center center;
  background-color: #1a1a1a; will-change: transform, opacity;
  box-shadow: 0 18px 50px rgba(0,0,0,.42);
}
.cflow__card img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block; user-select: none;
}
.cflow__veil { position: absolute; inset: 0; background: #000; pointer-events: none; }
/* Mobile hero art is being reconfigured — for now the deck is simply hidden
   below its breakpoint and the hero runs as copy only. */
@media (max-width: 940px) { .cflow { display: none; } }

/* hero collage — real product photography, angled like the consumer site */
.collage { position: relative; height: 368px; }
.collage figure {
  position: absolute; background: #fff; border-radius: 14px; padding: 8px;
  box-shadow: 0 20px 46px rgba(0,0,0,.34); transition: transform .25s ease; overflow: hidden;
}
.collage figure img { width: 100%; height: 100%; object-fit: contain; border-radius: 8px; background: #fff; }
/* Lifestyle photography fills its tile; packshots stay letterboxed above. */
.collage figure.is-photo { padding: 6px; }
.collage figure.is-photo img { object-fit: cover; }
.collage figure:hover { transform: scale(1.04) rotate(0deg) !important; z-index: 6; }
/* Square tiles for square source photos — a landscape tile cropped the tops of
   the hats clean off, which is the whole subject. Only width is set;
   aspect-ratio keeps each tile 1:1 at any viewport. */
.collage figure { aspect-ratio: 1 / 1; }
.collage .c1 { width: 43%; left: 1%;  top: 1%;    transform: rotate(-5deg); z-index: 3; }
.collage .c2 { width: 37%; right: 2%; top: 0;     transform: rotate(4deg);  z-index: 2; }
.collage .c3 { width: 35%; left: 21%; bottom: 0;  transform: rotate(3deg);  z-index: 4; }
.collage .c4 { width: 32%; right: 0;  bottom: 4%; transform: rotate(-6deg); z-index: 1; }

@media (max-width: 940px) {
  .hero__inner { grid-template-columns: 1fr; padding: 44px 20px 48px; gap: 30px; }
  .collage { height: 300px; }
}

/* ------------------------------------------------------------- proof band */
.proof { background: var(--surface); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.proof__grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 0;
  max-width: var(--maxw); margin: 0 auto; padding: 0 20px;
}
.proof__item { padding: 20px 16px; text-align: center; border-right: 1px solid var(--border); }
.proof__item:last-child { border-right: 0; }
.proof__n {
  font-family: var(--font-display); font-size: clamp(26px, 3vw, 38px); line-height: 1;
  letter-spacing: .01em; color: var(--ink);
}
.proof__n em { font-style: normal; color: var(--o); }
.proof__l { margin-top: 6px; font-size: 11.5px; font-weight: 700; color: var(--muted); letter-spacing: .02em; }
.footnote { font-size: 11.5px; color: var(--muted-2); text-align: center; padding: 0 20px 22px; }
@media (max-width: 780px) {
  .proof__grid { grid-template-columns: repeat(2, 1fr); }
  .proof__item { padding: 26px 12px; border-bottom: 1px solid var(--border); }
  .proof__item:nth-child(2) { border-right: 0; }
  .proof__item:nth-child(3), .proof__item:nth-child(4) { border-bottom: 0; }
}

/* ---------------------------------------------------------------- section */
.section { padding: 66px 0; }
.section--tight { padding: 46px 0; }
.section--surface { background: var(--surface); }
.section--ink { background: var(--ink); color: #fff; }
.section--ink .sec-head p { color: #B7B2A9; }
.sec-head { margin-bottom: 30px; display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.sec-head h2 { font-family: var(--font-display); font-weight: 400; text-transform: uppercase; font-size: clamp(28px, 3.4vw, 42px); line-height: 1.05; }
.sec-head h2 em { font-style: normal; color: var(--o); }
.sec-head p { color: var(--muted); max-width: 620px; margin-top: 10px; font-size: 15px; }
/* The site's "see all" link. Not scoped to .sec-head — it is used in showcase
   headers, on product pages and in the trust panel too, and while the rule
   lived under .sec-head every one of those rendered as unstyled body text. */
.link {
  font-weight: 800; font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase;
  border-bottom: 2px solid var(--o); padding-bottom: 3px; white-space: nowrap;
}
.link:hover { color: var(--o); }
/* the "funky" script accents above headings, straight from the B2C look */
.accent { display: inline-block; font-family: var(--font-script); font-weight: 700; font-size: 25px; color: var(--o); transform: rotate(-1.5deg); margin-bottom: 2px; }
.page-head .accent { font-size: 27px; }

/* ------------------------------------------------------------ color bars */


/* ------------------------------------------------------------ product card */
.grid {
  display: grid; gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
}
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .grid--4 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 760px)  { .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .grid { gap: 14px; grid-template-columns: repeat(2, minmax(0,1fr)); } }

.card {
  background: #fff; border: 1px solid var(--border); border-radius: var(--r);
  overflow: hidden; display: flex; flex-direction: column; position: relative;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s;
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-color: #D6D1C6; }
/* Product photos render CONTAINED on white, never cropped — Amazon listing
   shots are framed with their own margins and cover-fit zoomed them badly. */
.card__media { position: relative; aspect-ratio: 1/1; background: #fff; overflow: hidden; border-bottom: 1px solid var(--surface-2); }
.card__media img { width: 100%; height: 100%; object-fit: contain; padding: 10px; transition: transform .3s ease; }
.card:hover .card__media img { transform: scale(1.04); }
.card__body { padding: 12px 14px 14px; display: flex; flex-direction: column; flex: 1; gap: 6px; }
.card__name { font-size: 14.5px; font-weight: 800; line-height: 1.3; }
.card__name a::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.card__sub { font-size: 12px; color: var(--muted); line-height: 1.35; }
.card__price { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-top: auto; padding-top: 4px; }
.card__ws { font-family: var(--font-display); font-size: 21px; letter-spacing: .01em; }
.card__msrp { font-size: 12px; color: var(--muted); }
.card__msrp s { text-decoration-color: var(--o); text-decoration-thickness: 1.5px; }
/* sale: discounted wholesale in red, the old wholesale struck beside it */
.card__ws--sale { color: var(--sale); }
.card__was { font-family: var(--font-display); font-size: 15px; color: var(--muted-2); text-decoration-color: var(--sale); text-decoration-thickness: 1.5px; }
.card__was[hidden] { display: none; }
.card__meta { font-size: 11.5px; color: var(--muted); display: flex; gap: 10px; flex-wrap: wrap; }
.card__cta { position: relative; z-index: 2; margin-top: 8px; }
.card__proof { font-size: 11.5px; font-weight: 700; color: var(--proof); display: flex; align-items: center; gap: 5px; }

/* card swatch previews — circular product thumbs + "+N" count, like B2C */
.swatches { position: relative; z-index: 2; display: flex; gap: 5px; align-items: center; flex-wrap: wrap; min-height: 26px; }
.swx {
  width: 26px; height: 26px; border-radius: 50%; overflow: hidden; padding: 0;
  border: 1.5px solid var(--border); background: #fff; flex: 0 0 auto;
  transition: transform .12s, border-color .12s;
}
/* `contain` with a little inset, not `cover` — a wide product like sunglasses
   filled the circle edge to edge and the colorway was cropped out of view. */
.swx img { width: 100%; height: 100%; object-fit: contain; padding: 2px; background: #fff; }
.swx:hover { transform: scale(1.12); border-color: var(--ink); }
.swx[aria-pressed="true"] { border-color: var(--o); box-shadow: 0 0 0 1.5px var(--o); }
.swatch-more { font-size: 11px; color: var(--muted); font-weight: 800; padding-left: 2px; }
/* A 26px circle is a fine hover target and a poor thumb target. On touch these
   grow past the 44px guidance, which also makes the colorway legible at arm's
   length instead of a smudge. */
@media (max-width: 760px) {
  .swatches { gap: 7px; min-height: 36px; }
  .swx { width: 36px; height: 36px; border-width: 2px; }
  .swx img { padding: 3px; }
  .swatch-more { font-size: 12px; }
}

.badge {
  position: absolute; top: 10px; left: 10px; z-index: 2; font-size: 10px; font-weight: 900;
  letter-spacing: .1em; text-transform: uppercase; padding: 5px 9px; border-radius: 999px; color: #fff;
}
/* Every chip that can appear on one card gets its own hue. Blue and green are
   reserved for the audience pill, so "New" moved to violet and "Most
   reordered" to teal — otherwise a green performance badge and a green
   Kids & Baby pill would sit side by side meaning different things. */
.badge--bestseller  { background: var(--o); }
.badge--reordered   { background: #0E6E6E; }
.badge--trending    { background: var(--ink); }
.badge--new         { background: #6B3FD4; }
.badge--seasonal    { background: var(--gold); }
.badge--sale        { background: var(--sale); }
.badge--oos         { background: var(--muted); }

/* Audience pill sits in the card body, between the swatch row and the title —
   it reads as product information, not as an image overlay. */
.aud {
  align-self: flex-start; font-size: 10px; font-weight: 900;
  letter-spacing: .1em; text-transform: uppercase; padding: 4px 9px; border-radius: 999px; color: #fff;
}
.aud--adult { background: var(--aud-adult); }
.aud--kids  { background: var(--aud-kids); }
.aud--mm    { background: var(--aud-mm); }

.swatches { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }
.swatch-dot { width: 15px; height: 15px; border-radius: 50%; border: 1px solid rgba(0,0,0,.16); }
.swatch-more { font-size: 11px; color: var(--muted); font-weight: 700; }

/* --------------------------------------------------------- tile / collection */
.tiles { display: grid; gap: 18px; grid-template-columns: repeat(3, minmax(0,1fr)); }
/* Four proven-seller tiles, one desktop row. */
.tiles--row { grid-template-columns: repeat(4, minmax(0,1fr)); gap: 14px; }
/* Product grid sitting directly under a tile row, no heading between — needs
   real separation or the two treatments read as one run-on block. */
.grid--gap-top { margin-top: 48px; }
@media (max-width: 1050px) { .tiles--row { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 900px) { .tiles { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 560px) { .tiles, .tiles--row { grid-template-columns: 1fr; } }
.tile {
  position: relative; border-radius: var(--r); overflow: hidden; min-height: 230px;
  display: flex; align-items: flex-end; color: #fff; background: var(--ink);
  transition: transform .18s ease, box-shadow .18s ease;
}
/* Same orange glow as the review cards. The tile has no resting border, so the
   ring is drawn with an inset shadow and the glow layered outside it. */
.tile:hover, .tile:focus-visible {
  transform: translateY(-4px);
  box-shadow: inset 0 0 0 2px var(--o), 0 0 20px rgba(242,101,34,.34), 0 0 46px rgba(242,101,34,.18), var(--shadow-lg);
}
.tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .62; transition: transform .35s ease, opacity .25s; }
.tile:hover img { transform: scale(1.06); opacity: .5; }
.tile__body { position: relative; z-index: 1; padding: 22px; width: 100%;
  background: linear-gradient(to top, rgba(10,10,12,.9) 12%, rgba(10,10,12,.35) 60%, transparent); }
.tile h3 { font-family: var(--font-display); font-weight: 400; text-transform: uppercase; font-size: 24px; line-height: 1.08; }
.tile p { font-size: 13px; color: #D9D5CE; margin-top: 6px; }
.tile .count { font-size: 11.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--o); margin-top: 10px; display: block; }
/* Compact variant: four across, photo-led, label only. Square so the square
   source photo fills it with no crop — the hats stay whole. */
.tile--sm { min-height: 0; aspect-ratio: 1 / 1; }
.tile--sm .tile__body { padding: 16px; background: linear-gradient(to top, rgba(10,10,12,.92) 18%, rgba(10,10,12,.45) 62%, rgba(10,10,12,.12)); }
.tile--sm h3 { font-size: 19px; }
.tile--sm .count { margin-top: 6px; font-size: 11px; }

/* ------------------------------------------------------------ top shop panel */
.topshop { display: grid; grid-template-columns: 1fr 1.15fr; gap: 44px; align-items: center; }
@media (max-width: 900px) { .topshop { grid-template-columns: 1fr; gap: 28px; } }
/* Faire Top Shop badge — built to match the supplied artwork rather than
   shipped as a flat image, so the kicker can flicker and the score can drift
   under the cursor. Stays crisp at any size and the figures stay live text. */
.tshop {
  margin: 0; position: relative; display: flex; flex-direction: column; align-items: center;
  gap: 2px; padding: 40px 30px 34px; border-radius: var(--r); overflow: hidden;
  background: radial-gradient(120% 100% at 50% 0%, #24252C 0%, #17181D 55%, #101116 100%);
  border: 1px solid rgba(255,255,255,.10); color: #fff; text-align: center;
  box-shadow: 0 20px 60px rgba(0,0,0,.35);
}
/* Thin orange rule along the bottom edge, as in the artwork. */
.tshop::after {
  content: ''; position: absolute; left: 8%; right: 8%; bottom: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--o), transparent);
}
/* Same Anton display face and size as the section heading beside it. */
.tshop__kicker {
  font-family: var(--font-display); font-weight: 400; font-size: clamp(28px, 3.4vw, 42px);
  line-height: 1.05; letter-spacing: .015em; text-transform: uppercase;
  color: var(--o); text-shadow: 0 0 14px rgba(242,101,34,.55);
}
.tshop__score { display: block; }
/* Pure white, glow included — no orange anywhere on the score. */
.tshop__score b {
  display: block; font-family: var(--font-display); font-weight: 400; font-size: clamp(76px, 11vw, 132px);
  line-height: .95; letter-spacing: .01em; margin: 6px 0 2px; color: #fff;
  text-shadow: 0 0 34px rgba(255,255,255,.32), 0 0 90px rgba(255,255,255,.16);
}
.tshop__stars { display: block; font-style: normal; font-size: 30px; letter-spacing: .1em; color: #F5B301;
  text-shadow: 0 2px 0 #B8860B, 0 0 22px rgba(245,179,1,.4); }
.tshop__count {
  margin-top: 14px; font-size: 15px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}
.tshop figcaption { font-size: 11.5px; color: #8E8A82; margin-top: 8px; }

/* Neon-sign flicker: mostly lit, with two irregular stutters per cycle. */
@keyframes tshop-flicker {
  0%, 39%, 41%, 62%, 64%, 68%, 100% { opacity: 1; text-shadow: 0 0 14px rgba(242,101,34,.55); }
  40%, 63%       { opacity: .35; text-shadow: none; }
  66%            { opacity: .6;  text-shadow: 0 0 6px rgba(242,101,34,.3); }
}
.tshop__kicker { animation: tshop-flicker 6s steps(1, end) infinite; }

/* Pixel drift: RGB channels pull apart and the glyphs jitter a pixel or two,
   using ::before/::after copies of the text from the data-drift attribute. */
/* z-index 0 opens a stacking context on the glyph so the ghost copies can sit
   at -1: behind the letterform but still above the card background. Painted
   on top they tinted the face itself, which should stay pure white. */
.tshop [data-drift] { position: relative; z-index: 0; }
.tshop [data-drift]::before, .tshop [data-drift]::after {
  content: attr(data-drift); position: absolute; inset: 0; opacity: 0; pointer-events: none;
  text-shadow: none; z-index: -1;
}
/* Monochrome echoes: the score drifts in white and the stars in their own
   gold, so neither picks up a colour cast the design does not already use. */
.tshop [data-drift]::before, .tshop [data-drift]::after { color: #FFFFFF; }
.tshop__stars[data-drift]::before, .tshop__stars[data-drift]::after { color: #F5B301; }
.tshop:hover [data-drift]::before, .tshop:focus-visible [data-drift]::before { opacity: .55; animation: tshop-drift-r .42s steps(2, end) infinite; }
.tshop:hover [data-drift]::after,  .tshop:focus-visible [data-drift]::after  { opacity: .4;  animation: tshop-drift-b .42s steps(2, end) infinite; }
.tshop:hover [data-drift], .tshop:focus-visible [data-drift] { animation: tshop-drift-x .42s steps(2, end) infinite; }
@keyframes tshop-drift-x { 0%,100% { transform: translate(0,0); } 50% { transform: translate(1px,-1px); } }
@keyframes tshop-drift-r { 0%,100% { transform: translate(-2px,1px); } 50% { transform: translate(-3px,-1px); } }
@keyframes tshop-drift-b { 0%,100% { transform: translate(2px,-1px); } 50% { transform: translate(3px,1px); } }

@media (prefers-reduced-motion: reduce) {
  .tshop__kicker { animation: none; }
  .tshop:hover [data-drift], .tshop:hover [data-drift]::before, .tshop:hover [data-drift]::after,
  .tshop:focus-visible [data-drift], .tshop:focus-visible [data-drift]::before, .tshop:focus-visible [data-drift]::after {
    animation: none; opacity: 0; transform: none;
  }
}
.scores { display: grid; gap: 12px; }
.score { display: grid; grid-template-columns: 1fr auto; gap: 6px 14px; align-items: center; }
.score__l { font-weight: 700; font-size: 14px; }
.score__v { font-family: var(--font-display); font-size: 21px; color: var(--o); }
.score__bar { grid-column: 1 / -1; height: 6px; border-radius: 999px; background: var(--surface-2); overflow: hidden; }
.score__bar i { display: block; height: 100%; background: var(--o); border-radius: 999px; }

/* ------------------------------------------------------------- testimonials */
.quotes { display: grid; gap: 18px; grid-template-columns: repeat(3, minmax(0,1fr)); }
@media (max-width: 950px) { .quotes { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 620px) { .quotes { grid-template-columns: 1fr; } }
.quote {
  background: #fff; border: 1px solid var(--border); border-radius: var(--r); padding: 24px;
  display: flex; flex-direction: column; gap: 14px;
  transition: border-color .18s ease, box-shadow .18s ease;
}
/* Orange glow on hover. The double ring — a tight opaque one plus a soft wide
   one — reads as light coming off the edge rather than a flat drop shadow. */
.quote:hover, .quote:focus-within {
  border-color: var(--o);
  box-shadow: 0 0 0 1px var(--o), 0 0 18px rgba(242,101,34,.28), 0 0 42px rgba(242,101,34,.14);
}
@media (prefers-reduced-motion: reduce) { .quote { transition: none; } }
.quote .stars { color: #F5B301; font-size: 14px; letter-spacing: .12em; }
.quote blockquote { font-size: 15.5px; line-height: 1.55; font-weight: 500; }
.quote blockquote::before { content: '“'; font-family: var(--font-display); color: var(--o); font-size: 34px; line-height: 0; vertical-align: -6px; margin-right: 2px; }
.quote figcaption { margin-top: auto; font-size: 13px; font-weight: 800; }
.quote figcaption span { display: block; font-weight: 600; color: var(--muted-2); font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; margin-top: 3px; }
/* City, state sits directly under the shop name — a place, not a category. */
.quote figcaption .q__place { text-transform: none; letter-spacing: 0; font-size: 12.5px; color: var(--muted); }
.themes { display: flex; gap: 6px; flex-wrap: wrap; }
.theme-pill { font-size: 10.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; background: var(--surface-2); color: var(--muted); padding: 4px 9px; border-radius: 999px; }

/* --------------------------------------------------------------- geo band */
.geo { display: grid; grid-template-columns: .9fr 1.1fr; gap: 46px; align-items: center; }
@media (max-width: 900px) { .geo { grid-template-columns: 1fr; gap: 26px; } }
.geo__map { position: relative; }
.geo__map svg { width: 100%; height: auto; }
.geo__map .st { fill: var(--o); opacity: .16; stroke: #fff; stroke-width: 1.1; transition: opacity .2s; }
.geo__map .st:hover { opacity: .5; }
.geo__pin { fill: var(--o); }
.geo__stats { display: flex; gap: 28px; flex-wrap: wrap; margin-top: 22px; }
.geo__stats div b { display: block; font-family: var(--font-display); font-size: 34px; color: var(--o); line-height: 1; }
.geo__stats div span { font-size: 12.5px; font-weight: 700; color: var(--muted); }

/* ------------------------------------------------- product review summary
   Rating line under the PDP subtitle, and the drawer it opens from the right.
   Stars are drawn as an overlaid pair so a 4.6 shows a real partial star
   instead of rounding to a half. */
.stars { display: inline-flex; gap: 1px; line-height: 1; }
.stars__s { position: relative; color: var(--border); font-size: 16px; letter-spacing: 0; }
.stars__f { position: absolute; inset: 0; overflow: hidden; color: var(--o); }

/* Card variant: between the audience pill and the product name. */
.card__rv { display: flex; align-items: center; gap: 7px; margin: 7px 0 5px; }
.card__rv b { font-size: 12.5px; font-weight: 800; }
.card__rv .stars__s { font-size: 13px; }

.rvline { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 10px 0 2px; }
.rvline b { font-size: 14px; font-weight: 800; }
.rvline__btn {
  display: inline-flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 700;
  text-decoration: underline; text-underline-offset: 3px; padding: 2px 0;
}
.rvline__btn:hover { color: var(--o); }
.rvline__spark { width: 16px; height: 16px; color: var(--o); }

/* Both carry a `display`, which outranks the UA [hidden] rule — without these
   the drawer is mounted permanently just off the right edge and never closes. */
.rvdrawer[hidden], .rvscrim[hidden] { display: none; }
.rvscrim { position: fixed; inset: 0; background: rgba(22,22,26,.5); z-index: 400; animation: rvfade .2s ease; }
@keyframes rvfade { from { opacity: 0; } to { opacity: 1; } }
.rvdrawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(460px, 100%); z-index: 401;
  background: #fff; display: flex; flex-direction: column;
  box-shadow: -20px 0 60px rgba(22,22,26,.28); animation: rvslide .28s cubic-bezier(.22,1,.36,1);
}
@keyframes rvslide { from { transform: translateX(100%); } to { transform: translateX(0); } }
.rvdrawer__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 16px 20px; border-bottom: 1px solid var(--border); flex: 0 0 auto;
}
.rvdrawer__head h2 { font-family: var(--font-display); font-weight: 400; font-size: 20px; text-transform: uppercase; letter-spacing: .02em; }
.rvdrawer__x { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; color: var(--muted); }
.rvdrawer__x:hover { background: var(--surface-2); color: var(--ink); }
.rvdrawer__x svg { width: 17px; height: 17px; }
.rvdrawer__body { padding: 20px; overflow-y: auto; flex: 1; }
.rvdrawer__top { display: flex; align-items: center; gap: 9px; margin-bottom: 14px; }
.rvdrawer__top b { font-size: 17px; font-weight: 800; }
.rvdrawer__top span { font-size: 13px; color: var(--muted); }
.rvdrawer__lede { font-size: 15px; line-height: 1.6; color: var(--ink-2); }
.rvdrawer__h {
  font-size: 11.5px; font-weight: 900; letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted); margin: 22px 0 12px;
}
.rvthemes { display: flex; flex-direction: column; gap: 16px; }
.rvthemes b { display: flex; align-items: center; gap: 8px; font-size: 14.5px; font-weight: 800; margin-bottom: 3px; }
.rvthemes b svg { width: 17px; height: 17px; color: var(--proof); flex: 0 0 auto; }
.rvthemes p { font-size: 13.6px; color: var(--muted); line-height: 1.55; }
.rvthemes__share { display: block; margin-top: 4px; font-size: 12px; font-weight: 800; color: var(--ink-2); }
.rvdrawer__note {
  margin: 22px 0 18px; padding-top: 16px; border-top: 1px solid var(--border);
  font-size: 12.2px; color: var(--muted-2); line-height: 1.5;
}
@media (max-width: 520px) { .rvdrawer { width: 100%; } }

/* ------------------------------------------------------------------ why us
   A vertical tablist instead of six equal cards: one reason reads at a time,
   each anchored to a real number. */
.reasons { display: grid; grid-template-columns: minmax(260px, 340px) minmax(0, 1fr); gap: 0; border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; background: #fff; }
.reasons__list { display: flex; flex-direction: column; border-right: 1px solid var(--border); background: var(--surface); }
.reason {
  display: grid; grid-template-columns: auto auto 1fr auto; align-items: center; gap: 12px;
  padding: 16px 18px; text-align: left; border-bottom: 1px solid var(--border);
  font: inherit; color: var(--muted); transition: background .14s, color .14s;
}
.reason:last-child { border-bottom: 0; }
.reason__n { font-family: var(--font-display); font-size: 13px; color: var(--muted-2); letter-spacing: .06em; }
.reason__ico { width: 30px; height: 30px; border-radius: 8px; background: #fff; border: 1px solid var(--border); display: grid; place-items: center; color: var(--muted-2); transition: .14s; }
.reason__ico svg { width: 16px; height: 16px; }
.reason__label { font-size: 14.5px; font-weight: 700; color: var(--ink); }
.reason__arrow { width: 15px; height: 15px; opacity: 0; transform: translateX(-4px); transition: .16s; color: var(--o); }
.reason:hover { background: #fff; }
.reason[aria-selected="true"] { background: #fff; }
.reason[aria-selected="true"] .reason__ico { background: var(--o); border-color: var(--o); color: #fff; }
.reason[aria-selected="true"] .reason__n { color: var(--o); }
.reason[aria-selected="true"] .reason__arrow { opacity: 1; transform: translateX(0); }
.reason[aria-selected="true"] .reason__label { color: var(--ink); }

.reasons__panels { padding: 30px 34px; display: flex; align-items: center; }
/* Copy left, unrolling photo right at ~a third of the panel. */
.reason__panel { max-width: 900px; width: 100%; display: grid; grid-template-columns: minmax(0, 1fr) 33%; gap: 30px; align-items: center; }
.reason__panel[hidden] { display: none; }   /* a class `display` outranks the UA [hidden] rule */
.reason__copy { min-width: 0; }
.reason__stat { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid var(--border); }
.reason__stat b { font-family: var(--font-display); font-size: clamp(34px, 4.4vw, 52px); line-height: 1; color: var(--o); letter-spacing: .01em; }
.reason__stat span { font-size: 13px; font-weight: 700; color: var(--muted); }
.reason__panel p { font-size: 15.5px; color: var(--muted); line-height: 1.62; }

/* Roll reveal. The <img> is the real content — server-rendered, so it stands
   alone without JS or WebGL. When the GL canvas takes over it hides, and the
   canvas paints the same photo unrolling from a spiral. */
.roll { position: relative; overflow: hidden; border-radius: var(--r-sm); background: var(--surface-2); aspect-ratio: 1 / 1; }
.roll__img { width: 100%; height: 100%; object-fit: cover; }
.roll canvas { position: absolute; display: block; pointer-events: none; }
.roll.is-gl .roll__img { visibility: hidden; }

@media (max-width: 1060px) {
  .reason__panel { grid-template-columns: minmax(0, 1fr) 38%; gap: 22px; }
}
@media (max-width: 860px) {
  .reasons { grid-template-columns: 1fr; }
  .reasons__list { border-right: 0; border-bottom: 1px solid var(--border); }
  .reasons__panels { padding: 24px 20px; }
  .reason__panel { grid-template-columns: 1fr; gap: 20px; }
  .roll { aspect-ratio: 16 / 10; }
}

/* ------------------------------------------------------------------- form */
/* The orange `.capture` block that used to wrap these lived here. Removed with
   the inline forms on 2026-08-10; the field styles below are still used by the
   signup modal, which is now the only form on the site. */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; margin-top: 24px; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }
.field { display: flex; flex-direction: column; gap: 5px; }
.field--full { grid-column: 1 / -1; }
.field label { font-size: 11.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: #FFEDE3; }
.field input, .field select, .field textarea {
  padding: 12px 14px; border-radius: var(--r-sm); border: 2px solid transparent; background: #fff;
  color: var(--ink); font-size: 14.5px; width: 100%;
}
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--ink); }
.field .hint { font-size: 11.5px; color: #FFEDE3; }
.form-msg { margin-top: 14px; font-weight: 700; font-size: 14px; min-height: 20px; }
.form-msg[data-state="error"] { color: #FFE0E0; }

/* ------------------------------------------------------------------ footer */
.footer { background: var(--ink); color: #B7B2A9; padding: 56px 0 26px; font-size: 14px; }
.footer a:hover { color: var(--o); }

/* The "give us your details" block, above the link columns. Sits on a slightly
   lifted panel so it reads as an invitation rather than another footer column,
   and keeps its own bottom rule to separate it from the links below. */
.footer__offer {
  display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap;
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.10);
  border-radius: var(--r); padding: 24px 26px; margin-bottom: 40px;
}
.footer__offer h5 { margin-bottom: 8px; }
.footer__offer p { max-width: 520px; }
.footer__offer .btn { flex: 0 0 auto; }
@media (max-width: 560px) {
  .footer__offer { padding: 20px; gap: 16px; }
  .footer__offer .btn { width: 100%; justify-content: center; }
}
.footer__grid { display: grid; grid-template-columns: 1.5fr repeat(3, 1fr); gap: 32px; }
@media (max-width: 860px) { .footer__grid { grid-template-columns: repeat(2, 1fr); gap: 26px; } }
@media (max-width: 520px) { .footer__grid { grid-template-columns: 1fr; } }
.footer h5 { color: #fff; font-size: 11px; letter-spacing: .2em; text-transform: uppercase; margin-bottom: 13px; font-weight: 800; }
.footer li { margin-bottom: 8px; }
.footer__brand p { max-width: 320px; margin-top: 12px; }
.footer__addr { font-style: normal; margin-top: 14px; line-height: 1.75; }
.footer__addr a { color: #fff; font-weight: 700; border-bottom: 1px solid rgba(255,255,255,.28); }
.footer__addr a:hover { color: var(--o); border-bottom-color: var(--o); }
.footer__bottom {
  margin-top: 40px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.11);
  display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap; font-size: 12.5px;
}

/* ============================================================== signup modal
   A three-step dialog: offer, email, profile. Landscape on desktop (copy left,
   art right), stacked on mobile (copy above art) — one grid, two axes.

   Steps are sibling <section>s toggled by [hidden] rather than separate
   dialogs, so focus management, the scrim and the escape hatch are written
   once and every step inherits them. */
.sgn__scrim { position: fixed; inset: 0; background: rgba(22,22,26,.6); z-index: 500; animation: sgnfade .22s ease; }
.sgn {
  position: fixed; z-index: 501; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(940px, calc(100vw - 40px)); max-height: min(90vh, 680px);
  background: var(--surface); border-radius: 18px; overflow: hidden;
  box-shadow: var(--shadow-lg); animation: sgnpop .26s cubic-bezier(.22,1,.36,1);
  /* The row has to be minmax(0, 1fr), and this has to be a grid, for the panel
     inside to inherit a bounded height. With only max-height set, the inner
     `height: 100%` had nothing definite to resolve against, so the panel grew
     to its content — 859px inside a 629px modal — and overflow:hidden clipped
     the Finish button clean off the bottom with no way to scroll to it. */
  display: grid; grid-template-rows: minmax(0, 1fr);
}
/* [hidden] has to beat the layout rules above — the same specificity trap that
   once left the review drawer permanently mounted off-screen. */
.sgn[hidden], .sgn__scrim[hidden] { display: none; }
@keyframes sgnfade { from { opacity: 0 } to { opacity: 1 } }
@keyframes sgnpop { from { opacity: 0; transform: translate(-50%, -46%) scale(.97) } to { opacity: 1; transform: translate(-50%, -50%) scale(1) } }
@media (prefers-reduced-motion: reduce) { .sgn, .sgn__scrim { animation: none; } }

.sgn__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .82fr); min-height: 0; }
.sgn__panel {
  padding: 28px 40px 30px; display: flex; flex-direction: column;
  overflow-y: auto; min-height: 0;
  /* The brand is pinned to the top; the centring moved down to .sgn__steps. */
  justify-content: flex-start;
}
/* Takes the leftover height and centres the active step inside it, so a short
   step still sits optically centred in the box while the mark stays put.
   Centred when the step is short, top-aligned when it is not: plain `center`
   makes the overflowing top of a tall step unreachable — `safe` exists for
   exactly this, and the flex-start above it is the fallback for browsers that
   do not know the keyword. */
.sgn__steps {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  justify-content: flex-start;
  justify-content: safe center;
}
/* Brand lockup at the top of the panel. It rides in the centred flex stack
   rather than being pinned to the box, so a short step stays optically centred
   instead of leaving a hole between the mark and the headline.
   `flex-shrink: 0` because the panel is a scrolling column and a 32px mark is
   the first thing flex would squash on a short viewport. */
.sgn__brand { align-self: flex-start; flex-shrink: 0; margin-bottom: 20px; }
/* The header hides the wordmark under 400px to protect the burger. The modal
   has the full width to itself, so the mark keeps its name here. */
.sgn__brand .logo-txt { display: block; }

.sgn__x {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.92); color: var(--ink); border: 1px solid var(--border);
}
.sgn__x:hover { background: var(--ink); color: #fff; border-color: var(--ink); }
.sgn__x svg { width: 18px; height: 18px; }

.sgn__step[hidden] { display: none; }
.sgn__eyebrow { font-size: 10px; font-weight: 900; letter-spacing: .22em; text-transform: uppercase; color: var(--muted-2); margin-bottom: 12px; }
.sgn__big {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(44px, 5.5vw, 70px); line-height: .92; letter-spacing: .01em;
}
.sgn__big em { font-style: normal; color: var(--o); }
.sgn__mid {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(26px, 3vw, 36px); line-height: 1.02;
}
.sgn__mid em { font-style: normal; color: var(--o); }
.sgn__sub { color: var(--muted); font-size: 15px; margin: 12px 0 22px; }
.sgn__sub--tight { margin-bottom: 16px; }

/* The step-1 question. Sized to read as the thing being asked rather than as
   supporting copy — it is the only decision on the screen, and the two buttons
   under it are its answers. */
.sgn__ask {
  font-size: 19px; font-weight: 800; line-height: 1.3; color: var(--ink);
  margin: 18px 0 18px; letter-spacing: -.005em;
}

/* The "already on Faire" answer. Deliberately the same quiet treatment the
   dismiss button used to have, so the two answers do not read as a recommended
   one and a consolation prize — but it is a real choice, so it lights orange
   on hover rather than going ink like a plain ghost button. */
.sgn__step [data-faire-status="existing"]:hover { color: var(--o); border-color: var(--o); background: #fff; }

/* Segmented copy. Step 1 sets data-faire on the modal root and everything
   marked data-seg shows or hides from that one attribute — no per-element JS,
   and nothing leaks before the question is answered. */
.sgn:not([data-faire]) [data-seg] { display: none; }
.sgn[data-faire="new"] [data-seg="existing"] { display: none; }
.sgn[data-faire="existing"] [data-seg="new"] { display: none; }

.sgn__perks { list-style: none; margin: 14px 0 4px; padding: 0; display: grid; gap: 9px; }
.sgn__perks li {
  position: relative; padding-left: 24px; font-size: 14.5px; line-height: 1.5; color: var(--muted);
}
.sgn__perks li::before {
  content: ''; position: absolute; left: 0; top: 7px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--o);
}
.sgn__perks b { color: var(--ink); font-weight: 800; }

.sgn .btn--block + .btn--block { margin-top: 9px; }
.sgn__yes { margin-top: 26px; }
/* The decline is deliberately quiet but never hidden — a modal with no visible
   way out is the pattern this one is trying not to be. */
.btn--ghost { background: transparent; color: var(--ink); border: 1.5px solid var(--border); font-weight: 700; }
.btn--ghost:hover { border-color: var(--ink); background: #fff; }

.sgn__proof { text-align: center; margin: 24px 0 0; }
.sgn__proof .stars { font-size: 19px; }
.sgn__proof p { font-size: 13px; font-weight: 800; margin-top: 5px; }
.sgn__fine { font-size: 11px; color: var(--muted-2); line-height: 1.6; margin-top: 18px; }

/* Fields: the shared .field styles are written for the dark capture section, so
   inside this light panel they need ink text and a visible border. */
.sgn .field { margin-bottom: 12px; }
.sgn .field label, .sgn__int legend {
  color: var(--ink); font-size: 11px; font-weight: 900; letter-spacing: .12em;
  text-transform: uppercase; display: block; margin-bottom: 6px; padding: 0;
}
.sgn .field input, .sgn .field select, .sgn .field textarea {
  width: 100%; background: #fff; color: var(--ink); border: 1.5px solid var(--border);
  border-radius: 10px; padding: 12px; font: inherit; font-size: 15px;
}
.sgn .field input:focus { outline: none; border-color: var(--o); box-shadow: 0 0 0 3px var(--o-soft); }
.sgn .field input[aria-invalid="true"] { border-color: #C0341B; }
.sgn .lbl-opt { text-transform: none; letter-spacing: 0; font-weight: 600; color: var(--muted-2); }
.sgn .form-msg { color: var(--ink); font-size: 13px; margin-top: 10px; min-height: 0; }
.sgn .form-msg[data-state="error"] { color: #C0341B; }
.sgn .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }
.sgn .field--full { grid-column: 1 / -1; }

/* Step 3 carries six inputs plus twelve chips. Everything on it is deliberately
   one notch tighter than the rest of the site so the whole step still reads as
   one short form rather than a second sign-up. */
.sgn__step[data-step="3"] .field { margin-bottom: 10px; }
.sgn__step[data-step="3"] .field label,
.sgn__step[data-step="3"] .sgn__int legend { font-size: 10px; letter-spacing: .1em; margin-bottom: 4px; }
.sgn__step[data-step="3"] .field input,
.sgn__step[data-step="3"] .field select,
.sgn__step[data-step="3"] .field textarea { padding: 9px 11px; font-size: 14px; }
.sgn .field textarea { width: 100%; resize: vertical; min-height: 44px; font: inherit; font-size: 14px;
  background: #fff; color: var(--ink); border: 1.5px solid var(--border); border-radius: 10px; padding: 9px 11px; }
.sgn .field textarea:focus { outline: none; border-color: var(--o); box-shadow: 0 0 0 3px var(--o-soft); }
.sgn .field select { appearance: auto; }

/* Step 3 is taller than the modal, so the submit sits below the fold and the
   step reads as having no button at all — which is exactly how it was reported.
   Pinning it to the bottom of the scroller keeps the primary action on screen
   at every scroll position. The wrapper is what sticks, not the button: sticky
   resolves against the nearest scrolling ancestor but is bounded by its own
   containing block, and the button's block is only as tall as the button. */
.sgn__step[data-step="3"] .form-grid > .field--full:last-child {
  position: sticky; bottom: 0; z-index: 1; margin-bottom: 0;
  padding: 10px 0 2px; background: var(--surface);
  box-shadow: 0 -10px 14px -8px rgba(22,22,26,.16);
}

.sgn__int { border: 0; padding: 0; margin: 0 0 10px; min-width: 0; }
.sgn__chips { display: flex; flex-wrap: wrap; gap: 5px; }
.sgn__chip { position: relative; }
/* The checkbox keeps keyboard focus and stays in the a11y tree; the label is
   what gets painted. */
.sgn__chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.sgn__chip span {
  display: block; padding: 5px 10px; border: 1.5px solid var(--border); border-radius: 999px;
  font-size: 11.5px; font-weight: 700; cursor: pointer; transition: .14s; background: #fff;
  white-space: nowrap;
}
.sgn__chip span:hover { border-color: var(--ink); }
.sgn__chip input:checked + span { background: var(--ink); color: #fff; border-color: var(--ink); }
.sgn__chip input:focus-visible + span { outline: 2px solid var(--o); outline-offset: 2px; }

.sgn__done { text-align: center; }
.sgn__done [data-signup-email] { font-weight: 800; color: var(--ink); word-break: break-word; }
.sgn__fine--tick { margin-top: 16px; }
.sgn__fine--tick a { color: var(--muted); font-weight: 700; border-bottom: 1px solid var(--o); }
.sgn__tick {
  width: 54px; height: 54px; border-radius: 50%; background: var(--o); color: #fff;
  display: grid; place-items: center; margin: 0 auto 18px;
}
.sgn__tick svg { width: 27px; height: 27px; }

/* Art panel — photo at its own proportions, then a dark block carrying the
   wordmark and the retailer quote.

   The photo is square and the panel is tall, so something has to give: `cover`
   scaled the source up ~50% and shoved the subject's face against the frame,
   and `contain` left a dead band underneath. Letting the image size itself and
   filling the remainder with the wordmark and a larger quote turns that band
   into the part of the panel that actually says something. */
.sgn__art { position: relative; background: var(--ink); overflow: hidden; display: flex; flex-direction: column; }
.sgn__art > img { width: 100%; height: auto; display: block; flex: 0 0 auto; }
.sgn__artfoot {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; justify-content: center; gap: 16px;
  padding: 22px 24px 26px;
}
.sgn__logo {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: 21px; letter-spacing: .045em; line-height: 1; color: #fff;
}
.sgn__logo em { font-style: normal; color: var(--o); }
.sgn__quote blockquote {
  font-size: 17px; line-height: 1.42; color: #fff; font-weight: 600;
  /* A hanging orange rule instead of a card — the panel is already dark. */
  border-left: 3px solid var(--o); padding-left: 14px;
}
.sgn__quote figcaption {
  font-size: 12px; line-height: 1.5; color: #B7B2A9; margin-top: 10px;
  font-weight: 700; padding-left: 17px;
}

@media (max-width: 820px) {
  /* Stacked: copy first, art below — matching the reference layout and keeping
     the offer above the fold on a short screen. */
  .sgn { width: 100vw; max-width: 100vw; max-height: 92vh; border-radius: 18px 18px 0 0;
         top: auto; bottom: 0; transform: translate(-50%, 0); overflow-y: auto; }
  @keyframes sgnpop { from { opacity: 0; transform: translate(-50%, 16px) } to { opacity: 1; transform: translate(-50%, 0) } }
  .sgn__grid { grid-template-columns: 1fr; height: auto; }
  .sgn__panel { padding: 22px 20px 22px; overflow: visible; }
  /* The aspect ratio moves to the image: the panel is now a column, and
     constraining the whole column would squash the wordmark and quote.

     The flex priorities invert here. On desktop the photo keeps its natural
     size and the text block fills what is left. On a wide-but-short mobile
     panel a 16:10 photo is taller than the panel itself, so the text block is
     the one that must keep its height and the photo is what gives — otherwise
     the quote gets crushed to a 40px sliver at tablet widths. */
  .sgn__art > img {
    aspect-ratio: 16 / 10; object-fit: cover; object-position: center 30%;
    flex: 1 1 auto; min-height: 0; max-height: 300px;
  }
  .sgn__artfoot { flex: 0 0 auto; padding: 18px 20px 22px; gap: 13px; }
  .sgn__quote blockquote { font-size: 15.5px; }
  .sgn__big { font-size: clamp(38px, 12.5vw, 54px); }
  /* 16px stops iOS zooming the page when a field takes focus. Step 3 shrinks
     its fields to fit six of them, so it needs the same selector weight to win
     the size back — it is the densest step and the one most likely to be
     tapped through on a phone. */
  .sgn .field input,
  .sgn__step[data-step="3"] .field input,
  .sgn__step[data-step="3"] .field select,
  .sgn__step[data-step="3"] .field textarea { font-size: 16px; }
  .sgn .form-grid { grid-template-columns: 1fr; }
  .sgn__panel { padding-bottom: calc(22px + env(safe-area-inset-bottom)); }
}
/* Very short viewports: the art is the first thing that can go. */
@media (max-height: 620px) and (min-width: 821px) {
  .sgn { max-height: 96vh; }
  .sgn__panel { padding: 26px 32px 22px; }
  .sgn__brand { margin-bottom: 14px; }
}

/* A button that reads as a link — used inside FAQ prose to open the modal. */
.lnk-btn { color: var(--ink); font: inherit; font-weight: 700; border-bottom: 1.5px solid var(--o); padding: 0; background: none; }
.lnk-btn:hover { color: var(--o); }

/* ========================================================== decorator landing
   Class prefix is `hb-` for historical reasons: this page launched as the hat
   bar landing page before it was broadened to all four decorator segments. */
.hb-hero { background: var(--ink); color: #fff; position: relative; overflow: hidden; }
.hb-hero::after {
  content: ''; position: absolute; inset: auto -10% -60% 52%; height: 480px;
  background: radial-gradient(closest-side, rgba(242,101,34,.30), transparent 70%);
  pointer-events: none;
}
/* Columns and gap deliberately identical to `.hero__inner`: the deck takes the
   larger side so its cards render at their full 400px rather than being scaled
   down to fit a narrow column. Changing this ratio changes the card size. */
.hb-hero__inner {
  position: relative; z-index: 1; display: grid;
  grid-template-columns: minmax(0, .7fr) minmax(0, 1fr);
  gap: 28px; align-items: center; padding-top: 54px; padding-bottom: 58px;
}
/* Same ramp as `.hero h1`. It has to be: the copy column is the narrower half
   of the grid now, and at the old 68px "putting a stitch in." wrapped and left
   "IN." alone on a third line. */
.hb-hero h1 { font-size: clamp(32px, 4.5vw, 59px); }
.hb-hero__lede { font-size: 16px; color: #D9D5CE; max-width: 520px; margin: 18px 0 26px; }
/* Row layout and the pointer itself are shared with the homepage callout —
   see "offer callout pointer" further up. This is just the spacing and the
   button's own look. */
.hb-hero__note { margin-top: 18px; }
.hb-hero__cta {
  background: none; padding: 0; border: 0; color: #fff; font: inherit;
  font-size: 14px; font-weight: 700;
  border-bottom: 1.5px solid var(--o); transition: color .16s ease;
}
.hb-hero__cta:hover { color: var(--o); }
/* Deliberately keyed to the still's own class, not `.hb-hero__art img`: the
   coverflow's card images are also imgs inside this container, and a bare
   descendant selector declared this late in the file would win over
   `.cflow__card img` on source order and put an 18px radius and a drop shadow
   on every frame of the deck. */
.hb-hero__still {
  width: 100%; height: auto; aspect-ratio: 1/1; object-fit: cover;
  border-radius: 18px; box-shadow: 0 22px 52px rgba(0,0,0,.42);
}
/* The deck carries the hero above its breakpoint; the still takes over below,
   where `.cflow` is display:none. Same 940/941 line as the homepage. */
.hb-hero__still { display: none; }
@media (max-width: 940px) {
  .hb-hero__still { display: block; }
}
@media (max-width: 900px) {
  .hb-hero__inner { grid-template-columns: 1fr; gap: 28px; padding-top: 40px; padding-bottom: 44px; }
  .hb-hero__art { max-width: 420px; }
}

.proof--tight .proof__item { padding: 16px 14px; }

/* Colorway showcase — a wall of real brims rather than one product card, for
   the two styles where the range is the thing being chosen. */
.showcase + .showcase { margin-top: 46px; }
.showcase__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap; margin-bottom: 18px;
  padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.showcase__kicker { display: block; font-size: 11px; font-weight: 900; letter-spacing: .16em; text-transform: uppercase; color: var(--muted-2); margin-bottom: 5px; }
.showcase__head h3 { font-family: var(--font-display); font-weight: 400; text-transform: uppercase; font-size: clamp(22px, 2.4vw, 30px); line-height: 1; }


/* Featured retailer quote on the reviews page. Styled distinctly from the
   review cards below it — this one is a direct testimonial, not a Faire review,
   and it should not read as another card in that set. */
.feat-quote {
  background: var(--ink); color: #fff; border-radius: var(--r);
  padding: 30px 34px; margin: 0;
}
.feat-quote__kicker {
  display: inline-block; margin-bottom: 14px; font-size: 10.5px; font-weight: 800;
  letter-spacing: .2em; text-transform: uppercase; color: var(--o);
}
.feat-quote blockquote {
  margin: 0; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(19px, 2.2vw, 26px); line-height: 1.34; color: #fff;
}
.feat-quote figcaption {
  margin-top: 16px; font-size: 12.5px; font-weight: 700;
  letter-spacing: .06em; color: #B7B2A9;
}
.feat-quote figcaption strong { color: #fff; font-weight: 800; }
.feat-quote figcaption .sep { color: var(--o); }
@media (max-width: 620px) { .feat-quote { padding: 24px 22px; } }

.hb-quote { text-align: center; padding: 8px 0; }
.hb-quote blockquote {
  font-family: var(--font-display); font-weight: 400; font-size: clamp(20px, 2.6vw, 30px);
  line-height: 1.32; color: var(--ink);
}
.hb-quote figcaption { margin-top: 16px; font-size: 13px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--muted-2); }

/* ================================================================= FAQ + contact
   The accordion is <details>/<summary> — open/close is the browser's job, so it
   works with no JS, is keyboard-operable for free, and survives find-in-page. */
.sec-head--center { justify-content: center; text-align: center; }
.sec-head--center p { margin-left: auto; margin-right: auto; }

/* Reference material, not a pitch. Every row starts collapsed and the whole
   block is deliberately quiet — eleven questions at display-heading scale ran
   longer than the catalog it was meant to support. */
.section--tight { padding-top: 34px; padding-bottom: 34px; }
.faq__h {
  font-size: 12px; font-weight: 900; letter-spacing: .18em; text-transform: uppercase;
  color: var(--muted-2); margin-bottom: 4px;
}
.faq { border-top: 1px solid var(--border); }
.faq__item { border-bottom: 1px solid var(--border); }
.faq__item > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 12px 2px; cursor: pointer; list-style: none;
  font-weight: 700; font-size: 14.5px; line-height: 1.4; color: var(--ink);
}
.faq__item > summary::-webkit-details-marker { display: none; }
/* Drawn rather than a glyph: a rotating cross keeps its optical weight at any
   size, where +/- characters jump around between fonts. */
.faq__item > summary::after {
  content: ''; flex: 0 0 auto; width: 11px; height: 11px;
  background:
    linear-gradient(var(--o), var(--o)) center/100% 2px no-repeat,
    linear-gradient(var(--o), var(--o)) center/2px 100% no-repeat;
  transition: transform .22s ease;
}
.faq__item[open] > summary::after { transform: rotate(45deg); }
.faq__item[open] > summary { color: var(--o); }
.faq__item > summary:hover { color: var(--o); }
.faq__a { padding: 0 40px 15px 2px; }
.faq__a p { color: var(--muted); font-size: 14px; line-height: 1.68; }
.faq__a a { color: var(--ink); font-weight: 700; border-bottom: 1.5px solid var(--o); }
.faq__a a:hover { color: var(--o); }
.faq__foot { margin-top: 16px; font-size: 13px; color: var(--muted-2); }
.faq__foot a { color: var(--muted); font-weight: 700; border-bottom: 1px solid var(--o); }
.faq__foot a:hover { color: var(--o); }
@media (max-width: 560px) {
  .faq__item > summary { font-size: 14px; padding: 13px 2px; gap: 12px; }
  .faq__a { padding-right: 6px; }
}

.contact-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin: 30px 0 8px; }
@media (max-width: 700px) { .contact-grid { grid-template-columns: 1fr; } }
.ccard {
  border: 1px solid var(--border); border-radius: var(--r); padding: 24px;
  background: #fff; transition: border-color .18s ease, box-shadow .18s ease;
}
.ccard:hover { border-color: var(--o); box-shadow: 0 0 0 1px var(--o), 0 0 18px rgba(242,101,34,.16); }
.ccard__ic { width: 38px; height: 38px; border-radius: 10px; background: var(--o); color: #fff; display: grid; place-items: center; margin-bottom: 14px; }
.ccard__ic svg { width: 20px; height: 20px; }
.ccard h3 { font-size: 12px; letter-spacing: .16em; text-transform: uppercase; font-weight: 900; color: var(--muted-2); margin-bottom: 9px; }
.ccard address { font-style: normal; font-size: 16px; font-weight: 700; line-height: 1.65; }
.ccard p { color: var(--muted); font-size: 14.5px; line-height: 1.65; margin-top: 8px; }
.ccard__who { font-size: 12.5px; font-weight: 800; color: var(--ink); margin-top: 10px; letter-spacing: .01em; }
.ccard a.big { font-size: 16px; font-weight: 800; border-bottom: 2px solid var(--o); word-break: break-word; }
.ccard a.big:hover { color: var(--o); }

/* ============================================================== catalog page */
.catalog { display: grid; grid-template-columns: 258px minmax(0,1fr); gap: 34px; align-items: start; }
@media (max-width: 900px) { .catalog { grid-template-columns: 1fr; gap: 18px; } }

.page-head { padding: 34px 0 24px; border-bottom: 1px solid var(--border); }
.page-head h1 { font-family: var(--font-display); font-weight: 400; text-transform: uppercase; font-size: clamp(30px, 4.4vw, 52px); line-height: 1.03; }
.page-head p { color: var(--muted); margin-top: 10px; max-width: 700px; }
.crumbs { font-size: 12px; color: var(--muted-2); font-weight: 600; margin-bottom: 12px; }
.crumbs a:hover { color: var(--o); }

.filters { position: sticky; top: calc(var(--hdr) + 12px); }
@media (max-width: 900px) {
  .filters { position: static; display: none; border: 1px solid var(--border); border-radius: var(--r); padding: 16px; }
  .filters.is-open { display: block; }
}
.fgroup { border-bottom: 1px solid var(--border); padding: 14px 0; }
.fgroup:first-child { padding-top: 0; }
.fgroup > summary {
  display: flex; justify-content: space-between; align-items: center; cursor: pointer;
  font-size: 11.5px; font-weight: 900; letter-spacing: .14em; text-transform: uppercase; list-style: none;
}
.fgroup > summary::-webkit-details-marker { display: none; }
.fgroup > summary::after { content: '−'; color: var(--o); font-size: 17px; }
.fgroup:not([open]) > summary::after { content: '+'; }
.fgroup__body { padding-top: 11px; display: flex; flex-direction: column; gap: 2px; max-height: 260px; overflow-y: auto; }
.fopt { display: flex; align-items: center; gap: 9px; padding: 5px 4px; border-radius: 6px; cursor: pointer; font-size: 13.5px; }
.fopt:hover { background: var(--surface); }
.fopt input { width: 15px; height: 15px; accent-color: var(--o); cursor: pointer; flex: 0 0 auto; }
.fopt .n { margin-left: auto; font-size: 11.5px; color: var(--muted-2); font-weight: 600; }
.fopt.is-empty { opacity: .38; }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 18px 0; }
.chip {
  display: inline-flex; align-items: center; gap: 7px; padding: 7px 13px; border-radius: 999px;
  border: 1.5px solid var(--border); font-size: 12.5px; font-weight: 700; background: #fff;
  transition: .14s;
}
/* Orange on hover, matching the review cards. The selected chip keeps its ink
   fill — hovering the one you are already on should not un-signal it. */
.chip:hover { border-color: var(--o); }
.chip[aria-pressed="true"], .chip[aria-current="page"] { background: var(--ink); color: #fff; border-color: var(--ink); }
.chip[aria-pressed="true"]:hover, .chip[aria-current="page"]:hover { border-color: var(--o); }
/* Count inside a chip — present but secondary, so the label reads first. */
.chip__n { color: var(--muted-2); font-weight: 800; }

/* Decorators page: the two ways in, sat between the hero and the first
   section. Label and chips share a baseline row and wrap together on mobile. */
.dec-nav { padding-top: 30px; }
.dec-nav .demo:first-child { padding-top: 0; }
.demo { display: flex; align-items: center; gap: 8px 18px; flex-wrap: wrap; padding-top: 30px; }
.demo__label { font-size: 21px; line-height: 1; }
.demo .chips { margin: 0; }
@media (max-width: 620px) { .demo { gap: 6px 12px; padding-top: 24px; } .demo__label { font-size: 19px; } }
.chip .n { color: var(--muted-2); font-size: 11px; }
.chip[aria-pressed="true"] .n, .chip[aria-current="page"] .n { color: rgba(255,255,255,.65); }
.chip--clear { border-style: dashed; color: var(--o-dark); border-color: var(--o); }

/* Quick-chip icons. One color per segment — emoji couldn't be recolored, so
   these are inline SVG tinted here. On a selected (ink) chip the tint would
   go muddy, so it flips to white. */
.chip--ico { gap: 6px; }
.qi { display: inline-flex; width: 16px; height: 16px; flex: 0 0 auto; }
.qi svg { width: 100%; height: 100%; }
.qi--women     { color: #DB2777; }
.qi--men       { color: #2563EB; }
.qi--kids      { color: #16A34A; }
.qi--baby      { color: #F59E0B; }
.qi--unisex    { color: #7C3AED; }
.qi--mommy-and-me { color: #DB2777; }
.qi--winter    { color: #38BDF8; }
.qi--summer    { color: #F59E0B; }
.qi--year-round{ color: #14B8A6; }
/* Kids and Baby read younger at a smaller mark. */
.qi--kids  { width: 14px; height: 14px; }
.qi--baby  { width: 12px; height: 12px; }
.chip[aria-pressed="true"] .qi, .chip[aria-current="page"] .qi { color: #fff; }

.toolbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 0; border-bottom: 1px solid var(--border); margin-bottom: 20px;
}
.toolbar .count { font-size: 13px; font-weight: 700; color: var(--muted); }
.toolbar select, .searchbox input {
  padding: 9px 12px; border: 1.5px solid var(--border); border-radius: var(--r-sm);
  background: #fff; font-size: 13.5px; font-weight: 600;
}
.searchbox { position: relative; flex: 1 1 240px; max-width: 380px; }
.searchbox input { width: 100%; padding-left: 34px; }
.searchbox svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--muted-2); }
.filter-toggle { display: none; }
@media (max-width: 900px) { .filter-toggle { display: inline-flex; } }

.empty { text-align: center; padding: 70px 20px; color: var(--muted); }
.empty h3 { font-family: var(--font-display); font-size: 26px; text-transform: uppercase; color: var(--ink); margin-bottom: 8px; }
.load-more { display: flex; justify-content: center; padding: 34px 0 10px; }

/* ================================================================ PDP */
/* minmax(0, …) rather than a bare fr: an fr track's automatic minimum is
   min-content, and the gallery's eight side-by-side slides made that far wider
   than the phone — the column grew to 488px inside a 350px page and took the
   whole document's horizontal scroll with it. The 0 minimum lets the track
   scroll internally, which is the entire point of a scroll-snap carousel. */
.pdp { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 48px; padding: 30px 0 20px; align-items: start; }
.pdp > * { min-width: 0; }
@media (max-width: 940px) { .pdp { grid-template-columns: minmax(0, 1fr); gap: 26px; } }
/* contain-fit gallery on white — never crops the product */
/* The track is a native horizontal scroller with snap points — that is what
   makes the finger swipe feel like the platform's own rather than a JS
   approximation. scroll-snap-stop keeps a hard fling from skipping photos. */
.gallery__main { position: relative; border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; background: #fff; }
.gallery__track {
  display: flex; aspect-ratio: 1/1;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
  scrollbar-width: none; -ms-overflow-style: none;
  /* The browser owns horizontal panning; the page still owns vertical, so a
     mostly-vertical drag scrolls the page instead of trapping the finger. */
  touch-action: pan-x pan-y;
  overscroll-behavior-x: contain;
}
.gallery__track::-webkit-scrollbar { display: none; }
.gallery__track:focus-visible { outline: 2px solid var(--o); outline-offset: -3px; }
.gallery__slide { flex: 0 0 100%; scroll-snap-align: center; scroll-snap-stop: always; }
.gallery__slide img { display: block; width: 100%; height: 100%; object-fit: contain; padding: 14px; }

.gallery__arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.94); color: var(--ink); border: 1px solid var(--border);
  box-shadow: var(--shadow-sm); opacity: 0; transition: opacity .16s ease, background .16s ease;
}
.gallery__arrow svg { width: 19px; height: 19px; }
.gallery__arrow--prev { left: 10px; }
.gallery__arrow--next { right: 10px; }
.gallery__arrow:hover { background: #fff; color: var(--o); border-color: var(--o); }
.gallery__main:hover .gallery__arrow:not([hidden]) { opacity: 1; }
.gallery__arrow:focus-visible { opacity: 1; outline: 2px solid var(--o); outline-offset: 2px; }
/* Arrows are a pointer affordance. On touch the swipe is the interaction and
   the dots are the indicator, so they would only cover the photo. */
@media (hover: none) { .gallery__arrow { display: none; } }

.gallery__dots { display: none; }
.gallery__thumbs { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.gallery__thumbs button { width: 62px; height: 62px; border-radius: var(--r-sm); overflow: hidden; border: 2px solid var(--border); background: #fff; flex: 0 0 auto; }
.gallery__thumbs button[aria-current="true"] { border-color: var(--o); }
.gallery__thumbs img { width: 100%; height: 100%; object-fit: contain; }

@media (max-width: 760px) {
  /* Dots replace the thumb strip as the position indicator: at this width eight
     62px thumbs wrap to two rows and push the price below the fold. */
  .gallery__dots { display: flex; gap: 7px; justify-content: center; padding: 12px 0 2px; }
  .gallery__dots[hidden] { display: none; }
  .gallery__dots button {
    width: 7px; height: 7px; border-radius: 50%; background: var(--border);
    padding: 0; transition: background .18s ease, width .18s ease;
  }
  .gallery__dots button[aria-current="true"] { background: var(--o); width: 20px; border-radius: 4px; }
  .gallery__thumbs {
    flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity;
    scrollbar-width: none; margin-top: 8px; padding-bottom: 2px;
  }
  .gallery__thumbs::-webkit-scrollbar { display: none; }
  .gallery__thumbs button { width: 54px; height: 54px; scroll-snap-align: start; }
}

/* Faire credential above the product title — Top Shop status and the rating,
   clickable through to the storefront. Bare text, no chrome: it is a
   credential, not a button. `flex` (not inline-flex) so the script eyebrow
   below it starts its own line. */
.brandbar {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-bottom: 4px; font-size: 13px; color: var(--muted); width: fit-content;
}
.brandbar:hover .brandbar__count { color: var(--ink); }
.brandbar__badge { display: inline-flex; align-items: center; gap: 4px; font-weight: 800; color: var(--ink); }
.brandbar__badge svg { width: 15px; height: 15px; color: var(--ink); }
.brandbar__rating { font-weight: 800; color: var(--ink); }
.brandbar__rating .star { color: #F5B301; }
.brandbar__count { color: var(--muted-2); text-decoration: underline; text-underline-offset: 2px; }

.pdp__kicker { display: block; font-size: 24px; color: var(--o); transform: rotate(-1.5deg); transform-origin: left center; }
.pdp__sub { font-size: 15px; font-weight: 600; color: var(--muted); margin: -4px 0 12px; }
.pdp h1 { font-family: var(--font-display); font-weight: 400; text-transform: uppercase; font-size: clamp(28px, 3.6vw, 44px); line-height: 1.04; margin: 4px 0 10px; }
/* Sits under the rating line, so it needs air above it as well as below. */
.pdp__badges { display: flex; gap: 7px; flex-wrap: wrap; margin: 12px 0 16px; }
.pill {
  font-size: 10.5px; font-weight: 900; letter-spacing: .1em; text-transform: uppercase;
  padding: 5px 10px; border-radius: 999px; color: #fff;
}
.pill--bestseller { background: var(--o); }
.pill--reordered  { background: #0E6E6E; }
.pill--trending   { background: var(--ink); }
.pill--new        { background: #6B3FD4; }
.pill--seasonal   { background: var(--gold); }
.pill--sale       { background: var(--sale); }
.pill--aud-adult  { background: var(--aud-adult); font-size: 11.5px; padding: 6px 13px; }
.pill--aud-kids   { background: var(--aud-kids); font-size: 11.5px; padding: 6px 13px; }
.pill--aud-mm     { background: var(--aud-mm); font-size: 11.5px; padding: 6px 13px; }

.priceblock { display: flex; gap: 26px; flex-wrap: wrap; align-items: flex-end; padding: 18px 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); margin: 16px 0 18px; }
.priceblock .p b { display: block; font-family: var(--font-display); font-size: 32px; line-height: 1; }
.priceblock .p span { font-size: 11px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-2); }
/* MSRP is struck through — you pay wholesale, it retails for more */
.priceblock .p--msrp b { color: var(--muted); font-size: 26px; }
.priceblock .p--msrp s { text-decoration-color: var(--o); text-decoration-thickness: 2px; }
.priceblock .p--onsale b { color: var(--sale); }
.priceblock .p--was b { color: var(--muted); font-size: 26px; }
.priceblock .p--was s { text-decoration-color: var(--sale); text-decoration-thickness: 2px; }
.priceblock .p--was[hidden] { display: none; }
/* Sale nav sits in FJ orange. Markdown prices and the Sale badge stay in the
   deeper red so a discount never reads as the "Trending" orange badge. */
.nav li.nav__sale > a { color: var(--o); }
.mnav__sale { color: var(--o) !important; }

.optrow { margin-bottom: 18px; }
.optrow__label { font-size: 11.5px; font-weight: 900; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 9px; display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap; }
.optrow__label span { font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--muted); font-size: 13px; }
.optrow__label .optrow__n { margin-left: auto; font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted-2); }
.opts { display: flex; gap: 7px; flex-wrap: wrap; }
.opt {
  border: 1.5px solid var(--border); border-radius: 999px; padding: 8px 14px; font-size: 13px;
  font-weight: 700; background: #fff; transition: .14s; max-width: 100%;
}
.opt:hover { border-color: var(--ink); }
.opt[aria-pressed="true"] { background: var(--ink); color: #fff; border-color: var(--ink); }
.opt[disabled] { opacity: .34; cursor: not-allowed; text-decoration: line-through; }
.opt--sw { padding: 0; width: 42px; height: 42px; border-radius: 50%; overflow: hidden; }
/* Same reasoning as .swx img — `contain` keeps a wide product like sunglasses
   whole inside the circle so the colorway is actually readable. */
.opt--sw img { width: 100%; height: 100%; object-fit: contain; padding: 3px; background: #fff; }
.opt--sw[aria-pressed="true"] { border-width: 3px; border-color: var(--o); }
/* Families like The Statement Snapback carry 100+ designs — keep the grid
   browsable with its own scroll instead of a mile-long page. */
.opts--swatchgrid { max-height: 232px; overflow-y: auto; padding: 2px; }

/* The colorway picker is the main thing a buyer touches on a phone. Bigger
   circles, bigger pills, and a taller scroll window so the grid does not become
   a letterbox once the swatches grow. */
@media (max-width: 760px) {
  .opts { gap: 9px; }
  .opt { padding: 11px 17px; font-size: 14px; }
  .opt--sw { width: 54px; height: 54px; padding: 0; }
  .opt--sw img { padding: 4px; }
  .opts--swatchgrid { max-height: 292px; }
}

.buybox { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); padding: 20px; }
.buybox__sku { font-size: 12px; color: var(--muted); margin-bottom: 12px; display: flex; gap: 12px; flex-wrap: wrap; }
.buybox__sku code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; background: #fff; padding: 2px 7px; border-radius: 5px; border: 1px solid var(--border); }
.buybox .btn + .btn { margin-top: 9px; }
.buybox__note { font-size: 11.5px; color: var(--muted-2); margin-top: 11px; text-align: center; }

.specs { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; margin: 20px 0; }
.specs div { background: #fff; padding: 13px 15px; }
.specs dt { font-size: 10.5px; font-weight: 900; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-2); }
.specs dd { font-size: 14.5px; font-weight: 700; margin-top: 3px; }

.selling { background: var(--proof-bg); border: 1px solid #C9E5DA; border-radius: var(--r); padding: 20px; margin: 20px 0; }
.selling h3 { font-size: 12px; font-weight: 900; letter-spacing: .14em; text-transform: uppercase; color: var(--proof); margin-bottom: 13px; }
.selling__grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 14px; }
@media (max-width: 560px) { .selling__grid { grid-template-columns: repeat(2, minmax(0,1fr)); } .specs { grid-template-columns: 1fr; } }
.selling__grid b { display: block; font-family: var(--font-display); font-size: 26px; line-height: 1; color: var(--ink); }
.selling__grid span { font-size: 11.5px; color: var(--muted); font-weight: 600; }
.selling__note { font-size: 11.5px; color: var(--muted); margin-top: 13px; }
.selling__tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 13px; }

.prose { max-width: 760px; }
.prose h2 { font-family: var(--font-display); font-weight: 400; text-transform: uppercase; font-size: 28px; margin: 34px 0 12px; }
.prose h3 { font-size: 17px; font-weight: 800; margin: 26px 0 8px; }
.prose p { margin-bottom: 14px; color: var(--ink); }
.prose ul { margin: 0 0 16px 0; }
.prose ul li { position: relative; padding-left: 20px; margin-bottom: 8px; }
.prose ul li::before { content: ''; position: absolute; left: 0; top: 9px; width: 7px; height: 7px; border-radius: 50%; background: var(--o); }
.prose .lede { font-size: 18px; color: var(--muted); }

.acc { border-top: 1px solid var(--border); }
.acc details { border-bottom: 1px solid var(--border); }
.acc summary { padding: 15px 2px; font-weight: 800; font-size: 14.5px; cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; }
.acc summary::-webkit-details-marker { display: none; }
.acc summary::after { content: '+'; color: var(--o); font-size: 19px; }
.acc details[open] summary::after { content: '−'; }
.acc__body { padding: 0 2px 18px; color: var(--muted); font-size: 14.5px; }
.acc__body p + p { margin-top: 12px; }
/* "Why You'll Love It" — bolded lead-in per bullet, matching the B2C PDP */
.why-love li { position: relative; padding-left: 18px; margin-bottom: 12px; line-height: 1.55; }
.why-love li::before { content: ''; position: absolute; left: 0; top: 9px; width: 6px; height: 6px; border-radius: 50%; background: var(--o); }
.why-love b { color: var(--ink); }

/* quick-segment rows above collection grids */
.quickrows { display: flex; flex-direction: column; gap: 6px; padding: 18px 0 2px; }
.quickrow { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; }
.quickrow__label { flex: 0 0 auto; min-width: 152px; padding-top: 5px; font-size: 22px; }
.quickrow .chips { margin: 0; flex: 1 1 300px; }
@media (max-width: 700px) {
  .quickrow { gap: 4px; }
  .quickrow__label { min-width: 0; font-size: 20px; padding-top: 0; }
  .quickrow .chips { flex-basis: 100%; }
}

/* reviews page */
.rev-head { display: grid; grid-template-columns: 300px minmax(0,1fr); gap: 40px; align-items: center; }
@media (max-width: 820px) { .rev-head { grid-template-columns: 1fr; gap: 24px; } }

.notice {
  background: var(--o-soft); border: 1px solid #F6D3BE; border-radius: var(--r);
  padding: 14px 18px; font-size: 13.5px; color: var(--o-dark); display: flex; gap: 10px; align-items: flex-start;
}
.notice svg { width: 17px; height: 17px; flex: 0 0 auto; margin-top: 2px; }

@media print { .header, .footer, .marquee { display: none; } }
