/* ============================================================
   SABLE — homepage sections
   ------------------------------------------------------------
   Loads only on the index template, after sbl-tokens.css.
   Namespace: sblx- (homepage-only). Never redefines a token —
   consumes var(--sbl-*) only. 1rem = 10px (Dawn root).
   ============================================================ */

/* ------------------------------------------------------------
   0. SCROLL REVEAL — fade + short rise as homepage sections enter
   the viewport (sbl-home.js). Default state is fully visible — the
   hidden "armed" state is only ever added by the script once it has
   confirmed it's running, so a JS failure leaves everything visible.
   Anything already on-screen at load is marked revealed synchronously
   by the script before this armed class is applied, so there is no
   flash-of-hidden-content on first paint. Applied per-section (one
   wrapping element each) rather than per-child, so it reads as one
   quick movement, not a cascade. The hero is intentionally excluded —
   it's LCP content and always above the fold anyway.
   ------------------------------------------------------------ */
[data-sbl-reveal] {
  opacity: 1;
  transform: none;
}
html.sblx-reveal-armed [data-sbl-reveal] {
  opacity: 0;
  transform: translateY(1.6rem);
  transition: opacity var(--sbl-dur-slow) var(--sbl-ease),
              transform var(--sbl-dur-slow) var(--sbl-ease);
}
html.sblx-reveal-armed [data-sbl-reveal].is-revealed {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  html.sblx-reveal-armed [data-sbl-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ------------------------------------------------------------
   1. HERO — full-bleed image/video, dark scrim, LCP content.
   ------------------------------------------------------------ */
/* Mobile: capped well under a full screen (~58vh) so the categories chip
   row is visible on first load without any scroll — the hero must never
   read as "the whole page". clamp() keeps it sane on very short/tall
   viewports; 58vh is the nominal target. */
.sblx-hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(34rem, 52vh, 48rem);
  overflow: hidden;
  background: var(--sbl-ink);
}
@media (min-width: 750px) {
  .sblx-hero { min-height: 68rem; }
}
@media (min-width: 990px) {
  .sblx-hero { min-height: 78rem; }
}

.sblx-hero__media {
  position: absolute;
  inset: 0;
}
.sblx-hero__image,
.sblx-hero__image--placeholder {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  background: var(--sbl-raise);
}
.sblx-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
}
@media (prefers-reduced-motion: reduce) {
  .sblx-hero__video { display: none; }
}

/* Directional scrim. The hero image is now BRIGHT (the store went light), so a
   flat vertical wash just turns the whole band grey and undoes the redesign.
   Instead: dark where the copy sits (left), clear where the product is (right).
   The scrim stays hardcoded dark on purpose — it has to work over any photo the
   merchant picks, so it can't be token-driven. */
.sblx-hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      90deg,
      rgba(251, 250, 248, 0.94) 0%,
      rgba(251, 250, 248, 0.72) 34%,
      rgba(251, 250, 248, 0) 66%
    ),
    linear-gradient(
      180deg,
      rgba(251, 250, 248, 0) 60%,
      rgba(251, 250, 248, var(--sblx-overlay, 0.30)) 100%
    );
}

@media (max-width: 749px) {
  .sblx-hero__scrim {
    background: linear-gradient(
      180deg,
      rgba(251, 250, 248, 0.55) 0%,
      rgba(251, 250, 248, 0.82) 45%,
      rgba(251, 250, 248, 0.94) 100%
    );
  }
}

.sblx-hero__content {
  position: relative;
  width: 100%;
  padding-bottom: var(--sbl-s-7);
}
@media (min-width: 750px) {
  .sblx-hero__content { padding-bottom: var(--sbl-s-9); }
}

.sblx-hero__box {
  max-width: 60rem;
}

/* Heading and support copy sit on the dark scrim above, not the page
   ground, so they are forced light regardless of the site theme.
   --sbl-mute is unreadable here (~3.8:1 on the near-black scrim) —
   use --sbl-ink (near-white) for both and lean on opacity for
   hierarchy instead of a token that assumes a dark page. */
.sblx-hero__heading {
  margin: 0 0 var(--sbl-s-3);
  font-size: var(--sbl-t-display);
  /* The store is light and so is the hero image; white copy on a pale photo
     failed contrast badly. Dark copy over a LIGHT scrim reads far better and
     suits the white redesign. If a dark hero image is ever chosen, raise the
     scrim opacity setting and flip these two colours back. */
  color: var(--sbl-paper);
}

.sblx-hero__sub {
  margin: 0 0 var(--sbl-s-5);
  max-width: 46rem;
  font-size: var(--sbl-t-body);
  color: var(--sbl-paper);
  opacity: 0.78;
}

.sblx-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sbl-s-3);
}

/* ------------------------------------------------------------
   2. CATEGORIES — chip row (instant routing, zero scroll) +
   contained grid of tiles below it. Composition/background both
   differ from the hero: bounded by .sbl-wrap on the flat ink
   ground, not full-bleed.

   Mobile section padding is tightened below (existing tokens
   only) — categories, featured and newsletter all read as full
   .sbl-section rhythm (7.2rem) on desktop but that alone eats
   most of a phone screen per section, so mobile drops to --sbl-s-6.
   ------------------------------------------------------------ */
@media (max-width: 749px) {
  .sblx-categories.sbl-section,
  .sblx-featured.sbl-section,
  .sblx-newsletter.sbl-section {
    /* Asymmetric, not the flat padding-block above: the top side stacked
       with a heading's own top margin read as dead air the heading was
       floating in rather than air belonging to the section before it —
       see the heading margin resets below. Bottom stays put; that side
       was never the complaint. */
    padding-top: var(--sbl-s-5);
    padding-bottom: var(--sbl-s-6);
  }
}

/* The heading ("Five categories...") is redundant on mobile once the
   chip row exists — it's the same information, and every line of it
   is height the categories grid or a product could occupy instead. */
.sblx-categories__head {
  display: none;
  margin-bottom: var(--sbl-s-5);
}
@media (min-width: 750px) {
  .sblx-categories__head { display: block; }
}
.sblx-categories__heading {
  margin: var(--sbl-s-2) 0 0;
  font-size: var(--sbl-t-h2);
}

/* --- Chip row: horizontally-scrolling pills, same block data as the
   grid below. This is the zero-scroll routing device — a shopper can
   reach a category from the first screen without touching the grid. */
.sblx-chiprow {
  display: flex;
  gap: var(--sbl-s-2);
  margin: 0 calc(var(--sbl-gutter) * -1) var(--sbl-s-4);
  padding: var(--sbl-s-1) var(--sbl-gutter) var(--sbl-s-2);
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.sblx-chiprow::-webkit-scrollbar { display: none; }

.sblx-chiprow__item {
  flex-shrink: 0;
  scroll-snap-align: start;
}
/* Edge padding above already clears the first chip from the screen edge;
   this clears the last one on the trailing side too. */
.sblx-chiprow__item:last-child { padding-right: var(--sbl-s-1); }

.sblx-chiprow__link {
  display: inline-flex;
  align-items: center;
  min-height: 4.6rem;              /* >= 44px touch target */
  padding: 0 var(--sbl-s-4);
  border: 1px solid var(--sbl-line);
  border-radius: var(--sbl-radius-pill);
  background: var(--sbl-raise);
  color: var(--sbl-paper);
  font-size: var(--sbl-t-small);
  font-weight: 600;
  letter-spacing: var(--sbl-ls-label);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--sbl-dur) var(--sbl-ease),
              border-color var(--sbl-dur) var(--sbl-ease);
}
.sblx-chiprow__link:hover,
.sblx-chiprow__link:focus-visible {
  border-color: var(--sbl-paper);
}

/* Desktop already gets the full bento grid one scroll away from the
   hero — the chip row is a mobile/tablet shortcut, not needed there. */
@media (min-width: 990px) {
  .sblx-chiprow { display: none; }
}

/* --- Grid: 2 columns on mobile at 4:5 (not the 3:4 token), first tile
   spanning both columns for hierarchy. Desktop bento below overrides
   this back to an explicit asymmetric layout. */
.sblx-categories__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sbl-s-3);
  list-style: none;
  margin: 0;
  padding: 0;
}
.sblx-categories__tile--1 { grid-column: 1 / -1; }

.sblx-categories__tile { position: relative; }

/* Title/arrow sit over the photo's dark scrim, not the page ground —
   force light regardless of theme (see .sblx-hero__heading above). */
.sblx-categories__link {
  position: relative;
  display: block;
  height: 100%;
  text-decoration: none;
  color: var(--sbl-ink);
}

/* 4:5, not the shared 3:4 token — this section owns its own ratio
   rather than using .sbl-media--portrait. Desktop bento overrides
   this to `auto` and sizes tiles by grid-row instead (below). */
.sblx-categories__media {
  height: 100%;
  aspect-ratio: 4 / 5;
}

/* The first tile spans both columns, so at 4:5 it renders ~440px tall on a
   393px phone and single-handedly pushes the product rail off-screen.
   Landscape for the spanning tile only — measured saving ~200px. */
@media (max-width: 749px) {
  .sblx-categories__tile--1 .sblx-categories__media {
    aspect-ratio: 3 / 2;
  }
}
.sblx-categories__media img {
  transition: transform var(--sbl-dur-slow) var(--sbl-ease);
}
.sblx-categories__link:hover .sblx-categories__media img,
.sblx-categories__link:focus-visible .sblx-categories__media img {
  transform: scale(1.03);
}

.sblx-categories__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(10, 10, 11, 0) 45%, rgba(10, 10, 11, 0.85) 100%);
  pointer-events: none;
}

.sblx-categories__label {
  position: absolute;
  left: var(--sbl-s-4);
  right: var(--sbl-s-4);
  bottom: var(--sbl-s-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sbl-s-2);
}
.sblx-categories__title {
  font-size: var(--sbl-t-h3);
  font-weight: 500;
}
.sblx-categories__arrow {
  color: var(--sbl-ink);
  font-size: var(--sbl-t-h3);
  transition: transform var(--sbl-dur) var(--sbl-ease), color var(--sbl-dur) var(--sbl-ease);
}
.sblx-categories__link:hover .sblx-categories__arrow,
.sblx-categories__link:focus-visible .sblx-categories__arrow {
  /* --sbl-signal is a deep bronze tuned for contrast on the light page —
     too dark to read on this dark scrim. --sbl-signal-dim (~6:1 on the
     scrim) is the on-image accent variant. */
  color: var(--sbl-signal-dim);
  transform: translateX(0.4rem);
}

/* Desktop: asymmetric bento — tile 1 large & tall, tiles 2-4
   fill the remaining column. Falls back to a single column
   above/below this range or with a non-4 block count. */
@media (min-width: 990px) {
  .sblx-categories__grid--4 {
    grid-template-columns: repeat(6, 1fr);
    grid-template-rows: repeat(2, 34rem);
  }
  .sblx-categories__grid--4 .sblx-categories__media {
    aspect-ratio: auto;
  }
  .sblx-categories__grid--4 .sblx-categories__tile--1 {
    grid-column: 1 / 4;
    grid-row: 1 / 3;
  }
  .sblx-categories__grid--4 .sblx-categories__tile--2 {
    grid-column: 4 / 7;
    grid-row: 1 / 2;
  }
  .sblx-categories__grid--4 .sblx-categories__tile--3 {
    grid-column: 4 / 6;
    grid-row: 2 / 3;
  }
  .sblx-categories__grid--4 .sblx-categories__tile--4 {
    grid-column: 6 / 7;
    grid-row: 2 / 3;
  }

  /* Five categories: same asymmetry, with the second row split three ways. */
  .sblx-categories__grid--5 {
    grid-template-columns: repeat(6, 1fr);
    grid-template-rows: repeat(2, 34rem);
  }
  .sblx-categories__grid--5 .sblx-categories__media {
    aspect-ratio: auto;
  }
  .sblx-categories__grid--5 .sblx-categories__tile--1 {
    grid-column: 1 / 4;
    grid-row: 1 / 3;
  }
  .sblx-categories__grid--5 .sblx-categories__tile--2 {
    grid-column: 4 / 7;
    grid-row: 1 / 2;
  }
  .sblx-categories__grid--5 .sblx-categories__tile--3 {
    grid-column: 4 / 5;
    grid-row: 2 / 3;
  }
  .sblx-categories__grid--5 .sblx-categories__tile--4 {
    grid-column: 5 / 6;
    grid-row: 2 / 3;
  }
  .sblx-categories__grid--5 .sblx-categories__tile--5 {
    grid-column: 6 / 7;
    grid-row: 2 / 3;
  }
}

/* ------------------------------------------------------------
   3. FEATURED RAIL — flat ink ground, horizontal snap on mobile,
   grid on desktop. --sbl-raise as a full-bleed fill here would read
   as near-invisible white-on-off-white, so this band differentiates
   from the categories grid above by composition and rhythm (rail of
   product cards vs. bento tiles) rather than a background fill —
   also cuts one more filled panel per the "cleaner" brief.
   ------------------------------------------------------------ */
.sblx-featured__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sbl-s-4);
  margin-bottom: var(--sbl-s-4);
}
@media (min-width: 750px) {
  .sblx-featured__head { margin-bottom: var(--sbl-s-5); }
}
.sblx-featured__heading {
  margin: var(--sbl-s-2) 0 0;
  font-size: var(--sbl-t-h2);
}
.sblx-featured__viewall {
  flex-shrink: 0;
}
@media (max-width: 749px) {
  /* The section's own top padding already separates this from what's
     above — the heading's own top margin was a second, redundant gap
     stacked on it. Drop it and let the heading sit close to the rail
     it introduces, with a sharper size step against body copy. */
  .sblx-featured__heading {
    margin-top: 0;
    font-size: clamp(var(--sbl-t-h2), 7vw, var(--sbl-t-h1));
  }
}

/* This must sit immediately after the categories grid — it's the section
   that finally shows a real product. 42% column width shows ~2.2 cards:
   two in full plus a visible slice of the third, signalling "more below"
   without a caption having to say so. */
.sblx-featured__rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 42%;
  gap: var(--sbl-s-4);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--sbl-s-2);
  margin: 0 calc(var(--sbl-gutter) * -1) 0;
  padding-inline: var(--sbl-gutter);
  list-style: none;
}
.sblx-featured__item {
  scroll-snap-align: start;
}

.sblx-featured__empty {
  color: var(--sbl-mute);
}

@media (min-width: 750px) {
  .sblx-featured__rail { grid-auto-columns: 38%; }
}

@media (min-width: 990px) {
  .sblx-featured__rail {
    grid-auto-flow: row;
    grid-template-columns: repeat(4, 1fr);
    overflow-x: visible;
    margin: 0;
    padding-inline: 0;
  }
}

/* ------------------------------------------------------------
   3B. MARQUEE — full-bleed band of stocked brand names between the
   featured rail and the trust strip. CSS-only infinite scroll: two
   identical tracks sit side by side inside a flex viewport sized to
   its content (width: max-content), and the keyframe translates the
   whole viewport by exactly -50% — i.e. the width of one track — so
   the loop lands back on an identical frame with no visible jump.
   The second track is aria-hidden (screen readers only need the
   list once); under reduced motion it's hidden outright and the
   animation stops, leaving one static, readable row.
   ------------------------------------------------------------ */
.sblx-marquee {
  overflow: hidden;
  border-block: var(--sbl-border);
  background: var(--sbl-ink);
}

.sblx-marquee__viewport {
  display: flex;
  width: max-content;
  animation: sblx-marquee-scroll 34s linear infinite;
}

.sblx-marquee__track {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding-block: var(--sbl-s-3);
}
@media (min-width: 750px) {
  .sblx-marquee__track { padding-block: var(--sbl-s-4); }
}

.sblx-marquee__item {
  font-size: var(--sbl-t-small);
  font-weight: 600;
  letter-spacing: var(--sbl-ls-label);
  text-transform: uppercase;
  color: var(--sbl-mute);
  white-space: nowrap;
  padding-inline: var(--sbl-s-4);
}
@media (min-width: 750px) {
  .sblx-marquee__item { font-size: var(--sbl-t-body); }
}

/* The one deliberate extra job for --sbl-signal on this page (the
   other is the category tile arrow on interaction, above) — a small
   mark doing real separating work, not decoration for its own sake. */
.sblx-marquee__sep {
  flex-shrink: 0;
  color: var(--sbl-signal);
  font-size: 0.7rem;
  line-height: 1;
}

@keyframes sblx-marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .sblx-marquee__viewport { animation: none; }
  .sblx-marquee__track[aria-hidden="true"] { display: none; }
}

/* ------------------------------------------------------------
   4. TRUST — flat ink band, compact icon strip. Background and
   composition both differ from the raised rail above.

   Mobile: a single scrolling row, not a stacked 2x2 — this strip
   was taking more height than it earns. Desktop restores the
   4-up grid.
   ------------------------------------------------------------ */
.sblx-trust {
  padding-block: var(--sbl-s-5);
  border-block: var(--sbl-border);
}
@media (min-width: 750px) {
  .sblx-trust { padding-block: var(--sbl-s-7); }
}

/* 2x2 on mobile, not a scroll row. As a swipeable row only two of the four
   trust signals were visible and the other two needed a gesture nobody makes
   here — and these four are exactly what a hesitant buyer needs to see. It
   costs ~50px of height to show all of them. */
.sblx-trust__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sbl-s-4) var(--sbl-s-3);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 750px) {
  .sblx-trust__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--sbl-s-5) var(--sbl-s-4);
    overflow-x: visible;
    margin: 0;
    padding: 0;
  }
}

.sblx-trust__item {
  display: flex;
  align-items: flex-start;
  gap: var(--sbl-s-3);
  min-width: 0;
}
@media (min-width: 750px) {
  .sblx-trust__item { width: auto; }
}

.sblx-trust__icon {
  flex-shrink: 0;
  width: 2.4rem;
  height: 2.4rem;
  color: var(--sbl-paper);
}
.sblx-trust__icon svg { width: 100%; height: 100%; }

.sblx-trust__copy {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.sblx-trust__title {
  font-size: var(--sbl-t-small);
  font-weight: 600;
  color: var(--sbl-paper);
}
.sblx-trust__text {
  font-size: var(--sbl-t-small);
  color: var(--sbl-mute);
  line-height: var(--sbl-lh-snug);
}

/* ------------------------------------------------------------
   5. EDITORIAL — split two-up. Image full-bleed one side, raised
   copy panel the other. Differs from the flat trust band above:
   split composition, mixed image + raise background.
   ------------------------------------------------------------ */
.sblx-editorial {
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 750px) {
  .sblx-editorial { grid-template-columns: 1fr 1fr; }
  .sblx-editorial--reverse { direction: rtl; }
  .sblx-editorial--reverse > * { direction: ltr; }
}

.sblx-editorial__media {
  background: var(--sbl-raise);
}
.sblx-editorial__image {
  display: block;
  width: 100%;
  height: 100%;
  /* Secondary block — it doesn't earn a 4:5 portrait on a phone. */
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
@media (min-width: 750px) {
  .sblx-editorial__image { aspect-ratio: auto; min-height: 100%; }
}

.sblx-editorial__panel {
  display: flex;
  align-items: center;
  background: var(--sbl-raise);
}

.sblx-editorial__inner {
  padding: var(--sbl-s-5) var(--sbl-gutter);
  max-width: 52rem;
}
@media (min-width: 750px) {
  .sblx-editorial__inner { padding: var(--sbl-s-7) var(--sbl-s-8); }
}

.sblx-editorial__heading {
  margin: var(--sbl-s-2) 0 var(--sbl-s-3);
  font-size: var(--sbl-t-h2);
}
.sblx-editorial__text {
  margin: 0 0 var(--sbl-s-5);
  color: var(--sbl-mute);
}
.sblx-editorial__text p { margin: 0 0 var(--sbl-s-3); }
.sblx-editorial__text p:last-child { margin-bottom: 0; }

@media (max-width: 749px) {
  /* Same redundant stack as featured/newsletter: the panel's own
     top padding plus the heading's top margin doubled up the gap
     between the image above and the heading it introduces. */
  .sblx-editorial__inner { padding-top: var(--sbl-s-4); }
  .sblx-editorial__heading {
    margin-top: 0;
    font-size: clamp(var(--sbl-t-h2), 7vw, var(--sbl-t-h1));
  }
}

/* ------------------------------------------------------------
   6. NEWSLETTER — flat ink, centered single-column form. Differs
   from the split editorial above by composition alone (centered,
   no imagery) — no card border, no fill; whitespace does the framing.
   ------------------------------------------------------------ */
.sblx-newsletter__box {
  max-width: 56rem;
  margin-inline: auto;
  padding: 0 var(--sbl-s-4);
  text-align: center;
}

.sblx-newsletter__heading {
  margin: var(--sbl-s-2) 0 var(--sbl-s-3);
  font-size: var(--sbl-t-h2);
}
.sblx-newsletter__text {
  margin: 0 0 var(--sbl-s-5);
  color: var(--sbl-mute);
}
@media (max-width: 749px) {
  .sblx-newsletter__heading {
    margin-top: 0;
    font-size: clamp(var(--sbl-t-h2), 7vw, var(--sbl-t-h1));
  }
}

.sblx-newsletter__form {
  max-width: 44rem;
  margin-inline: auto;
}

.sblx-newsletter__field {
  display: flex;
  flex-direction: column;
  gap: var(--sbl-s-2);
}
@media (min-width: 550px) {
  .sblx-newsletter__field { flex-direction: row; }
}

.sblx-newsletter__input {
  flex: 1;
  min-height: 4.8rem;
  padding: 0 var(--sbl-s-4);
  background: var(--sbl-ink);
  border: var(--sbl-border);
  border-radius: var(--sbl-radius);
  color: var(--sbl-paper);
  font: inherit;
  font-size: var(--sbl-t-body);
}
.sblx-newsletter__input::placeholder { color: var(--sbl-faint); }
.sblx-newsletter__input:focus-visible {
  outline: 2px solid var(--sbl-signal);
  outline-offset: -2px;
}

.sblx-newsletter__submit { flex-shrink: 0; }

.sblx-newsletter__message {
  margin: var(--sbl-s-3) 0 0;
  font-size: var(--sbl-t-small);
}
.sblx-newsletter__message--error { color: var(--sbl-alert); }
.sblx-newsletter__message--success { color: var(--sbl-good); }
