/* sections.css - styles for the general-purpose content sections (ST-M7).
 *
 * OWNED BY ST-M7. Do not edit from another milestone.
 *
 * One file for the content-section library (image banner, rich text, multicolumn, collection
 * list, slideshow, ...) so the library can grow without touching base.css or any other
 * milestone's stylesheet. Consumes the layout's design tokens (--primary/--bg/--text/--maxw)
 * and the per-section padding props stamped on .nscms-section (see base.css).
 *
 * Commerce surfaces have their own files and are NOT styled here: card.css (product cards),
 * product.css (product page), cart.css (cart + drawer), header.css (header/footer).
 *
 * EVERY variation below is driven by a SECTION or BLOCK SETTING - merchants never write CSS
 * (D2 in STOREFRONT_THEME_PARITY_PLAN.md), and each setting was taken from the real Dawn
 * source (see the citation at the top of each section's .liquid and .json). The class /
 * custom-property vocabulary the section templates emit is:
 *
 *   --sec-cols / --sec-cols-mobile   columns_desktop / columns_mobile
 *   --sec-overlay                    image_overlay_opacity, as a CSS <percentage>
 *   --sec-x / --sec-y                the 9-point desktop_content_position / box_align
 *   --sec-text-align / --sec-flex-x  desktop_content_alignment, content_alignment, text_alignment
 *   .sec-heading--{h2|h1|h0|hxl|hxxl}  heading_size (Dawn's type-scale vocabulary, NOT small/medium/large)
 *   .sec-media--{adapt|square|portrait|landscape|circle}  image_ratio
 *   .sec-behavior-{none|ambient|fixed|zoom-in}            image_behavior
 *   .sec-grid--swipe                 swipe_on_mobile
 *   --sec-bleed                      how far a full-width section reaches (see below)
 */

:root {
  --sec-gap: 1.25rem;
  /* Basic draws every image, tile and card with SQUARE corners (477:4192 throughout). */
  --sec-radius: 0;
  --sec-border: #e6e6e9;
  --sec-surface: #f5f5f7;
  --sec-muted: #6b7280;
  /* The design's empty-image fill (grey/200) and its glyph colour. */
  --sec-placeholder-bg: #e7e7e9;
  --sec-placeholder-fg: #595550;
  --sec-box-bg: rgba(255, 255, 255, 0.92);
  --sec-overlay-color: #000000;

  /* How far a "full width" section reaches: to the WINDOW edge. 50vw is half the window, 50% is
     half the section wrapper it is resolved against (a custom property is substituted before the
     percentage resolves, so it means the wrapper at every use site), and the difference is exactly
     the gutter between the page's content column and the edge of the screen.
     This used to be a flat 1.25rem, which only cancelled <main>'s own padding — so on any screen
     wider than the page width a "full width" hero, category band or video stopped at the content
     column, and the Basic design's edge-to-edge sections came out as boxes in the middle of the
     page. The horizontal scrollbar that 100vw would otherwise add is clipped on <body> (base.css). */
  --sec-bleed: calc(50vw - 50%);

  /* Dawn's heading_size is a type SCALE (h2 -> hxxl), not a t-shirt size. ST-M1b replaces
     these with the real global type scale; the class names are the stable contract.
     Basic (ST-M10a): the ladder is shifted up so the DEFAULT (h2) lands on the design's 40px
     section title (477:4234) and hxl on its 72px hero. The rungs keep their proportions, so a
     merchant who chose a larger size still gets a larger one — only the floor moved. */
  --sec-h2: clamp(1.6rem, 1.1rem + 1.8vw, 2.5rem);
  --sec-h1: clamp(1.9rem, 1.3rem + 2.2vw, 3rem);
  --sec-h0: clamp(2.3rem, 1.5rem + 2.9vw, 3.625rem); /* 58px: the hero title (477:4227) */
  --sec-hxl: clamp(2.8rem, 1.7rem + 4vw, 4.5rem);
  --sec-hxxl: clamp(3.2rem, 1.9rem + 5vw, 5.5rem);
}

/* --- shared typography --------------------------------------------------------------- */
/* Basic (ST-M10a). The design gives every homepage section the SAME title treatment (measured off
   477:4234): the heading face at 40px, uppercase, 1.6px tracking, regular weight, 1.22 leading.
   It lives on the shared class rather than per section, so the six homepage sections — and every
   later one that uses `.sec-heading` — line up without six copies of the same rule.
   Weight 400, not 600: the design's titles are regular, and a semibold serif at 40px reads as a
   different typeface entirely. */
.sec-heading {
  margin: 0;
  font-family: var(--font-heading, var(--font-body));
  line-height: 1.22;
  /* parity_snifl_home: Theme settings › Section headings "Medium" declares the token (home_parity.go);
     without it the fallback is the regular weight this rule always had. */
  font-weight: var(--sec-heading-weight, 400);
  /* 10-16 G2: Theme settings › Headings and labels. The two tokens exist only for "As typed"
     (section_style.go), so the fallbacks are the capitals and tracking this rule always had. Every
     tracked-capitals rule in the theme's stylesheets reads the same pair. */
  letter-spacing: var(--caps-spacing, 0.1rem);
  text-transform: var(--caps-transform, uppercase);
  text-wrap: balance;
}

/* Basic (ST-M10a): the section title row — title left, a small "View all" link right, baseline
   aligned (477:4233). Wraps on a narrow screen so the link drops under the title rather than
   squeezing it. */
.sec-title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  margin-bottom: 1.75rem;
}

/* The design's link: 14px, uppercase, 1.4px tracking, with a permanent 1px rule under it — unlike
   the header's nav, where the same rule is drawn transparent until the link is current. */
.sec-view-all {
  flex: none;
  font-size: 0.875rem;
  letter-spacing: var(--caps-spacing, 0.0875rem);
  text-transform: var(--caps-transform, uppercase);
  text-decoration: none;
  color: inherit;
  border-bottom: 1px solid currentColor;
  padding-bottom: 1px;
}

.sec-view-all:hover {
  opacity: 0.7;
  text-decoration: none;
}

/* 10-16 Featured collection › Link style "Short line under the words": 18/25 medium words as typed, with a
   40px line centred below them (the client site's "Shop all"). Only a link with the class changes. */
.sec-view-all--line {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-size: 1.125rem;
  line-height: 1.5625rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  border-bottom: 0;
  padding-bottom: 0;
}

/* parity_snifl_home: Featured collection › Link colour "Button colour" (the scheme's solid button). */
.sec-view-all--button-color {
  color: var(--primary, currentColor);
}

.sec-view-all--line::after {
  content: "";
  width: 40px;
  height: 1px;
  background: currentColor;
}

/* --- testimonials (ST-M10a) ------------------------------------------------------------
   The design's review row (477:4283): a short name over a quote, centred, three across a 1540px
   content width with generous space between. No card, no border, no quotation marks — the words
   sit on the page. */
.sec-testimonials {
  align-items: start;
  gap: 2rem; /* 32px between the three (477:4283) */
}

.sec-testimonial {
  display: grid;
  gap: 1.25rem;
}

.sec-testimonials--align-center .sec-testimonial {
  text-align: center;
}

/* 477:4285: the name in the heading face, 20px uppercase with 2px tracking. */
.sec-testimonial__author {
  margin: 0;
  font-family: var(--font-heading, var(--font-body));
  font-size: 1.25rem;
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: var(--caps-spacing, 0.125rem);
  text-transform: var(--caps-transform, uppercase);
}

/* 477:4286: the quote large and light — 24px, weight 300, 1.75 leading. */
.sec-testimonial__quote {
  /* The quote is richtext, so it arrives wrapped in its own <p>. Collapse those margins rather
     than letting the block's gap and the paragraph's margin stack into an uneven row. */
  font-size: clamp(1.125rem, 0.9rem + 0.6vw, 1.5rem);
  font-weight: 300;
  line-height: 1.75;
  letter-spacing: 0.03rem;
}

.sec-testimonial__quote > :first-child {
  margin-top: 0;
}

.sec-testimonial__quote > :last-child {
  margin-bottom: 0;
}

.sec-heading--h2 {
  font-size: var(--sec-h2);
}

.sec-heading--h1 {
  font-size: var(--sec-h1);
}

.sec-heading--h0 {
  font-size: var(--sec-h0);
}

.sec-heading--hxl {
  font-size: var(--sec-hxl);
}

.sec-heading--hxxl {
  font-size: var(--sec-hxxl);
}

.sec-text {
  margin: 0;
  line-height: 1.5;
}

.sec-text--subtitle {
  font-size: 1.1rem;
  opacity: 0.88;
}

.sec-text--caption-with-letter-spacing {
  text-transform: var(--caps-transform, uppercase);
  letter-spacing: var(--caps-spacing, 0.08em);
  font-size: 0.85rem;
}

.sec-caption {
  margin: 0;
  line-height: 1.4;
}

.sec-caption--small {
  font-size: 0.8rem;
}

.sec-caption--medium {
  font-size: 0.92rem;
}

.sec-caption--large {
  font-size: 1.05rem;
}

/* The `richtext` settings (rich_text_v2's text block, multicolumn's column description) are
   merchant-authored HTML, emitted raw. Give it sane rhythm without fighting the merchant. */
.sec-rte {
  /* 10-16 parity: Theme settings › Typography › Line spacing "Compact" declares the two tokens
     (section_style.go); without it the fallbacks are this rule's own 1.55 and the inherited size. */
  font-size: var(--text-size, inherit);
  line-height: var(--text-line-height, 1.55);
}

.sec-rte > :first-child {
  margin-top: 0;
}

.sec-rte > :last-child {
  margin-bottom: 0;
}

.sec-rte p,
.sec-rte ul,
.sec-rte ol {
  margin: 0 0 0.75rem;
}

.sec-rte ul,
.sec-rte ol {
  padding-left: 1.25rem;
}

/* --- shared buttons + links --------------------------------------------------------- */
.sec-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: var(--sec-flex-x, center);
}

.sec-buttons--center {
  justify-content: center;
  margin-top: var(--sec-gap);
}

/* Basic (ST-M10a): a SQUARE button with uppercase, tracked type — 12px/32px padding, 14px, 1.4px
   tracking (477:4229). It was a pill with sentence-case body type, which read as a different
   design language from everything around it.
   The COLOUR is left on the theme's own token rather than pinned to the design's white-on-image
   button: colour schemes are a merchant feature, and hard-coding the mock's palette would ignore
   whatever they picked. Shape and type are the design; colour stays theirs. */
.sec-button {
  display: inline-block;
  border: 1px solid var(--primary, currentColor);
  /* 10-15-C §1: Theme settings › Button shape. The token exists only when a shape other than square
     is chosen (section_style.go), so the fallback is the square corner this rule always had. */
  border-radius: var(--button-radius, 0);
  background: var(--primary, #111);
  /* 10-16 G2: the colour scheme's "Solid button text". The token exists only where a scheme sets one
     (section_style.go), so the fallback is the white this rule always had. */
  color: var(--solid-button-text, #fff);
  /* 10-16 parity: Theme settings › Button text size "Medium" declares the five --button-* tokens
     (section_style.go); without it every fallback is the value this rule always had. */
  padding: var(--button-padding, 0.75rem 2rem);
  font: inherit;
  font-size: var(--button-font-size, 0.875rem);
  font-weight: var(--button-font-weight, 400);
  letter-spacing: var(--button-letter-spacing, 0.0875rem);
  /* 10-15-C §3: Theme settings › Button text. The token exists only for "As typed"
     (section_style.go), so the fallback is the capitals this rule always had. */
  text-transform: var(--button-text-transform, uppercase);
  line-height: var(--button-line-height, 1.4);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.sec-button:hover {
  text-decoration: none;
  opacity: 0.9;
}

/* Dawn's "Outline style" checkbox. */
.sec-button--secondary {
  background: transparent;
  color: inherit;
  border-color: currentColor;
}

.sec-link {
  display: inline-block;
  color: var(--primary);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* --- shared media ------------------------------------------------------------------- */
.sec-media {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--sec-radius);
  background: var(--sec-placeholder-bg);
  aspect-ratio: var(--sec-ratio, 1 / 1);
}

.sec-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* "adapt" keeps the image's own proportions (Dawn's wording). */
.sec-media--adapt {
  aspect-ratio: auto;
  background: none;
}

.sec-media--adapt img {
  height: auto;
}

.sec-media--square {
  --sec-ratio: 1 / 1;
}

.sec-media--portrait {
  --sec-ratio: 3 / 4;
}

/* parity_snifl_home: Multicolumn's "Set shape" — the height as a % of the width (--mc-ar on the grid). */
.sec-media--custom {
  --sec-ratio: 100 / var(--mc-ar, 100);
}

.sec-media--landscape {
  --sec-ratio: 4 / 3;
}

.sec-media--circle {
  --sec-ratio: 1 / 1;
  border-radius: 50%;
}

/* The image_picker settings carry only a URL, so there is nothing to render for an unset
   image. min-height keeps the placeholder visible in "adapt" boxes, which have no ratio to
   give them height. */
.sec-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  min-height: 8rem;
  color: var(--sec-placeholder-fg);
  background: var(--sec-placeholder-bg);
}

/* The design's image glyph is a fixed 64px in every tile (477:4476, 477:4650) and 100px in the
   hero (477:4420) — a size, not a fraction of the tile, so a large tile does not get a large icon. */
.sec-placeholder svg {
  width: 64px;
  max-width: 40%;
  height: auto;
}

/* --- image_behavior ------------------------------------------------------------------
 * Dawn animates the banner/slide image four ways. `none` is the default and does nothing.
 * ambient + zoom-in are pure CSS; zoom-in is scroll-linked where the browser supports a view()
 * timeline and simply static where it does not. `fixed` (Dawn's parallax) uses the clip-path
 * containing-block technique, and is deliberately limited to wide viewports with a single
 * fixed-height image - the case where it degrades gracefully.
 * ----------------------------------------------------------------------------------- */
@keyframes sec-ambient {
  from {
    transform: scale(1.06) translate(0, 0);
  }

  to {
    transform: scale(1.18) translate(-1.5%, 1%);
  }
}

@keyframes sec-zoom-in {
  from {
    transform: scale(1);
  }

  to {
    transform: scale(1.22);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .sec-behavior-ambient img {
    animation: sec-ambient 30s ease-in-out infinite alternate;
  }

  @supports (animation-timeline: view()) {
    .sec-behavior-zoom-in img {
      animation: sec-zoom-in linear both;
      animation-timeline: view();
    }
  }
}

@media (min-width: 990px) and (prefers-reduced-motion: no-preference) {
  .sec-banner:not(.sec-banner--h-adapt):not(.sec-banner--split) .sec-behavior-fixed {
    clip-path: inset(0);
  }

  .sec-banner:not(.sec-banner--h-adapt):not(.sec-banner--split) .sec-behavior-fixed img {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
  }
}

/* --- 9-point content position + alignment -------------------------------------------
 * image_banner's desktop_content_position and the slide block's box_align share one
 * vocabulary, so they share these rules.
 * ----------------------------------------------------------------------------------- */
.sec-banner--pos-top-left,
.sec-slide--pos-top-left {
  --sec-y: start;
  --sec-x: start;
}

.sec-banner--pos-top-center,
.sec-slide--pos-top-center {
  --sec-y: start;
  --sec-x: center;
}

.sec-banner--pos-top-right,
.sec-slide--pos-top-right {
  --sec-y: start;
  --sec-x: end;
}

.sec-banner--pos-middle-left,
.sec-slide--pos-middle-left {
  --sec-y: center;
  --sec-x: start;
}

.sec-banner--pos-middle-center,
.sec-slide--pos-middle-center {
  --sec-y: center;
  --sec-x: center;
}

.sec-banner--pos-middle-right,
.sec-slide--pos-middle-right {
  --sec-y: center;
  --sec-x: end;
}

.sec-banner--pos-bottom-left,
.sec-slide--pos-bottom-left {
  --sec-y: end;
  --sec-x: start;
}

.sec-banner--pos-bottom-center,
.sec-slide--pos-bottom-center {
  --sec-y: end;
  --sec-x: center;
}

.sec-banner--pos-bottom-right,
.sec-slide--pos-bottom-right {
  --sec-y: end;
  --sec-x: end;
}

.sec-banner--align-left,
.sec-slide--align-left,
.sec-richtext--align-left,
.sec-multicolumn--align-left {
  --sec-text-align: left;
  --sec-flex-x: flex-start;
}

.sec-banner--align-center,
.sec-slide--align-center,
.sec-richtext--align-center,
.sec-multicolumn--align-center {
  --sec-text-align: center;
  --sec-flex-x: center;
}

.sec-banner--align-right,
.sec-slide--align-right,
.sec-richtext--align-right {
  --sec-text-align: right;
  --sec-flex-x: flex-end;
}

/* The mobile alignment settings override the desktop ones below the tablet breakpoint. They
   come later in the file, so equal-specificity selectors resolve in their favour. */
@media (max-width: 749px) {
  .sec-banner--malign-left,
  .sec-slide--malign-left {
    --sec-text-align: left;
    --sec-flex-x: flex-start;
  }

  .sec-banner--malign-center,
  .sec-slide--malign-center {
    --sec-text-align: center;
    --sec-flex-x: center;
  }

  .sec-banner--malign-right,
  .sec-slide--malign-right {
    --sec-text-align: right;
    --sec-flex-x: flex-end;
  }
}

/* --- image_banner ------------------------------------------------------------------- */
/* Dawn's image banner has no width setting: it is always the full-width surface. */
.sec-banner {
  position: relative;
  display: grid;
  margin-inline: calc(-1 * var(--sec-bleed));
  min-height: var(--sec-banner-h, 28rem);
}

.sec-banner--h-adapt {
  --sec-banner-h: auto;
}

.sec-banner--h-small {
  --sec-banner-h: 20rem;
}

.sec-banner--h-medium {
  --sec-banner-h: 26rem;
}

.sec-banner--h-large {
  --sec-banner-h: 32rem;
}

@media (min-width: 750px) {
  .sec-banner--h-small {
    --sec-banner-h: 28rem;
  }

  .sec-banner--h-medium {
    --sec-banner-h: 39rem;
  }

  .sec-banner--h-large {
    --sec-banner-h: 48rem;
  }
}

/* 10-15-C §2 (S4): image_height "Full screen" — one screen tall, less whatever sits above <main>
   (announcement bar + header). --header-height is measured by snippets/header-offset.liquid, which
   the banner prints only when this height is chosen; without the script it is 0 and the banner is
   simply one screen tall. svh where the browser has it, so a phone's address bar does not push the
   bottom of the banner off screen. */
.sec-banner--h-full {
  --sec-banner-h: calc(100vh - var(--header-height, 0px));
}

@supports (height: 100svh) {
  .sec-banner--h-full {
    --sec-banner-h: calc(100svh - var(--header-height, 0px));
  }
}

/* 10-15-C fix (S4): "Full screen" is an EXACT height, not a floor. The other heights are a
   min-height the photo may grow past (a 16:9 photo at 1440 is 810 tall, more than one screen
   less the header, and a square one 1440). Here the media box is size-contained, so the photo
   no longer sizes the row: the banner is one screen tall and the photo covers it from its
   centre (object-fit: cover above). Only copy taller than the screen can still grow it, so text
   is never cut off. The two-image split shares that height (one row, or two stacked on a phone). */
.sec-banner--h-full.sec-banner--no-content {
  min-height: var(--sec-banner-h);
}

.sec-banner--h-full .sec-banner__media {
  contain: size;
  grid-auto-rows: minmax(0, 1fr);
}

/* On a phone with the text below the photo ("Container (mobile)", on by default) the PHOTO is
   one screen tall and the text follows under it. */
@media (max-width: 749px) {
  .sec-banner--h-full.sec-banner--mobile-below .sec-banner__media {
    height: var(--sec-banner-h);
  }
}

.sec-banner__media,
.sec-banner__content {
  grid-area: 1 / 1;
}

/* 10-15-C fix3: `clip`, not `hidden`. A box with overflow: hidden is a scroll container, and a
   view() timeline measures its subject against the NEAREST scroll container: "Zoom in" measured the
   photo against this box, where it never moves, so the zoom never ran. clip cuts the overflow the
   same way without being a scroll container, so view() reaches the page's scroll. `hidden` stays
   first for a browser without clip (which has no scroll timelines either). */
.sec-banner__media {
  position: relative;
  overflow: hidden;
  overflow: clip;
}

/* Dawn's "Image 2": the two images share the banner half and half. */
.sec-banner--split .sec-banner__media {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@media (max-width: 749px) {
  .sec-banner--split.sec-banner--stack-mobile .sec-banner__media {
    grid-template-columns: 1fr;
  }
}

.sec-banner__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.sec-banner--h-adapt .sec-banner__image {
  height: auto;
}

.sec-banner__overlay {
  position: absolute;
  inset: 0;
  background: var(--sec-overlay-color);
  opacity: var(--sec-overlay, 0%);
}

.sec-banner__content {
  position: relative;
  display: grid;
  align-items: var(--sec-y, center);
  justify-items: var(--sec-x, center);
  padding: 2.5rem 1.5rem;
}

.sec-banner__box {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  max-width: min(46rem, 100%);
  padding: 2rem;
  border-radius: var(--sec-radius);
  background: var(--sec-box-bg);
  text-align: var(--sec-text-align, center);
}

/* show_text_box = false: the copy sits directly on the photograph. There is no colour scheme
   yet (ST-M1b), so the shadow is what keeps it legible over an image we know nothing about. */
.sec-banner__box--plain {
  background: none;
  padding: 0;
  color: #fff;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.55);
}

/* …unless there IS no photograph. A slide with no image draws the light grey placeholder, and
   white-on-light-grey is unreadable — which is exactly what a merchant sees on the day they
   install the theme, before they have uploaded anything. Fall back to the page's own text colour
   and drop the shadow, so the empty state reads as a real slide waiting for an image rather than
   a broken one. `:has()` is the whole reason this can be said in CSS at all. */
/* …unless there IS no photograph. A slide or banner with no image draws the light grey
   placeholder, and white-on-light-grey is unreadable — which is exactly what a merchant sees on
   the day they install the theme, before they have uploaded anything. Fall back to the page's own
   text colour and drop the shadow, so the empty state reads as a slide waiting for an image rather
   than a broken one. Scoped to the whole slide/banner because the image is a SIBLING of the text
   box, not its ancestor; `:has()` is the only thing that can express that in CSS. */
/* …but only when there is no shade either. Basic's hero is white type over a grey placeholder
   darkened by its gradient (477:4222), and that reads — it is the design's own empty state. */
.sec-banner:not(:has(img)):not(:has(.sec-banner__overlay)) .sec-banner__box--plain,
.sec-slide:not(:has(img)):not(:has(.sec-slide__overlay)) .sec-slide__box--plain {
  color: var(--text, inherit);
  text-shadow: none;
}

/* show_text_below (mobile): stop overlaying and stack the copy under the image instead. */
@media (max-width: 749px) {
  .sec-banner--mobile-below {
    display: block;
    min-height: 0;
  }

  .sec-banner--mobile-below .sec-banner__content {
    padding: 1.25rem;
  }

  .sec-banner--mobile-below .sec-banner__box--plain {
    color: inherit;
    text-shadow: none;
  }
}

/* A banner with no heading/text/button blocks is just the image. */
.sec-banner--no-content {
  min-height: 0;
}

/* parity_snifl_home — image_banner options, each behind a class or a custom property the template
   prints only for a non-default choice (docs/clients/snifl/SITE_MEASUREMENTS.md §3.1 row 1).
   Height "Full screen, behind the header": one screen tall, pulled up under the header by the
   header's measured height (snippets/header-offset.liquid), so the photo starts at the top of the
   page. The header is lifted above it: a pinned header already is (z-index 50); one that scrolls
   away gets the same stacking here, without losing its own position when it has one. */
.sec-banner--h-under {
  --sec-banner-h: 100vh;
  /* Less <main>'s 1rem top padding too: this margin collapses with the section wrapper's own -1rem
     (the "flush under the header" rule above), and the more negative of the two wins. */
  margin-top: calc(-1 * var(--header-height, 0px) - 1rem);
}

@supports (height: 100svh) {
  .sec-banner--h-under {
    --sec-banner-h: 100svh;
  }
}

.sec-banner--h-under .sec-banner__media {
  contain: size;
  grid-auto-rows: minmax(0, 1fr);
}

.sec-banner--h-under.sec-banner--no-content {
  min-height: var(--sec-banner-h);
}

body:has(.sec-banner--h-under) .nscms-section--header {
  position: relative;
  z-index: 50;
}

@media (max-width: 749px) {
  .sec-banner--h-under.sec-banner--mobile-below .sec-banner__media {
    height: var(--sec-banner-h);
  }
}

/* 10-19 follow-up (owner, Snifl preview item 1): "Leave room for the next section" for the two
   full-screen heights, so the next section peeks below the banner: three quarters of a phone screen
   (--peek-phones), 85% of a wider screen (--peek-wide). Only a banner with a class changes. For
   "behind the header" the share includes the header, which sits over the photo. */
@media (max-width: 749px) {
  .sec-banner--h-full.sec-banner--peek-phones {
    --sec-banner-h: calc(75vh - var(--header-height, 0px));
  }

  .sec-banner--h-under.sec-banner--peek-phones {
    --sec-banner-h: 75vh;
  }

  @supports (height: 100svh) {
    .sec-banner--h-full.sec-banner--peek-phones {
      --sec-banner-h: calc(75svh - var(--header-height, 0px));
    }

    .sec-banner--h-under.sec-banner--peek-phones {
      --sec-banner-h: 75svh;
    }
  }
}

@media (min-width: 750px) {
  .sec-banner--h-full.sec-banner--peek-wide {
    --sec-banner-h: calc(85vh - var(--header-height, 0px));
  }

  .sec-banner--h-under.sec-banner--peek-wide {
    --sec-banner-h: 85vh;
  }

  @supports (height: 100svh) {
    .sec-banner--h-full.sec-banner--peek-wide {
      --sec-banner-h: calc(85svh - var(--header-height, 0px));
    }

    .sec-banner--h-under.sec-banner--peek-wide {
      --sec-banner-h: 85svh;
    }
  }
}

/* "Shadow behind text on the image" off. */
.sec-banner--no-shadow .sec-banner__box--plain {
  text-shadow: none;
}

/* "Text spacing": computers (1200px+), tablets (750-1199px), phones. Unset steps fall back to the
   values the content box always had. */
.sec-banner--spaced .sec-banner__content {
  padding: var(--sb-py, 2.5rem) var(--sb-px, 1.5rem);
}

.sec-banner--spaced .sec-banner__box {
  gap: var(--sb-gap, 0.9rem);
}

@media (max-width: 1199px) {
  .sec-banner--spaced .sec-banner__content {
    padding: var(--sb-py-t, 2.5rem) var(--sb-px-t, 1.5rem);
  }
}

@media (max-width: 749px) {
  .sec-banner--spaced:not(.sec-banner--mobile-below) .sec-banner__content {
    padding: var(--sb-py-m, 2.5rem) var(--sb-px-m, 1.5rem);
  }
}

/* Heading: "Set size" per screen, weight, tight lines, line length. */
.sec-banner__heading--custom {
  font-size: var(--sb-h, 4.5rem);
}

@media (max-width: 1199px) {
  .sec-banner__heading--custom {
    font-size: var(--sb-h-t, 3.5rem);
  }
}

@media (max-width: 749px) {
  .sec-banner__heading--custom {
    font-size: var(--sb-h-m, 2.5rem);
  }
}

.sec-banner__heading--medium {
  font-weight: 500;
}

.sec-banner__heading--bold {
  font-weight: 700;
}

.sec-banner__heading--tight {
  line-height: 1;
}

/* A line length makes the breaks predictable, so the lines are not re-balanced either. */
.sec-banner__heading--max {
  max-width: var(--sb-h-max, none);
  text-wrap: wrap;
}

/* --- collection_banner (Basic, 311:2011) ---------------------------------------------
   With an image: full window width, 560px at 1920 (a proportion of the width below that), the
   picture under a shade that deepens towards the bottom, the title (heading face, uppercase) and
   the description (small tracked capitals) centred on it in white.
   Without one: the same two lines, centred on the page. */
.collection-banner {
  display: grid;
  justify-items: center;
  text-align: center;
  padding: 1.5rem 0 0.5rem;
}

.collection-banner h1 {
  margin: 0;
  font-family: var(--font-heading, var(--font-body));
  font-size: var(--sec-h0);
  font-weight: 400;
  line-height: 1.24;
  text-transform: var(--caps-transform, uppercase);
}

.collection-banner .body {
  max-width: 48rem;
  margin-top: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.6;
  letter-spacing: var(--caps-spacing, 0.0875rem);
  text-transform: var(--caps-transform, uppercase);
}

.collection-banner .body > :first-child {
  margin-top: 0;
}

.collection-banner .body > :last-child {
  margin-bottom: 0;
}

.collection-banner--overlay {
  position: relative;
  margin-inline: calc(-1 * var(--sec-bleed));
  margin-top: -1rem; /* flush under the header, like the homepage hero */
  padding: 0;
  min-height: clamp(18rem, 29.17vw, 35rem);
  place-items: center;
  color: #fefefe;
  overflow: hidden;
}

.collection-banner--overlay > .collection-banner__media,
.collection-banner--overlay > .collection-banner__content {
  grid-area: 1 / 1;
}

.collection-banner--overlay .collection-banner__media {
  position: absolute;
  inset: 0;
}

.collection-banner--overlay .collection-banner__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.12) 0%, rgba(0, 0, 0, 0.42) 100%);
}

.collection-banner--overlay .collection-banner__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.collection-banner--overlay .collection-banner__content {
  position: relative;
  z-index: 1;
  padding: 2.5rem max(1.25rem, calc((100% - var(--maxw)) / 2));
}

/* --- main_404 with an image (10-15-C §2, S12) ----------------------------------------
   Printed only when the merchant picked an image for the 404 page: the words and the image side by
   side from the tablet breakpoint up (image_position picks the side), stacked with the image under
   the words on a phone. The image takes the theme's corner radius (--sec-radius, Theme settings ›
   Buttons and corners). Without an image the page is today's three lines and none of this applies. */
.nf-page {
  display: grid;
  gap: 2rem;
  align-items: center;
}

.nf-page__image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--sec-radius);
  object-fit: cover;
}

@media (min-width: 750px) {
  .nf-page {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 3rem;
  }

  .nf-page--image-left .nf-page__media {
    order: -1;
  }
}

/* 10-16 pages parity: main_404's "Look (with an image)" settings. The class and its custom properties are
   printed only when one is set, and each property falls back to the value the rules above already give. */
.nf-page--tuned {
  gap: var(--nf-gap, 2rem);
  max-width: var(--nf-w, none);
  min-height: var(--nf-min-h, 0);
  margin-inline: auto;
}

.nf-page--tuned .nf-page__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}

.nf-page--tuned .nf-page__text > * {
  margin: 0;
}

.nf-page--tuned h1 {
  font-size: var(--nf-h-m, 2em);
  line-height: 1;
  color: var(--nf-h-color, inherit);
}

.nf-page--tuned .nf-page__text > p:first-of-type {
  font-size: var(--nf-t, inherit);
  font-weight: var(--nf-t-weight, inherit);
  line-height: 1.4;
  color: var(--nf-t-color, inherit);
}

.nf-page--tuned .nf-page__image {
  height: var(--nf-img-h-m, var(--nf-img-h, auto));
}

@media (min-width: 750px) {
  .nf-page--tuned {
    gap: var(--nf-gap, 3rem);
  }

  .nf-page--tuned .nf-page__image {
    height: var(--nf-img-h, auto);
  }
}

@media (min-width: 990px) {
  .nf-page--tuned h1 {
    font-size: var(--nf-h, 2em);
  }
}

/* --- rich_text_v2 ------------------------------------------------------------------- */
.sec-richtext {
  display: grid;
  justify-items: center;
}

.sec-richtext--pos-left {
  justify-items: start;
}

.sec-richtext--pos-center {
  justify-items: center;
}

.sec-richtext--pos-right {
  justify-items: end;
}

/* Dawn's full_width widens BOTH the section box and the column inside it (its non-full state
   nests a page-width container, which is what makes the text column narrower). */
.sec-richtext--full {
  margin-inline: calc(-1 * var(--sec-bleed));
  padding-inline: var(--sec-bleed);
}

.sec-richtext__inner {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: min(52rem, 100%);
  text-align: var(--sec-text-align, center);
}

.sec-richtext--full .sec-richtext__inner {
  max-width: 100%;
}

/* 10-16 pages parity: rich_text_v2's Text width, Background colour, Minimum height, Space beside the text
   on computers, and the heading's Custom size + weight. Each class is printed only off its default
   (sections/rich_text_v2.liquid), so none of this touches a section saved before. */
.sec-richtext--w .sec-richtext__inner {
  width: 100%;
  max-width: min(var(--rt-text-w), 100%);
}

/* The band reaches the window edge and carries the section's padding, as image_with_text does, while
   the words keep to the page column. */
.sec-richtext--band {
  margin-inline: calc(-1 * var(--sec-bleed));
  padding-inline: var(--sec-bleed);
  margin-block: calc(-1 * var(--section-pt, 0px)) calc(-1 * var(--section-pb, 0px));
  padding-block: var(--section-pt, 0px) var(--section-pb, 0px);
  background: var(--rt-bg);
}

/* A coloured band opening the page sits flush under the header, like a full-width banner. */
main > .nscms-section:first-child:has(> .sec-richtext--band) {
  margin-top: -1rem;
}

.sec-richtext--min-h {
  box-sizing: border-box;
  min-height: var(--rt-min-h);
  align-content: start;
}

@media (min-width: 990px) {
  /* From the page's own edge (the page width's outer edge), not from <main>'s 1.25rem margin. */
  .sec-richtext--side {
    padding-inline: max(0px, calc(var(--rt-side) - 1.25rem));
  }

  .sec-richtext--side.sec-richtext--full,
  .sec-richtext--side.sec-richtext--band {
    padding-inline: calc(var(--sec-bleed) - 1.25rem + var(--rt-side));
  }
}

.sec-richtext__heading--custom {
  font-size: var(--rt-h-size-m, 2rem);
  line-height: 1.2;
}

@media (min-width: 990px) {
  .sec-richtext__heading--custom {
    font-size: var(--rt-h-size, 3rem);
  }
}

.sec-richtext__heading--medium {
  font-weight: 500;
}

.sec-richtext__heading--bold {
  font-weight: 700;
}

/* --- shared grid (multicolumn + collection_list) ------------------------------------- */
.sec-grid {
  display: grid;
  grid-template-columns: repeat(var(--sec-cols-mobile, 1), minmax(0, 1fr));
  gap: var(--sec-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* An auto-fill tablet band, so a merchant who chose 6 desktop columns does not get 6
   unreadable ones on an iPad. */
@media (min-width: 750px) {
  .sec-grid {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  }
}

@media (min-width: 990px) {
  .sec-grid {
    grid-template-columns: repeat(var(--sec-cols, 3), minmax(0, 1fr));
  }
}

/* swipe_on_mobile: below the tablet breakpoint the grid becomes a scroll-snap carousel. No JS -
   it is native overflow scrolling, so it works with scripting disabled. */
@media (max-width: 749px) {
  .sec-grid--swipe {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .sec-grid--swipe::-webkit-scrollbar {
    display: none;
  }

  .sec-grid--swipe > * {
    flex: 0 0 78%;
    scroll-snap-align: center;
  }
}

/* --- multicolumn -------------------------------------------------------------------- */
/* Basic (ST-M10a): section titles are LEFT-aligned, like every other one in the design. These
   two were centred while collage and video were not, so the homepage read as three different
   layouts stacked. */
.sec-multicolumn__title,
.sec-collections__title {
  margin-bottom: var(--sec-gap);
}

.sec-column {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
  text-align: var(--sec-text-align, left);
}

.sec-multicolumn--align-center .sec-column {
  align-items: center;
}

/* background_style = primary: Dawn calls it "Show as column background". With no colour
   schemes yet (ST-M1b) it draws the theme's own surface token. */
/* Basic (ST-M10a): the design's category columns are a full-bleed image with the label and button
   sitting ON it (477:4267) — not a tinted card with a padded box of text under it. The tint and the
   rounded corners go; the "Secondary background" setting still turns a surface on for merchants who
   want the card look, it is just no longer the shape of the default. */
.sec-column--bg-primary {
  background: var(--sec-surface);
  padding: 1.25rem;
}

.sec-column__media {
  width: 100%;
}

.sec-column__media--third {
  width: 33.3333%;
}

.sec-column__media--half {
  width: 50%;
}

.sec-column__media--full {
  width: 100%;
}

.sec-column__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
}

/* --- multicolumn, layout: overlay (Basic's category band, 477:4266) ---------------------
   Two tiles, 20px apart, running to the window edges. Each tile is its image — the grey
   placeholder until one is chosen — with the heading (48px, the heading face) and a white button
   centred on it, 20px apart. "Adapt" has no image to adapt to on an empty tile, so it takes the
   design's own proportion (950 × 798). */
.sec-multicolumn--full {
  margin-inline: calc(-1 * var(--sec-bleed));
}

/* parity_snifl_home — Multicolumn options, each behind a class printed only when chosen. */
.sec-multicolumn--radius .sec-column__media {
  border-radius: var(--mc-radius);
}

.sec-multicolumn--gap {
  gap: var(--mc-gap);
}

/* With a set space, a photo-only column (no heading, text or link) has no empty text box under the
   photo adding the column's 12px gap to the section's bottom spacing. */
.sec-multicolumn--gap .sec-column__info:empty {
  display: none;
}

@media (max-width: 809px) {
  .sec-multicolumn--gap-m {
    gap: var(--mc-gap-m);
  }
}

@media (min-width: 750px) {
  .sec-multicolumn--t-same {
    grid-template-columns: repeat(var(--sec-cols, 3), minmax(0, 1fr));
  }
}

@media (max-width: 809px) {
  .sec-title-row--m-stack {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 1rem;
  }
}

/* 10-16 pages parity: "No space between columns" (the class exists only when ticked). A column with no
   title, text or link drops its empty info box too, so a row of photos is just the photos. */
.sec-multicolumn--no-gap {
  gap: 0;
}

.sec-multicolumn--no-gap .sec-column__info:empty {
  display: none;
}

.sec-column--overlay {
  position: relative;
  display: grid;
  gap: 0;
  text-align: center;
  isolation: isolate;
}

.sec-column--overlay > .sec-column__media,
.sec-column--overlay > .sec-column__overlay-content {
  grid-area: 1 / 1;
}

.sec-column--overlay > .sec-media--adapt {
  aspect-ratio: 950 / 798;
  background: var(--sec-placeholder-bg);
}

.sec-column--overlay > .sec-media--adapt img {
  height: 100%;
}

.sec-column__overlay-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  padding: 2rem;
  pointer-events: none;
}

.sec-column__overlay-content > * {
  pointer-events: auto;
}

.sec-column__overlay-title {
  margin: 0;
  font-family: var(--font-heading, var(--font-body));
  font-size: clamp(2rem, 1.2rem + 2vw, 3rem);
  font-weight: 400;
  line-height: 1.24;
  text-transform: var(--caps-transform, uppercase);
  color: #0b0b0e;
}

/* Over a real photograph the words need the light treatment instead. */
.sec-column--overlay:has(img) .sec-column__overlay-title,
.sec-column--overlay:has(img) .sec-rte {
  color: #fefefe;
}

.sec-column--overlay .sec-buttons {
  justify-content: center;
}

/* The placeholder glyph sits in the same place as the words on an empty tile (it does in the
   design too, 477:4628) — keep it, but behind them. */
.sec-column--overlay .sec-placeholder {
  min-height: 0;
}

/* --- collection_list ---------------------------------------------------------------- */
.sec-collection-card {
  min-width: 0;
}

.sec-collection-card__link {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  color: inherit;
  text-decoration: none;
}

.sec-collection-card__link:hover {
  text-decoration: none;
}

.sec-collection-card__title {
  font-size: 1rem;
  font-weight: 500;
}

.sec-collection-card__link:hover .sec-collection-card__title {
  text-decoration: underline;
}

/* --- slideshow ---------------------------------------------------------------------- */
.sec-slideshow {
  position: relative;
}

/* layout: full_bleed reaches the window edge; layout: grid ("Page" in Dawn) stays inset. */
.sec-slideshow--full_bleed {
  margin-inline: calc(-1 * var(--sec-bleed));
}

/* A full-width hero or banner opening the page sits flush under the header (477:4222 starts on
   the navbar's bottom edge), not 16px below it on <main>'s top padding. */
main > .nscms-section:first-child:has(> .sec-slideshow--full_bleed, > .sec-banner) {
  margin-top: -1rem;
}

/* 10-16 pages parity: image_with_text's "Start right under the header" does the same for an image with text
   opening the page; the class exists only when the box is ticked. */
main > .nscms-section:first-child:has(> .sec-iwt--flush) {
  margin-top: -1rem;
}

.sec-slideshow--grid .sec-slideshow__track {
  border-radius: var(--sec-radius);
}

.sec-slideshow__track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sec-slideshow__track::-webkit-scrollbar {
  display: none;
}

.sec-slide {
  position: relative;
  flex: 0 0 100%;
  scroll-snap-align: start;
  display: grid;
  min-height: var(--sec-slide-h, 26rem);
}

.sec-slideshow--h-adapt_image {
  --sec-slide-h: auto;
}

.sec-slideshow--h-small {
  --sec-slide-h: 20rem;
}

.sec-slideshow--h-medium {
  --sec-slide-h: 26rem;
}

.sec-slideshow--h-large {
  --sec-slide-h: 32rem;
}

@media (min-width: 750px) {
  .sec-slideshow--h-small {
    --sec-slide-h: 28rem;
  }

  .sec-slideshow--h-medium {
    --sec-slide-h: 39rem;
  }

  /* Basic's hero is 853px tall on a 1920 window (477:4222) — a proportion of the width, so it
     keeps the design's shape on a laptop instead of turning into a tall grey slab. */
  .sec-slideshow--h-large {
    --sec-slide-h: clamp(32rem, 44.43vw, 53.3rem);
  }
}

.sec-slide__media,
.sec-slide__content {
  grid-area: 1 / 1;
}

/* 10-15-C fix3: `clip`, not `hidden`, as .sec-banner__media (a scroll container stops view()). */
.sec-slide__media {
  position: relative;
  overflow: hidden;
  overflow: clip;
}

/* 10-15-C fix3: the track scrolls sideways, so it is every slide's nearest scroll container and
   view() measured the photo against it, where it never moves up or down: "Zoom in" never ran. The
   slideshow itself is measured on the page instead (a named view timeline) and a zooming slide's
   photo follows that. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .sec-slideshow:has(.sec-behavior-zoom-in) {
      view-timeline: --sec-slideshow block;
    }

    .sec-slide__media.sec-behavior-zoom-in img {
      animation-timeline: --sec-slideshow;
    }
  }
}

.sec-slide__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.sec-slideshow--h-adapt_image .sec-slide__image {
  height: auto;
}

/* Basic draws the slide's shade as a GRADIENT — clear at the top, darkest behind the words at the
   bottom (477:4222: transparent → rgba(0,0,0,.3)) — not a flat wash over the whole photograph.
   The opacity setting still decides how dark the bottom gets. */
.sec-slide__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 0%, var(--sec-overlay-color) 100%);
  opacity: var(--sec-overlay, 0%);
}

.sec-slide__content {
  position: relative;
  display: grid;
  align-items: var(--sec-y, center);
  justify-items: var(--sec-x, center);
  /* The side padding keeps the words clear of the arrows, which sit on the page gutter. */
  padding: 2.5rem max(4.5rem, calc((100% - var(--maxw)) / 2 + 4.5rem));
}

@media (min-width: 750px) {
  .sec-slide__content {
    padding-block: 5rem; /* the design's 80px under the button */
  }
}

.sec-slide__box {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  max-width: min(46rem, 100%);
  padding: 2rem;
  border-radius: var(--sec-radius);
  background: var(--sec-box-bg);
  text-align: var(--sec-text-align, center);
}

.sec-slide__box--plain {
  background: none;
  padding: 0;
  color: #fefefe;
  /* The design's rhythm: 8px heading → line, 24px line → button (477:4225/4226). */
  gap: 0.5rem;
  /* 1020px of words on the design (477:4225) — room for the title on one line. */
  max-width: min(63.75rem, 100%);
}

.sec-slide__box--plain .sec-buttons {
  margin-top: 1rem;
}

/* The hero line: 14px, 1.4px tracking (477:4228). The heading carries no tracking (477:4227). */
.sec-slide .sec-heading {
  letter-spacing: 0;
  line-height: 1.24;
}

.sec-slide .sec-text {
  font-size: 0.875rem;
  letter-spacing: 0.0875rem;
}

/* On a photograph the button inverts — white with dark type (477:4229) — so it reads against the
   image whatever colour the merchant's own buttons are. The category band does the same. */
.sec-slide__box--plain .sec-button:not(.sec-button--secondary),
.sec-column--overlay .sec-button:not(.sec-button--secondary) {
  background: #fefefe;
  border-color: #fefefe;
  color: #0b0b0e;
}

.sec-slide .sec-placeholder svg {
  width: 100px; /* the hero's larger glyph (477:4420) */
}

@media (max-width: 749px) {
  .sec-slideshow--mobile-below .sec-slide {
    display: block;
    min-height: 0;
  }

  .sec-slideshow--mobile-below .sec-slide__content {
    padding: 1.25rem;
  }

  .sec-slideshow--mobile-below .sec-slide__box--plain {
    color: inherit;
    text-shadow: none;
  }
}

/* Basic lays the controls OVER the slide (477:4223): a bare white arrow on each page gutter, level
   with the words, and nothing between them. The page indicator the merchant chose (counter, dots
   or numbers) keeps its place as a quiet line along the bottom edge. The row itself lets clicks
   through — only the arrows and the indicator catch them — so it never blocks the slide's button. */
.sec-slideshow__controls {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 max(1.25rem, calc((100% - var(--maxw)) / 2)) 9.5rem;
  color: #fefefe;
  pointer-events: none;
}

.sec-slideshow__controls > * {
  pointer-events: auto;
}

.sec-slideshow__controls .sec-slideshow__pagination,
.sec-slideshow__controls .sec-slideshow__counter {
  position: absolute;
  left: 50%;
  bottom: 1.5rem;
  transform: translateX(-50%);
  font-size: 0.75rem;
  letter-spacing: 0.075rem;
}

.sec-slideshow__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  opacity: 0.9;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.sec-slideshow__arrow svg {
  width: 100%;
  height: 100%;
}

.sec-slideshow__arrow:hover {
  opacity: 1;
}

.sec-slideshow__arrow--prev:hover {
  transform: translateX(-3px);
}

.sec-slideshow__arrow--next:hover {
  transform: translateX(3px);
}

@media (max-width: 749px) {
  .sec-slideshow__controls {
    padding-bottom: 1rem;
  }

  .sec-slideshow__arrow {
    width: 2rem;
    height: 2rem;
  }
}

/* The arrows are progressive enhancement: they ship hidden and the inline script reveals them,
   so a no-JS shopper never sees a dead control. Restate display:none - `display:inline-flex`
   above would otherwise beat the [hidden] UA rule. */
.sec-slideshow__arrow[hidden] {
  display: none;
}

.sec-slideshow__pagination {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sec-slideshow__pagination a {
  display: block;
  color: inherit;
  text-decoration: none;
  opacity: 0.45;
}

.sec-slideshow__pagination a:hover,
.sec-slideshow__pagination [aria-current="true"] {
  opacity: 1;
  text-decoration: none;
}

.sec-slideshow__dot {
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: currentColor;
}

.sec-slideshow__pagination--numbers a {
  padding: 0.1rem 0.45rem;
  font-variant-numeric: tabular-nums;
}

.sec-slideshow__pagination--numbers [aria-current="true"] {
  font-weight: 600;
  text-decoration: underline;
}

.sec-slideshow__counter {
  margin: 0;
  font-variant-numeric: tabular-nums;
  opacity: 0.75;
}

/* --- motion ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .sec-slideshow__track,
  .sec-grid--swipe {
    scroll-behavior: auto;
  }
}

/* --- dark mode (shopper preference, mirrors base.css) -------------------------------- */
html[data-theme="dark"] {
  --sec-border: #334155;
  --sec-surface: #1e293b;
  --sec-muted: #94a3b8;
  --sec-placeholder-bg: #1e293b;
  --sec-box-bg: rgba(15, 23, 42, 0.9);
}

/* ===================================================================================== *
 * SECOND WAVE (ST-M7 remainder): collage, video, collapsible_content.
 *
 * Appended, never interleaved, so the first five sections' rules keep their cascade
 * position. Same rule as above: every variation here is driven by a SECTION or BLOCK
 * SETTING taken from real Dawn source - merchants never write CSS (D2). New vocabulary:
 *
 *   .sec-collage--{left|right}            desktop_layout (which tile is the large one)
 *   .sec-collage--m-{collage|column}      mobile_layout
 *   .sec-collage__card--{none|product-card-wrapper}   card_styles
 *   .sec-video--full                      full_width
 *   .sec-collapsible--container-{none|row|section}    layout ("Container")
 *   .sec-collapsible--halign-{left|center|right}      heading_alignment
 *   .sec-collapsible__grid--{image_first|image_second}  desktop_layout ("Placement")
 *   .sec-collapsible__media--{adapt|small|large}      image_ratio
 * ===================================================================================== */

/* A heading the merchant blanked still needs to exist for screen readers + the document
   outline (Dawn does the same with its own .visually-hidden). Namespaced `sec-` because
   header.css owns the unprefixed one and is not linked on every surface. */
.sec-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- collage ------------------------------------------------------------------------ */
.sec-collage__title {
  margin-bottom: var(--sec-gap);
}

/* Mobile default is Dawn's `column`: one tile per row. */
.sec-collage {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sec-gap);
}

/* mobile_layout: collage - two tiles per row, with the large one spanning both. */
@media (max-width: 749px) {
  .sec-collage--m-collage {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sec-collage--m-collage.sec-collage--left > .sec-collage__item:first-child,
  .sec-collage--m-collage.sec-collage--right > .sec-collage__item:last-child {
    grid-column: span 2;
  }
}

/* Desktop: three columns, and the large tile takes two of them over two rows - which is
   what makes Dawn's collage a collage rather than a grid. */
@media (min-width: 750px) {
  .sec-collage {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: stretch;
  }

  .sec-collage--left > .sec-collage__item:first-child,
  .sec-collage--right > .sec-collage__item:last-child {
    grid-column: span 2;
    grid-row: span 2;
  }
}

.sec-collage__item {
  min-width: 0;
  display: flex;
}

.sec-collage__card {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  width: 100%;
  min-width: 0;
}

/* card_styles: `product-card-wrapper` is Dawn's "Style all as product cards"; with no colour
   schemes yet (ST-M1b) the chrome comes from the theme's own surface token. `none` is
   Dawn's "Use individual card styles", which for us means no chrome at all. */
.sec-collage__card--product-card-wrapper {
  padding: 0.75rem;
  border-radius: var(--sec-radius);
  background: var(--sec-surface);
}

.sec-collage__link {
  color: inherit;
  text-decoration: none;
}

.sec-collage__link:hover {
  text-decoration: none;
}

.sec-collage__link:hover .sec-collage__caption {
  text-decoration: underline;
}

/* Dawn's `second_image` (show the second image on hover) reaches the markup as
   .sec-collage__link--hover-second but is INERT: card drops carry only featured_image, so
   there is no second image to cross-fade to. Same deferral ST-M2 logged for its cards. */

/* The media fills whatever the grid gave the tile, so a large tile really looks larger. */
.sec-collage__media {
  flex: 1 1 auto;
}

/* Basic (477:4252): the tile's name in the body face, 16px uppercase with 1.6px tracking, and a
   16px arrow 8px after it; 20px under the image. */
.sec-collage__card {
  gap: 1.25rem;
}

.sec-collage__caption {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: var(--caps-spacing, 0.1rem);
  text-transform: var(--caps-transform, uppercase);
}

.sec-collage__arrow {
  width: 1rem;
  height: 1rem;
  flex: none;
  transition: transform 0.15s ease;
}

.sec-collage__link:hover .sec-collage__caption {
  text-decoration: none;
}

.sec-collage__link:hover .sec-collage__arrow {
  transform: translateX(3px);
}

/* The design's proportions: the large tile is square, and the two beside it split its height
   with 64px between them (477:4255) — so the small tiles take whatever height the large one
   sets instead of each insisting on being square themselves. */
@media (min-width: 750px) {
  .sec-collage {
    column-gap: 1.25rem;
    row-gap: 4rem;
  }

  .sec-collage__item:not(.sec-collage__item--large) .sec-collage__media {
    aspect-ratio: auto;
    min-height: 12rem;
  }
}

/* --- video -------------------------------------------------------------------------- */
.sec-video__title {
  margin-bottom: var(--sec-gap);
}

.sec-video--full {
  margin-inline: calc(-1 * var(--sec-bleed));
}

.sec-video__frame {
  position: relative;
}

.sec-video__poster {
  --sec-ratio: 16 / 9;

  display: block;
  color: inherit;
}

.sec-video__poster:hover {
  text-decoration: none;
}

.sec-video__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sec-video__play {
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4rem;
  height: 4rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--sec-box-bg);
  color: var(--text, #111);
  box-shadow: 0 2px 14px rgba(0, 0, 0, 0.25);
}

.sec-video__poster:hover .sec-video__play {
  background: #fff;
}

.sec-video__play svg {
  width: 44%;
  height: auto;
}

/* The iframe replaces the poster in place, so it inherits the poster's box. */
.sec-video__iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--sec-radius);
}

/* --- collapsible_content ------------------------------------------------------------ */
.sec-collapsible__header {
  margin-bottom: var(--sec-gap);
}

.sec-collapsible--halign-left .sec-collapsible__header {
  text-align: left;
}

.sec-collapsible--halign-center .sec-collapsible__header {
  text-align: center;
}

.sec-collapsible--halign-right .sec-collapsible__header {
  text-align: right;
}

.sec-collapsible__caption {
  margin-bottom: 0.35rem;
  opacity: 0.75;
}

/* layout ("Container"): `none` is bare, `section` boxes the whole section, `row` boxes each
   row (handled on .sec-accordion--boxed below). */
.sec-collapsible--container-section {
  padding: 1.5rem;
  border-radius: var(--sec-radius);
  background: var(--sec-surface);
}

.sec-collapsible__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sec-gap);
}

@media (min-width: 750px) {
  .sec-collapsible__grid--with-image {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }

  /* desktop_layout image_second = the image sits AFTER the rows. Order, not source order,
     so the rows stay first in the DOM for keyboard + screen-reader users. */
  .sec-collapsible__grid--image_second.sec-collapsible__grid--with-image .sec-collapsible__media {
    order: 2;
  }
}

.sec-collapsible__media--adapt {
  aspect-ratio: auto;
  background: none;
}

.sec-collapsible__media--adapt .sec-collapsible__image {
  height: auto;
}

.sec-collapsible__media--small {
  aspect-ratio: auto;
  height: 20rem;
}

.sec-collapsible__media--large {
  aspect-ratio: auto;
  height: 40rem;
}

.sec-collapsible__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sec-collapsible__rows {
  min-width: 0;
}

/* --- the accordion row (no JavaScript: <details> opens natively) --------------------- */
.sec-accordion {
  border-bottom: 1px solid var(--sec-border);
}

.sec-accordion--boxed {
  margin-bottom: 0.6rem;
  padding: 0 1rem;
  border: 1px solid var(--sec-border);
  border-radius: var(--sec-radius);
  background: var(--sec-surface);
}

.sec-accordion__summary {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.95rem 0;
  cursor: pointer;
  list-style: none;
}

/* Safari/Chrome draw their own marker; the caret below is ours. */
.sec-accordion__summary::-webkit-details-marker {
  display: none;
}

.sec-accordion__summary::marker {
  content: "";
}

.sec-accordion__title {
  margin: 0;
  flex: 1 1 auto;
  font-size: 1.05rem;
  font-weight: 500;
  line-height: 1.35;
}

.sec-accordion__icon {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
}

.sec-accordion__svg {
  width: 100%;
  height: auto;
  fill: currentColor;
}

/* 10-15-C §2 (S5): feature_row's "Icon from the icon set" — the same line icon as a collapsible row,
   drawn at the emoji's size (2rem) and centred over the title like the emoji line it replaces. */
.feature-row__icon {
  display: flex;
  justify-content: center;
  line-height: 1;
}

.feature-row__icon .sec-accordion__icon {
  width: 2rem;
  height: 2rem;
}

.sec-accordion__caret {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  opacity: 0.7;
}

.sec-accordion__caret svg {
  width: 100%;
  height: auto;
}

.sec-accordion[open] .sec-accordion__caret {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: no-preference) {
  .sec-accordion__caret {
    transition: transform 0.15s ease-in-out;
  }
}

.sec-accordion__content {
  padding: 0 0 1rem;
}

.sec-accordion--boxed .sec-accordion__content {
  padding-bottom: 0.85rem;
}

.sec-accordion__page {
  margin: 0.5rem 0 0;
}

/* --- scroll_burst (10-15-C §3) ------------------------------------------------------------
 * N5 "Scroll burst": a sticky stage one screen tall over a scroll runway. Up to 8 images start
 * stacked in the centre and fly out to their end positions (--bx / --by: % of the stage from its
 * centre, --bs: the end size in %), while the text block grows and fades in.
 *
 * Scroll-driven CSS only: the section is a named view timeline (--sec-burst) and its images and
 * text animate on it. No scroll listener, no script.
 *
 * THE FINISHED STATE IS THE RESTING STYLE. The rules outside the @supports block draw the end of
 * the animation, and the keyframes only name where things START (an implicit `to` is the resting
 * style). So without animation-timeline, or for a shopper who prefers reduced motion, the section
 * shows the finished picture, still, and the runway is dropped so there is nothing empty to scroll.
 * The stage is a full screen, so % of the stage is vw / vh (no container queries needed).
 * ----------------------------------------------------------------------------------------- */
.sec-burst {
  position: relative;
  margin-inline: calc(-1 * var(--sec-bleed));
}

.sec-burst__stage {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  overflow: hidden;
}

@supports (height: 100svh) {
  .sec-burst__stage {
    height: 100svh;
  }
}

.sec-burst__runway {
  height: var(--burst-runway, 0px);
}

/* 10-15-C fix3: the text is drawn above the images (z-index 2 over their 1), so wherever an image
   ends up on a narrow screen the words stay readable; the images pass behind them. */
.sec-burst__text {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  max-width: 72rem;
  padding-inline: 1.5rem;
  text-align: center;
}

.sec-burst__heading {
  font-size: var(--burst-h-m);
  line-height: 1;
}

.sec-burst__heading--medium {
  font-weight: 500;
}

.sec-burst__heading--bold {
  font-weight: 700;
}

.sec-burst__heading--as-typed {
  text-transform: none;
  letter-spacing: 0;
}

/* 10-16 G2: the section's own "Heading in capitals" wins over the theme's Headings and labels. On,
   it clears the theme's two tokens here (`initial` makes a custom property unset), so .sec-heading's
   own capitals and tracking stand even when the theme is set to As typed. */
.sec-burst__heading:not(.sec-burst__heading--as-typed) {
  --caps-transform: initial;
  --caps-spacing: initial;
}

.sec-burst__heading--accent {
  color: var(--primary);
}

/* 10-15-C fix3: Heading colour › Pick a colour (a hex, printed on the heading only then). */
.sec-burst__heading--custom {
  color: var(--burst-h-color, inherit);
}

.sec-burst__line--subtitle {
  font-size: 1.1rem;
  opacity: 0.88;
}

.sec-burst__line--large {
  font-size: 1.75rem;
  font-weight: 500;
  line-height: 1.2;
}

/* The images sit behind the text (10-15-C fix3, see .sec-burst__text) and never take a click. */
.sec-burst__images {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.sec-burst__item {
  position: absolute;
  top: 50%;
  left: 50%;
  /* Block 1 on top of the stack. */
  z-index: calc(10 - var(--bi, 0));
  width: var(--burst-size-m);
  aspect-ratio: var(--burst-ratio, 1 / 1);
  overflow: hidden;
  border-radius: var(--burst-radius-m);
  background: var(--sec-placeholder-bg);
  transform: translate(calc(-50% + var(--bx, 0) * 1vw), calc(-50% + var(--by, 0) * 1vh)) scale(calc(var(--bs, 100) / 100));
}

.sec-burst--portrait {
  --burst-ratio: 3 / 4;
}

.sec-burst--landscape {
  --burst-ratio: 4 / 3;
}

.sec-burst__image,
.sec-burst__item .sec-placeholder {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: cover;
}

@media (min-width: 750px) {
  .sec-burst__text {
    gap: 2.25rem;
  }

  .sec-burst__heading {
    font-size: var(--burst-h);
  }

  .sec-burst__line--large {
    font-size: 2.125rem;
  }

  .sec-burst__item {
    width: var(--burst-size);
    border-radius: var(--burst-radius);
  }
}

@keyframes sec-burst-fly {
  from {
    transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes sec-burst-reveal {
  from {
    opacity: 0;
    transform: scale(0.9);
  }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .sec-burst {
      view-timeline: --sec-burst block;
    }

    /* contain 0% = the section's top reaches the top of the screen (the stage sticks); contain 100% =
       its bottom reaches the bottom (the stage lets go). The last tenth holds the finished picture. */
    .sec-burst__item {
      animation: sec-burst-fly linear both;
      animation-timeline: --sec-burst;
      animation-range: contain 0% contain 90%;
    }

    /* 10-15-C fix3: the text comes in late, over the last fifth of the runway, after the images
       have mostly flown out: on the first client site's 1000px runway it starts at 800px and is
       at 0.62 opacity and 0.96 scale at 900px (measured there: about 0.65 and 0.96), finished
       at 960px, before the stage lets go. It was 45% to 90%. */
    .sec-burst__text {
      animation: sec-burst-reveal linear both;
      animation-timeline: --sec-burst;
      animation-range: contain 80% contain 96%;
    }
  }
}

/* parity_snifl_home — scroll_burst options, each behind a class the template prints only when chosen.
   "The same distance on every screen": the end positions are % of a 1440 x 900 stage whatever the
   screen, so the client site's measured offsets (SITE_MEASUREMENTS.md §4.3, identical at 1440, 810
   and 390) hold on a tablet and a phone too. */
.sec-burst--fixed .sec-burst__item {
  transform: translate(calc(-50% + var(--bx, 0) * 14.4px), calc(-50% + var(--by, 0) * 9px)) scale(calc(var(--bs, 100) / 100));
}

/* Heading size on tablets (750-1199px), the line length, the text line's weight, the gap. */
@media (min-width: 750px) and (max-width: 1199px) {
  .sec-burst--h-tablet .sec-burst__heading {
    font-size: var(--burst-h-t);
  }
}

.sec-burst--h-max .sec-burst__heading {
  max-width: var(--burst-h-max, none);
  text-wrap: wrap;
}

.sec-burst__heading-line {
  display: block;
}

.sec-burst--gap .sec-burst__text {
  gap: var(--burst-gap);
}

.sec-burst__line--section_heading {
  font-family: var(--font-heading, var(--font-body));
  font-size: var(--sec-h2);
  line-height: 1.22;
  font-weight: var(--sec-heading-weight, 400);
}

.sec-burst__line--w-regular {
  font-weight: 400;
}

.sec-burst__line--w-medium {
  font-weight: 500;
}

.sec-burst__line--w-semibold {
  font-weight: 600;
}

.sec-burst__line--w-bold {
  font-weight: 700;
}

/* "Pause on the finished picture" off: the images fly for the whole scroll length. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .sec-burst--no-hold .sec-burst__item {
      animation-range: contain 0% contain 100%;
    }
  }
}

/* The still fallbacks: the finished picture above, with no runway to scroll through. */
@supports not (animation-timeline: view()) {
  .sec-burst__runway {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sec-burst__runway {
    display: none;
  }

  .sec-burst__item,
  .sec-burst__text {
    animation: none;
  }
}

/* --- scrolling_text (10-15-C §3) -------------------------------------------------------
   N2: a strip of text items that scrolls sideways forever. sections/scrolling_text.liquid prints
   the items once plus aria-hidden copies; the track slides by exactly one copy (100% / copies of
   its own width) and starts over, which is where the second copy sat at the start, so the loop has
   no visible jump. assets/marquee.js sets --marquee-duration from one copy's measured width so the
   speed is px per second, and adds copies on a wide screen. The strip carries the section's colour
   scheme (its own setting), so it can be rounded while the section's padding keeps the page colour. */
.sec-marquee {
  /* 10-15-C fix3: the template prints the two gaps under their own names and this picks one (the
     phone one below 750px). An inline --marquee-gap used to beat the phone rule. */
  --marquee-gap: var(--marquee-gap-desktop, 48px);
  display: flex;
  align-items: center;
  min-height: var(--marquee-height, 48px);
  overflow: hidden;
  border-radius: var(--marquee-radius, var(--sec-radius, 0));
  background: var(--marquee-bg, transparent);
  color: var(--marquee-fg, inherit);
}

.sec-marquee--full {
  margin-inline: calc(-1 * var(--sec-bleed));
}

.sec-marquee__track {
  display: flex;
  flex: 0 0 auto;
  width: max-content;
}

.sec-marquee__group {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: var(--marquee-gap, 48px);
  margin: 0;
  /* The gap after the last item, so the join between two copies is an ordinary gap. */
  padding: 0 var(--marquee-gap, 48px) 0 0;
  list-style: none;
}

.sec-marquee__item {
  font-size: var(--marquee-size, 16px);
  font-weight: var(--marquee-weight, 400);
  line-height: 1.4;
  white-space: nowrap;
}

@media (max-width: 749px) {
  .sec-marquee {
    --marquee-gap: var(--marquee-gap-mobile, 24px);
  }
}

@keyframes sec-marquee-scroll {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(calc(-100% / var(--marquee-copies, 2)));
  }
}

@media (prefers-reduced-motion: no-preference) {
  .sec-marquee__track {
    animation: sec-marquee-scroll var(--marquee-duration, 20s) linear infinite;
  }

  .sec-marquee--right .sec-marquee__track {
    animation-direction: reverse;
  }

  .sec-marquee--pause:hover .sec-marquee__track,
  .sec-marquee--pause:focus-within .sec-marquee__track {
    animation-play-state: paused;
  }
}

/* Reduced motion: no movement at all. The items show once, still and centred, wrapping onto more
   lines when they do not fit, and the copies are hidden. */
@media (prefers-reduced-motion: reduce) {
  .sec-marquee__track {
    flex: 1 1 auto;
    width: auto;
    animation: none;
    transform: none;
  }

  .sec-marquee__group {
    flex: 1 1 auto;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 0.25rem;
    padding: 0.5rem 1rem;
  }

  .sec-marquee__group[aria-hidden="true"] {
    display: none;
  }

  .sec-marquee__item {
    white-space: normal;
    text-align: center;
  }
}

/* --- image_with_text (10-15-C §3) ---------------------------------------------------------
   sections/image_with_text.liquid (BUILD_BRIEF_2026-10-15-C N1). Every selector here starts with
   .sec-iwt, so nothing else on a page can change. The template prints the merchant's numbers as
   --iwt-* properties on .sec-iwt (already clamped); the classes carry the choices.

   FULL-WIDTH BAND. The theme's section wrapper (.nscms-section, base.css) spans only the page
   column, so a coloured scheme would paint a box in the middle of the page. .sec-iwt therefore
   reaches the window edge (--sec-bleed, like rich_text_v2's full width) and repaints the scheme's
   background (--section-background, inherited from the wrapper) and the wrapper's padding
   (--section-pt / --section-pb, cancelled out of the wrapper with the negative margins), so the
   band, its padding included, runs edge to edge. With the base scheme and no padding all of it
   resolves to nothing.

   IMAGE HEIGHT. Each state (wide = side by side, narrow = stacked) has four properties: the box's
   aspect-ratio and height, and the image's position and height inside it. The -d set is the wide
   one, the -m set the stacked one ("same" copies -d). A shaped box (ratio or set height) holds the
   image absolutely and crops it (cover); "the image's own shape" lets the image size the box. */
.sec-iwt {
  --iwt-ar-d: auto;
  --iwt-h-d: auto;
  --iwt-pos-d: static;
  --iwt-ih-d: auto;
  --iwt-ar-m: var(--iwt-ar-d);
  --iwt-h-m: var(--iwt-h-d);
  --iwt-pos-m: var(--iwt-pos-d);
  --iwt-ih-m: var(--iwt-ih-d);
  margin-inline: calc(-1 * var(--sec-bleed));
  margin-block: calc(-1 * var(--section-pt, 0px)) calc(-1 * var(--section-pb, 0px));
  padding-block: var(--section-pt, 0px) var(--section-pb, 0px);
  /* 10-16 pages parity: "Color behind the text" (--iwt-text-bg, printed only when set) wins over the scheme. */
  background: var(--iwt-text-bg, var(--section-background, transparent));
}

.sec-iwt--boxed {
  padding-inline: var(--sec-bleed);
}

.sec-iwt--h-square { --iwt-ar-d: 1 / 1; --iwt-pos-d: absolute; --iwt-ih-d: 100%; }
.sec-iwt--h-portrait { --iwt-ar-d: 3 / 4; --iwt-pos-d: absolute; --iwt-ih-d: 100%; }
.sec-iwt--h-landscape { --iwt-ar-d: 4 / 3; --iwt-pos-d: absolute; --iwt-ih-d: 100%; }
.sec-iwt--h-custom { --iwt-h-d: var(--iwt-hpx); --iwt-pos-d: absolute; --iwt-ih-d: 100%; }

.sec-iwt--mh-adapt { --iwt-ar-m: auto; --iwt-h-m: auto; --iwt-pos-m: static; --iwt-ih-m: auto; }
.sec-iwt--mh-square { --iwt-ar-m: 1 / 1; --iwt-h-m: auto; --iwt-pos-m: absolute; --iwt-ih-m: 100%; }
.sec-iwt--mh-portrait { --iwt-ar-m: 3 / 4; --iwt-h-m: auto; --iwt-pos-m: absolute; --iwt-ih-m: 100%; }
.sec-iwt--mh-landscape { --iwt-ar-m: 4 / 3; --iwt-h-m: auto; --iwt-pos-m: absolute; --iwt-ih-m: 100%; }
.sec-iwt--mh-custom { --iwt-ar-m: auto; --iwt-h-m: var(--iwt-mhpx); --iwt-pos-m: absolute; --iwt-ih-m: 100%; }

/* Stacked (phones, or phones and tablets): one column, the image above or below the words. */
.sec-iwt__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--iwt-m-gap, 24px);
}

.sec-iwt--m-image-below .sec-iwt__media-col {
  order: 1;
}

.sec-iwt__media-col {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  padding: min(var(--iwt-inset, 0px), var(--iwt-m-pad, 20px));
  background: var(--iwt-backdrop, transparent);
}

/* 10-15-C fix3: overflow `clip`, not `hidden`. hidden made this box a scroll container, so the
   zoom's view() timeline measured the photo against the box (where it never moves) and stopped at
   one scale. clip cuts the zoomed photo the same way and lets view() reach the page's scroll. */
.sec-iwt__media {
  position: relative;
  overflow: hidden;
  overflow: clip;
  border-radius: var(--iwt-radius, var(--sec-radius, 0));
  aspect-ratio: var(--iwt-ar-m);
  height: var(--iwt-h-m);
}

.sec-iwt__media > img,
.sec-iwt__media > .sec-placeholder {
  display: block;
  position: var(--iwt-pos-m);
  inset: 0;
  width: 100%;
  height: var(--iwt-ih-m);
  object-fit: cover;
  object-position: center;
}

/* No image yet: the placeholder needs a shape of its own when the box takes the image's. */
.sec-iwt__media > .sec-placeholder {
  display: flex;
  min-height: 0;
  aspect-ratio: 4 / 3;
}

.sec-iwt__text-col {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  min-width: 0;
  padding-block: var(--iwt-text-py, 0px);
}

/* Edge to edge on a narrow screen: the image spans the window, the words keep off its edges. */
.sec-iwt--full .sec-iwt__text-col {
  padding-inline: var(--iwt-m-pad, 20px);
}

.sec-iwt--valign-top .sec-iwt__text-col { justify-content: flex-start; }
.sec-iwt--valign-bottom .sec-iwt__text-col { justify-content: flex-end; }
.sec-iwt--box-center .sec-iwt__text-col { align-items: center; }
.sec-iwt--box-right .sec-iwt__text-col { align-items: flex-end; }

.sec-iwt__content {
  display: flex;
  flex-direction: column;
  gap: var(--iwt-content-gap, 1rem);
  width: 100%;
  max-width: var(--iwt-text-max, none);
  text-align: left;
  --sec-flex-x: flex-start;
}

.sec-iwt--align-center .sec-iwt__content { text-align: center; --sec-flex-x: center; }
.sec-iwt--align-right .sec-iwt__content { text-align: right; --sec-flex-x: flex-end; }

/* 10-15-C fix3: "Text alignment on phones", while the text sits under the image (below 750px, or
   below 990px with "On phones and tablets"). No class at its default, so Text alignment stands. */
@media (max-width: 749px) {
  .sec-iwt--m-align-left .sec-iwt__content { text-align: left; --sec-flex-x: flex-start; }
  .sec-iwt--m-align-center .sec-iwt__content { text-align: center; --sec-flex-x: center; }
  .sec-iwt--m-align-right .sec-iwt__content { text-align: right; --sec-flex-x: flex-end; }
}

@media (max-width: 989px) {
  .sec-iwt--stack-tablet.sec-iwt--m-align-left .sec-iwt__content { text-align: left; --sec-flex-x: flex-start; }
  .sec-iwt--stack-tablet.sec-iwt--m-align-center .sec-iwt__content { text-align: center; --sec-flex-x: center; }
  .sec-iwt--stack-tablet.sec-iwt--m-align-right .sec-iwt__content { text-align: right; --sec-flex-x: flex-end; }
}

/* 10-15-C fix3: a link in the text follows the text's own colour, underlined, so it reads on every
   colour scheme. The link colour is the scheme's outline-button colour, which on a dark band can be
   as dark as the band (it also paints the solid buttons, so a scheme cannot simply lighten it). */
.sec-iwt .sec-rte a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* The heading block's "Heading in capitals" (off) and "Heading weight". */
.sec-iwt .sec-iwt__heading--as-typed {
  text-transform: none;
  letter-spacing: 0;
}

/* 10-16 G2: as for Scroll burst — the block's switch, when on, wins over the theme's As typed. */
.sec-iwt .sec-heading:not(.sec-iwt__heading--as-typed) {
  --caps-transform: initial;
  --caps-spacing: initial;
}

.sec-iwt .sec-iwt__heading--medium { font-weight: 500; }
.sec-iwt .sec-iwt__heading--bold { font-weight: 700; }

/* "Custom size": the block's own two px sizes (the template clamps them), the smaller one below
   990px, where the theme's own heading ladder has already stepped down too. */
.sec-iwt .sec-iwt__heading--custom { font-size: var(--iwt-h-size-m, 2rem); }

@media (min-width: 990px) {
  .sec-iwt .sec-iwt__heading--custom { font-size: var(--iwt-h-size, 3rem); }
}

/* An item: a short heading over a line or two of text, in the heading face but in the case it was
   typed (the section headings keep the theme's capitals unless their block says otherwise). */
.sec-iwt__item {
  display: grid;
  gap: 0.5rem;
}

.sec-iwt__item-heading {
  margin: 0;
  font-family: var(--font-heading, var(--font-body));
  font-weight: 500;
  line-height: 1.22;
}

.sec-iwt__item-heading--small { font-size: 1.125rem; }
.sec-iwt__item-heading--medium { font-size: 1.375rem; }
.sec-iwt__item-heading--large { font-size: 1.75rem; }

/* 10-15-C fix3: the item's "Heading size on phones" (px, printed on the heading only when set). */
@media (max-width: 749px) {
  .sec-iwt .sec-iwt__item-heading--m-size { font-size: var(--iwt-ih-size-m); }
}

/* 10-16 pages parity: "Space above the text on phones" — while stacked, the text has this space above
   it and none below (the space between image and text follows). The class exists only when it is set. */
@media (max-width: 749px) {
  .sec-iwt--m-pt .sec-iwt__text-col { padding-block: var(--iwt-m-pt, 0px) 0; }
}

@media (max-width: 989px) {
  .sec-iwt--m-pt.sec-iwt--stack-tablet .sec-iwt__text-col { padding-block: var(--iwt-m-pt, 0px) 0; }
}

/* 10-16 pages parity: the eyebrow's "Extra small" step (10px, set solid, a little tracking), and the
   text block's "Paragraphs: side by side" and plain "Links in the text". Classes printed only then. */
.sec-iwt .sec-caption--xsmall {
  font-size: 10px;
  line-height: 1;
  letter-spacing: 0.02em;
}

.sec-iwt .sec-rte--two-up {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 8px;
}

.sec-iwt .sec-rte--two-up > * {
  margin: 0;
}

.sec-iwt .sec-rte--plain-links a {
  text-decoration: none;
}

/* "Text only" button: the outline button without its outline or side padding, so it lines up with
   the words and still sits on the button row. Its colour is the link colour unless the block picked
   one (--iwt-link, printed on the link itself only then). */
.sec-iwt .sec-iwt__text-button {
  border-color: transparent;
  padding-inline: 0;
  color: var(--iwt-link, var(--color-link, var(--primary, currentColor)));
}

/* Side by side. Written twice, once per "Put the text under the image" choice, because the two
   differ only in the width they start at. The image's column is its share of what is left after
   the space between; edge to edge, the space beside the text comes off first (the grid's padding
   on the text's side). */
@media (min-width: 750px) {
  .sec-iwt--stack-phone .sec-iwt__grid {
    grid-template-columns: calc((100% - var(--iwt-gap, 48px)) * var(--iwt-w, 50) / 100) minmax(0, 1fr);
    grid-template-areas: "media text";
    column-gap: var(--iwt-gap, 48px);
    row-gap: 0;
  }

  .sec-iwt--stack-phone.sec-iwt--image-right .sec-iwt__grid {
    grid-template-columns: minmax(0, 1fr) calc((100% - var(--iwt-gap, 48px)) * var(--iwt-w, 50) / 100);
    grid-template-areas: "text media";
  }

  .sec-iwt--stack-phone.sec-iwt--full.sec-iwt--image-left .sec-iwt__grid { padding-inline-end: var(--iwt-gutter, 20px); }
  .sec-iwt--stack-phone.sec-iwt--full.sec-iwt--image-right .sec-iwt__grid { padding-inline-start: var(--iwt-gutter, 20px); }
  .sec-iwt--stack-phone .sec-iwt__media-col { grid-area: media; order: 0; padding: var(--iwt-inset, 0px); padding-top: var(--iwt-inset-top, var(--iwt-inset, 0px)); }
  .sec-iwt--stack-phone .sec-iwt__text-col { grid-area: text; padding-inline: 0; }
  .sec-iwt--stack-phone.sec-iwt--no-text .sec-iwt__grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "media"; }

  .sec-iwt--stack-phone .sec-iwt__media {
    aspect-ratio: var(--iwt-ar-d);
    height: var(--iwt-h-d);
  }

  .sec-iwt--stack-phone .sec-iwt__media > img,
  .sec-iwt--stack-phone .sec-iwt__media > .sec-placeholder {
    position: var(--iwt-pos-d);
    height: var(--iwt-ih-d);
  }

  /* "Keep the image in view": the image's column still fills the row (so a colour around the image
     runs its full height) and the image inside it is pinned. */
  .sec-iwt--stack-phone.sec-iwt--sticky .sec-iwt__media-col { justify-content: flex-start; }
  .sec-iwt--stack-phone.sec-iwt--sticky .sec-iwt__media { position: sticky; top: var(--iwt-sticky-top, 0px); }
}

@media (min-width: 990px) {
  .sec-iwt--stack-tablet .sec-iwt__grid {
    grid-template-columns: calc((100% - var(--iwt-gap, 48px)) * var(--iwt-w, 50) / 100) minmax(0, 1fr);
    grid-template-areas: "media text";
    column-gap: var(--iwt-gap, 48px);
    row-gap: 0;
  }

  .sec-iwt--stack-tablet.sec-iwt--image-right .sec-iwt__grid {
    grid-template-columns: minmax(0, 1fr) calc((100% - var(--iwt-gap, 48px)) * var(--iwt-w, 50) / 100);
    grid-template-areas: "text media";
  }

  .sec-iwt--stack-tablet.sec-iwt--full.sec-iwt--image-left .sec-iwt__grid { padding-inline-end: var(--iwt-gutter, 20px); }
  .sec-iwt--stack-tablet.sec-iwt--full.sec-iwt--image-right .sec-iwt__grid { padding-inline-start: var(--iwt-gutter, 20px); }
  /* 10-16 pages parity: padding-top is "Space above the image" (unset = Space around the image, as before). */
  .sec-iwt--stack-tablet .sec-iwt__media-col { grid-area: media; order: 0; padding: var(--iwt-inset, 0px); padding-top: var(--iwt-inset-top, var(--iwt-inset, 0px)); }
  .sec-iwt--stack-tablet .sec-iwt__text-col { grid-area: text; padding-inline: 0; }
  .sec-iwt--stack-tablet.sec-iwt--no-text .sec-iwt__grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "media"; }

  .sec-iwt--stack-tablet .sec-iwt__media {
    aspect-ratio: var(--iwt-ar-d);
    height: var(--iwt-h-d);
  }

  .sec-iwt--stack-tablet .sec-iwt__media > img,
  .sec-iwt--stack-tablet .sec-iwt__media > .sec-placeholder {
    position: var(--iwt-pos-d);
    height: var(--iwt-ih-d);
  }

  .sec-iwt--stack-tablet.sec-iwt--sticky .sec-iwt__media-col { justify-content: flex-start; }
  .sec-iwt--stack-tablet.sec-iwt--sticky .sec-iwt__media { position: sticky; top: var(--iwt-sticky-top, 0px); }
}

/* "Zoom image as you scroll": the theme's scroll-driven zoom (image_behavior zoom-in above), from
   1 to the merchant's zoom_scale as the image passes through the screen. Only where the browser has
   scroll timelines AND the shopper has not asked for less motion; everyone else sees it still. */
@keyframes sec-iwt-zoom {
  from {
    transform: scale(1);
  }

  to {
    transform: scale(calc(var(--iwt-zoom, 120) / 100));
  }
}

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .sec-iwt--zoom .sec-iwt__media > img {
      animation: sec-iwt-zoom linear both;
      animation-timeline: view();
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  .sec-iwt--zoom .sec-iwt__media > img {
    animation: none;
    transform: none;
  }
}
/* parity_snifl_home — image_with_text options, behind classes the template prints only when set.
   Tablets (750-1199px, side by side): their own gap, space beside the text, space above and below the
   text, and an image as tall as the text or a set height. */
@media (min-width: 750px) and (max-width: 1199px) {
  .sec-iwt--t.sec-iwt--stack-phone .sec-iwt__grid {
    grid-template-columns: calc((100% - var(--iwt-gap-t, var(--iwt-gap, 48px))) * var(--iwt-w, 50) / 100) minmax(0, 1fr);
    column-gap: var(--iwt-gap-t, var(--iwt-gap, 48px));
  }

  .sec-iwt--t.sec-iwt--stack-phone.sec-iwt--image-right .sec-iwt__grid {
    grid-template-columns: minmax(0, 1fr) calc((100% - var(--iwt-gap-t, var(--iwt-gap, 48px))) * var(--iwt-w, 50) / 100);
  }

  .sec-iwt--t.sec-iwt--stack-phone.sec-iwt--full.sec-iwt--image-left .sec-iwt__grid { padding-inline-end: var(--iwt-gutter-t, var(--iwt-gutter, 20px)); }
  .sec-iwt--t.sec-iwt--stack-phone.sec-iwt--full.sec-iwt--image-right .sec-iwt__grid { padding-inline-start: var(--iwt-gutter-t, var(--iwt-gutter, 20px)); }
  .sec-iwt--t.sec-iwt--stack-phone .sec-iwt__text-col { padding-block: var(--iwt-text-py-t, var(--iwt-text-py, 0px)); }

  .sec-iwt--th-fill.sec-iwt--stack-phone .sec-iwt__media {
    flex: 1 1 0;
    min-height: 0;
    aspect-ratio: auto;
    height: auto;
  }

  .sec-iwt--th-custom.sec-iwt--stack-phone .sec-iwt__media {
    aspect-ratio: auto;
    height: var(--iwt-hpx-t, var(--iwt-hpx, 480px));
  }

  /* A square as tall as the text, centred in its column; a column narrower than the square crops it. */
  .sec-iwt--th-fill.sec-iwt--stack-phone .sec-iwt__media > img,
  .sec-iwt--th-fill.sec-iwt--stack-phone .sec-iwt__media > .sec-placeholder {
    position: absolute;
    inset: 0 auto 0 50%;
    width: auto;
    height: 100%;
    aspect-ratio: 1 / 1;
    translate: -50% 0;
  }

  .sec-iwt--th-custom.sec-iwt--stack-phone .sec-iwt__media > img,
  .sec-iwt--th-custom.sec-iwt--stack-phone .sec-iwt__media > .sec-placeholder {
    position: absolute;
    height: 100%;
  }
}

/* "Space below the text on phones". */
@media (max-width: 749px) {
  .sec-iwt--m-pb .sec-iwt__text-col { padding-bottom: var(--iwt-m-pb, 0px); }
  /* "Space between blocks on phones" (--iwt-m-cgap, printed only when set). */
  .sec-iwt__content { gap: var(--iwt-m-cgap, var(--iwt-content-gap, 1rem)); }
}

/* ...and on tablets while stacked, like "Space above the text on phones" (owner, 2026-10-23: Snifl's About
   text touched the next section at 810px). */
@media (max-width: 989px) {
  .sec-iwt--m-pb.sec-iwt--stack-tablet .sec-iwt__text-col { padding-bottom: var(--iwt-m-pb, 0px); }
}

/* Eyebrow "14px, 12px on tablets"; the item heading's weight; the heading's size from 990 to 1199px. */
.sec-iwt .sec-caption--steady {
  font-size: 14px;
  line-height: 1.2;
}

@media (min-width: 750px) and (max-width: 1199px) {
  .sec-iwt .sec-caption--steady { font-size: 12px; }
}

.sec-iwt .sec-iwt__item-heading--w-regular { font-weight: 400; }
.sec-iwt .sec-iwt__item-heading--w-semibold { font-weight: 600; }
.sec-iwt .sec-iwt__item-heading--w-bold { font-weight: 700; }

@media (min-width: 990px) and (max-width: 1199px) {
  .sec-iwt .sec-iwt__heading--t-size { font-size: var(--iwt-h-size-t); }
}

/* The Email sign-up block (2026-10-23): the button is a <details> summary drawn as the theme's solid button;
   once open it gives way to the email box and its button on one row (wrapping on a narrow phone). The box
   follows the colour scheme (its line is the text colour at 25%) and the theme's Corner radius. */
.sec-iwt__signup { width: 100%; }
.sec-iwt__signup-open { display: inline-block; list-style: none; }
.sec-iwt__signup-open::-webkit-details-marker { display: none; }
.sec-iwt__signup-open::marker { content: ""; }
.sec-iwt__signup-toggle[open] > .sec-iwt__signup-open { display: none; }
.sec-iwt__signup-form { display: grid; gap: 0.5rem; max-width: 34rem; }
.sec-iwt--align-center .sec-iwt__signup-form { margin-inline: auto; }
.sec-iwt--align-right .sec-iwt__signup-form { margin-left: auto; }
.sec-iwt__signup-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.sec-iwt__signup-field { flex: 1 1 12rem; min-width: 0; }
.sec-iwt__signup-field input {
  box-sizing: border-box;
  width: 100%;
  min-height: 2.875rem;
  margin: 0;
  padding: 0.625rem 0.875rem;
  border: 1px solid color-mix(in srgb, var(--text, #121212) 25%, transparent);
  border-radius: var(--sec-radius, 0);
  background-color: var(--bg, #fff);
  color: inherit;
  font: inherit;
  font-size: 0.9375rem;
}
.sec-iwt__signup-field input:focus { outline: none; border-color: var(--text, currentColor); }
.sec-iwt__signup-submit { flex: 0 0 auto; }
.sec-iwt__signup-note { margin: 0; font-size: 0.8125rem; opacity: 0.75; }
.sec-iwt__signup-error { margin: 0; color: #b3261e; font-size: 0.875rem; }
.sec-iwt__signup-form[hidden],
.sec-iwt__signup-error[hidden],
.sec-iwt__signup-done[hidden] { display: none; }
.sec-iwt__signup-done { margin: 0; font-size: 0.9375rem; }
.sec-iwt__signup-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 749px) {
  .sec-iwt__signup-field, .sec-iwt__signup-submit { flex: 1 1 100%; }
}
/* --- end image_with_text (10-15-C §3) --- */

/* --- contact_form (10-15-C §3) ------------------------------------------------------------
   N4. A heading, a line of text and the form (theme/sections/contact_form.liquid). The fields follow
   the section's colour scheme (the line is the text colour at 25%) and the theme's Corner radius
   (--sec-radius); the button is the theme's .sec-button, so it follows Button shape. The phone box is
   the storefront's shared one (.cko-phone, checkout.css): checkout.js turns its calling-code select
   into the searchable list, and the rules below only make that pair look like the fields beside it.
   Every default is square corners and the page's own colours, like the rest of the library. */
.sec-contact {
  --sec-contact-line: color-mix(in srgb, var(--text, #121212) 25%, transparent);
  --sec-contact-err: #b3261e;
  /* The searchable list's palette (account.css --acct-*), which only the account and checkout roots
     declare: the list opens on white, so its words stay dark whatever the scheme. */
  --acct-ink: #0f0c0b;
  --acct-muted: #595550;
  --acct-line: #dcdad8;
  --acct-soft: #f8f8f7;
  display: grid;
  gap: 1.75rem;
  width: 100%;
  max-width: 40rem;
  margin-inline: auto;
}

.sec-contact--left {
  margin-inline: 0;
}

.sec-contact--center .sec-contact__header {
  text-align: center;
}

.sec-contact__header {
  display: grid;
  gap: 0.75rem;
}

.sec-contact__form {
  display: grid;
  gap: 1.25rem;
}

.sec-contact__form[hidden],
.sec-contact__success[hidden],
.sec-contact__error[hidden] {
  display: none;
}

.sec-contact__fields {
  display: grid;
  gap: 1rem;
}

.sec-contact__field {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  min-width: 0;
}

.sec-contact__label {
  font-size: 0.875rem;
  line-height: 1.4;
}

.sec-contact__optional {
  opacity: 0.7;
}

.sec-contact__field input,
.sec-contact__field textarea,
.sec-contact .cko-phone__cc {
  /* 10-15-C fix3: the padding and the line inside the width, or every box is 30px wider than the
     form (the theme sets no box-sizing of its own). */
  box-sizing: border-box;
  width: 100%;
  min-height: 2.875rem;
  margin: 0;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--sec-contact-line);
  border-radius: var(--sec-radius, 0);
  background-color: transparent;
  color: inherit;
  font: inherit;
  font-size: 0.9375rem;
  line-height: 1.4;
}

.sec-contact__field textarea {
  min-height: 7.5rem;
  resize: vertical;
}

.sec-contact__field input:focus,
.sec-contact__field textarea:focus,
.sec-contact .cko-phone__cc:focus {
  outline: none;
  border-color: var(--text, currentColor);
}

.sec-contact [aria-invalid="true"] {
  border-color: var(--sec-contact-err);
}

/* The shared phone pair: a small gap instead of checkout's shared border, so each box keeps its own
   corners when Corner radius is on. */
.sec-contact .cko-phone__row {
  gap: 0.5rem;
}

.sec-contact .cko-phone__cc,
.sec-contact .cselect--dial {
  margin-right: 0;
}

.sec-contact .cselect__trigger {
  border-color: var(--sec-contact-line);
  border-radius: var(--sec-radius, 0);
  background-color: transparent;
  color: inherit;
}

.sec-contact .cselect.is-open > .cselect__trigger,
.sec-contact .cselect:focus-within > .cselect__trigger {
  border-color: var(--text, currentColor);
}

/* The trap field: off-screen, never display:none (some bots skip hidden inputs). */
.sec-contact__trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* 10-15-C fix4 — the hCaptcha box is a fixed 302px iframe, wider than a 320px phone's form, so it
   pushed the page 2px sideways. Its wrapper never grows past the form (min-width 0 lets the grid
   track stay the form's width) and clips what overhangs, and below 360px the box itself is drawn
   smaller so none of it is cut (scaled from its left edge; the scaled box keeps its layout height,
   leaving a little room under it). Only a form with spam protection on has this element. */
.sec-contact__captcha {
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
}

@media screen and (max-width: 359px) {
  .sec-contact__captcha iframe {
    transform: scale(0.85);
    transform-origin: 0 0;
  }
}

.sec-contact__error {
  margin: 0;
  color: var(--sec-contact-err);
  font-size: 0.875rem;
}

.sec-contact__submit {
  justify-self: start;
}

.sec-contact--center .sec-contact__submit {
  justify-self: stretch;
}

.sec-contact__submit:disabled {
  opacity: 0.6;
  cursor: progress;
}

.sec-contact__success {
  margin: 0;
  padding: 1rem 1.25rem;
  border: 1px solid var(--sec-contact-line);
  border-radius: var(--sec-radius, 0);
}

.sec-contact__success:focus {
  outline: none;
}

/* The no-JavaScript landing page (templates/contact_notice.liquid). */
.sec-contact-notice {
  max-width: 40rem;
  margin: 3rem auto;
  display: grid;
  gap: 1rem;
}
/* --- end contact_form (10-15-C §3) --- */

/* ===================================================================================== *
 * 10-16 G3 (BUILD_BRIEF_2026-10-16 §6, §7): section heading alignment, Multicolumn's button
 * beside the heading, and Feature row as an inline band. Every rule hangs off a class the
 * templates print ONLY for a non-default choice, so with the defaults none of this matches.
 * ===================================================================================== */

/* "Heading alignment: Centred with the link under it" (Featured collection, Collection list,
   Collage, Testimonials, Multicolumn with its button beside the heading). */
.sec-title-row--center {
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 1rem;
  text-align: center;
}

/* Multicolumn's heading centred on its own (button under the columns). */
.sec-title--center {
  text-align: center;
}

/* Multicolumn's button in the title row: the row already spaces the heading from the columns. */
.sec-title-row > .sec-multicolumn__title {
  margin-bottom: 0;
}

.sec-title-row > .sec-button {
  flex: none;
}

/* Feature row, "Style: Inline band". Like .sec-iwt, the strip reaches the window edges and repaints
   the scheme's background and the wrapper's padding itself (the wrapper spans only the page column).
   With the base scheme it falls back to the theme's surface grey so a band always reads as one; a
   padding left at 0 gives 24px above and below. */
.feature-row--band {
  margin-inline: calc(-1 * var(--sec-bleed));
  margin-block: calc(-1 * var(--section-pt, 0px)) calc(-1 * var(--section-pb, 0px));
  padding: var(--section-pt, 1.5rem) var(--sec-bleed) var(--section-pb, 1.5rem);
  background: var(--section-background, var(--sec-surface));
}

.feature-row__heading {
  margin: 0 0 1.5rem;
  text-align: center;
}

.feature-row__items {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.5rem clamp(1.5rem, 16vw - 7rem, 8rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.feature-row__item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  min-width: 0;
}

.feature-row--band .feature-row__icon {
  flex: none;
  align-items: center;
  height: 1.5rem;
}

.feature-row--band .feature-row__icon .sec-accordion__icon {
  width: 1.5rem;
  height: 1.5rem;
}

.feature-row__emoji {
  font-size: 1.375rem;
}

.feature-row__body {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

.feature-row__title {
  font-size: 1.125rem;
  font-weight: 500;
  line-height: 1.4;
}

.feature-row__text {
  margin: 0;
  font-size: 1rem;
  line-height: 1.375;
}

/* parity_snifl_home — a feature's own "Icon image", sized like the drawn icons. */
.feature-row__icon--image img {
  display: block;
  width: 1.5rem;
  height: 1.5rem;
  object-fit: contain;
}

/* "Band layout: Even columns" (SITE_MEASUREMENTS.md §3.1 row 8): computers — each feature 296px wide
   (a 32px icon, 16px, then the words), 64px apart, centred; tablets (750-1199px) — equal columns 16px
   apart, each centred with a 24px icon over the words, the text line 14px; phones — one under the
   other, 48px apart. */
.feature-row--even .feature-row__items {
  flex-wrap: nowrap;
  gap: 4rem;
}

.feature-row--even .feature-row__item {
  flex: 0 1 18.5rem;
  gap: 1rem;
}

.feature-row--even .feature-row__icon,
.feature-row--even .feature-row__icon .sec-accordion__icon,
.feature-row--even .feature-row__icon--image img {
  width: 2rem;
  height: 2rem;
}

.feature-row--even .feature-row__body {
  gap: 0.375rem;
}

.feature-row--even .feature-row__title {
  line-height: 1.4;
}

.feature-row--even .feature-row__text {
  line-height: 1.4;
}

@media (max-width: 1199px) {
  .feature-row--even .feature-row__items {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 1rem;
  }

  .feature-row--even .feature-row__item {
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
  }

  .feature-row--even .feature-row__icon,
  .feature-row--even .feature-row__icon .sec-accordion__icon,
  .feature-row--even .feature-row__icon--image img {
    width: 1.5rem;
    height: 1.5rem;
  }

  .feature-row--even .feature-row__body {
    align-self: stretch;
  }

  .feature-row--even .feature-row__text {
    font-size: 0.875rem;
  }
}

@media (max-width: 809px) {
  .feature-row--even .feature-row__items {
    grid-auto-flow: row;
    gap: 3rem;
  }
}

/* Phones: one feature under the other, the icon on top, everything centred. */
@media (max-width: 749px) {
  .feature-row__items {
    flex-direction: column;
    align-items: center;
    gap: 2.5rem;
  }

  .feature-row__item {
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
  }
}
/* --- end 10-16 G3 --- */

/* --- 10-16 pages parity: main_article Style "Editorial" ----------------------------------------
   Printed only for that style (sections/main_article.liquid). A centred column (--post-w), the title
   over a grey date and author, the cover photo with 24px corners, the excerpt as an 18px lead, and the
   tags under the post. Sizes from the client site's post (SITE_MEASUREMENTS.md §3.11). */
.post--editorial {
  max-width: var(--post-w, 1200px);
  margin: 0 auto;
}

.post--editorial .post__title {
  margin: 0;
  font-size: 34px;
  line-height: 1.2;
  font-weight: 500;
}

.post--editorial .post__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 13px;
  margin: 16px 0 0;
  font-size: var(--text-size, 16px);
  line-height: 1.4;
  color: #605f5f;
}

.post--editorial .post__image {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1200 / 760;
  margin-top: 32px;
  border-radius: 24px;
  object-fit: cover;
}

.post--editorial .post__lead {
  margin: 32px 0 0;
  font-size: 18px;
  line-height: 1.4;
  font-weight: 500;
}

.post--editorial .post__body {
  margin-top: 21px;
  font-size: var(--text-size, 16px);
  line-height: var(--text-line-height, 1.4);
}

.post--editorial .post__body p {
  margin: 0 0 20px;
}

.post--editorial .post__tags {
  margin: 44px 0 0;
  padding: 12px 0;
  border-block: 1px solid rgba(0, 0, 0, 0.1);
  color: #605f5f;
}

.post--editorial .post__meta > span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.post--editorial .post__tags strong {
  margin-right: 10px;
  font-size: 18px;
  font-weight: 500;
  color: #000;
}

@media (max-width: 1199px) {
  .post--editorial .post__title {
    font-size: 28px;
  }
}

@media (max-width: 749px) {
  .post--editorial .post__image {
    aspect-ratio: 359 / 380;
  }
}

/* === BUILD_BRIEF_2026-10-19 §1 + §2: SHARED SIDEWAYS SLIDER ===============================
   Markup: snippets/slider-progress.liquid. Behaviour: assets/slider.js. Only elements carrying the
   kslider classes match, and no section prints them unless its slider setting is on, so nothing
   here touches a page that does not use it.
     .kslider--phone   featured_collection / product_grid "Phone layout: Slider": below 750px the grid
                       becomes a row of cards about 82% wide; from 750px it is the grid, unchanged.
     .kslider--always  shop_reviews "Layout: Slider": a row everywhere, --kslider-per-view cards on
                       computers (from 990px), 2 on tablets, one ~82% card on phones.
   ========================================================================================== */
.kslider {
  --kslider-peek: 82%;
  --kslider-gap: 1.25rem;
}

.kslider__track {
  scrollbar-width: none;
}

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

/* 2026-10-20: the lines sit centred under the cards (they were packed to the left). */
.kslider__progress {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 1.25rem;
}

/* 2026-10-20: mouse drag (assets/slider.js). .is-draggable is set only by the script and only while the
   row really overflows; .is-dragging only while the mouse is dragging it, when snapping is switched off
   so the row can follow the pointer (the script snaps it to a card on release). */
@media (hover: hover) and (pointer: fine) {
  .kslider.is-draggable .kslider__track {
    cursor: grab;
  }
}

.kslider.is-dragging .kslider__track {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
  -webkit-user-select: none;
}

.kslider.is-dragging .kslider__track a,
.kslider.is-dragging .kslider__track button,
.kslider.is-dragging .kslider__track img {
  pointer-events: none;
}

.kslider__progress[hidden],
.kslider__bar[hidden] {
  display: none;
}

.kslider__bar {
  position: relative;
  flex: 1 1 0;
  max-width: 64px;
  height: 2px;
  overflow: hidden;
  border-radius: 2px;
}

.kslider__bar::before {
  content: "";
  position: absolute;
  inset: 0;
  background: currentColor;
  opacity: 0.2;
}

.kslider__fill {
  position: absolute;
  inset: 0;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
}

.kslider__bar.is-done .kslider__fill,
.kslider__bar.is-current .kslider__fill {
  transform: scaleX(1);
}

.kslider.is-playing .kslider__bar.is-current .kslider__fill {
  animation: kslider-fill var(--kslider-interval, 3s) linear forwards;
}

.kslider.is-playing.is-held .kslider__bar.is-current .kslider__fill {
  animation-play-state: paused;
}

@keyframes kslider-fill {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

.kslider--always .kslider__track {
  display: flex;
  gap: var(--kslider-gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
}

.kslider--always .kslider__track > * {
  flex: 0 0 var(--kslider-peek);
  min-width: 0;
  scroll-snap-align: start;
}

@media (min-width: 750px) {
  .kslider--always .kslider__track > * {
    flex-basis: calc((100% - var(--kslider-gap)) / 2);
  }

  .kslider--phone .kslider__progress {
    display: none;
  }
}

@media (min-width: 990px) {
  .kslider--always .kslider__track > * {
    flex-basis: calc((100% - (var(--kslider-per-view, 3) - 1) * var(--kslider-gap)) / var(--kslider-per-view, 3));
  }
}

@media (max-width: 749px) {
  .kslider--phone .kslider__track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
  }

  .kslider--phone .kslider__track > * {
    flex: 0 0 var(--kslider-peek);
    min-width: 0;
    scroll-snap-align: start;
  }
}

/* === BUILD_BRIEF_2026-10-19 §2: THE "REVIEWS" SECTION (shop_reviews) ======================
   Cards of stars, words, a name and (for a real review) the product it is for. Grid uses the
   shared .sec-grid columns; Slider is the shared slider above. The card takes the section's colour
   scheme through currentColor, so it reads on any scheme. */
.sec-revs__summary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 1.5rem;
}

.sec-title-row--center + .sec-revs__summary {
  justify-content: center;
}

.sec-revs__stars {
  color: var(--reviews-star, #f5a623);
  letter-spacing: 0.1em;
}

.sec-revs__average {
  font-weight: 600;
}

.sec-revs__count {
  opacity: 0.7;
}

.sec-revs__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.sec-revs__card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1.5rem;
  border-radius: 12px;
  isolation: isolate;
}

/* A soft tint of the scheme's own text colour behind each card. */
.sec-revs__card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: currentColor;
  opacity: 0.05;
}

.sec-revs__card .sec-revs__stars {
  margin: 0;
  font-size: 1.125rem;
}

.sec-revs__quote {
  flex: 1 1 auto;
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
}

.sec-revs__quote p {
  margin: 0;
}

.sec-revs__author {
  margin: 0;
  font-weight: 600;
}

.sec-revs__product {
  margin: 0;
  font-size: 0.875rem;
  opacity: 0.75;
}

.sec-revs__product a {
  color: inherit;
}

.sec-revs__note {
  margin: 0;
  padding: 1rem;
  border: 1px dashed currentColor;
  border-radius: 8px;
  opacity: 0.7;
}

/* === 2026-10-20: SECTION HEADING COLOUR AND WEIGHT ==========================================
   A section title's own "Heading colour" and "Heading weight" (snippets/sec-heading-look.liquid), on
   featured_collection, shop_reviews, feature_row, collection_list, multicolumn, collage and
   testimonials. The classes print only when a section picks something other than the default, so
   nothing here touches a page that does not. "Primary colour" is the theme palette's Primary / links
   colour, printed on the heading as --sec-h-color; without one it falls back to the colour scheme's
   --primary. These come after .sec-heading (same specificity), so they win over its weight token. */
.sec-heading-look--primary {
  color: var(--sec-h-color, var(--primary, currentColor));
}

.sec-heading-look--custom {
  color: var(--sec-h-color, inherit);
}

.sec-heading-look--medium {
  font-weight: 500;
}

.sec-heading-look--bold {
  font-weight: 700;
}