/** Shopify CDN: Minification failed

Line 135:57 Unexpected "12n"

**/
/* ============================================================================
   haiku-gallery — the collection page as an infinite scroll gallery

   Ported from the Codrops "Infinite Scroll Gallery with Page Transitions"
   demo (ISC). Layout, sizing and timings are the reference's; the changes are
   noted where they occur.

   THE PROGRESSIVE-ENHANCEMENT CONTRACT, which every rule below respects:

     no `.hg-live` on <html>  →  a plain vertical list of linked products,
                                 normal document scrolling, no JS required
     `.hg-live`               →  the gallery takes the page over

   haiku-gallery.js adds that class only after GSAP, Flip, Observer and
   SplitText are all present, reduced-motion is not requested, we are not in
   the theme editor, and the images have settled. Anything short of that and
   the shopper still gets a working, scrollable, clickable collection.

   Contents
   1. Stage + progressive enhancement
   2. The gallery — layout, the sizing rhythm
   3. The preview overlay (Flip target)
   4. Modes, motion, small screens
   ========================================================================== */


/* ----------------------------------------------------------------------------
   1. Stage + progressive enhancement
---------------------------------------------------------------------------- */

/* The gallery drives itself, so the document must not also scroll — but ONLY
   once we have taken over. Until then the page behaves normally. */
html.hg-live,
html.hg-live body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: none;
  scrollbar-width: none;
}

html.hg-live body::-webkit-scrollbar {
  display: none;
}

/* The theme's header sits over the gallery; the footer is unreachable once
   scrolling is hijacked, so it is hidden rather than left dangling. */
html.hg-live .main-footer,
html.hg-live #shopify-section-footer,
html.hg-live .footer-group {
  display: none;
}

.hg {
  position: relative;
  width: 100%;
}

/* Pre-takeover: a legible stack of products, centred, nothing exotic. */
.hg:not(.is-live) .gallery {
  gap: clamp(32px, 6vh, 72px);
  padding-top: clamp(24px, 6vh, 64px);
  padding-bottom: clamp(48px, 10vh, 120px);
}

.hg:not(.is-live) .gallery__slide {
  /* No horizontal scatter without the loop to balance it. */
  transform: none;
}

/* The overlay is inert until the gallery is live. */
.hg:not(.is-live) .content {
  display: none !important;
}

.hg.is-live {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}


/* ----------------------------------------------------------------------------
   2. The gallery
---------------------------------------------------------------------------- */

.gallery {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12vh;
  width: 100%;
  padding-top: 14vh;
  margin: 0;
  list-style: none;
}

.gallery__slide {
  flex-shrink: 0;
  transform: translateX(var(--stagger, 0vw));
  cursor: pointer;
  outline: none;
  padding: 0;
  margin: 0;
}

.gallery__slide:focus-visible .gallery__img-wrapper {
  outline: 2px solid var(--color-accent);
  outline-offset: 6px;
}

/* The slide's anchor is what makes this work without JS. Once the gallery is
   live the click is intercepted and the anchor is purely semantic. */
.gallery__link {
  display: block;
  color: inherit;
  text-decoration: none;
}

/* THE SIZING RHYTHM.

   ⚠️ nth-of-type, NOT nth-child. .gallery can hold non-figure children, so
   nth-child(12n+1) did not land on the first slide: it measured --img-w and
   --stagger as empty strings while slides 2-4 were correct. nth-of-type counts
   only the <figure> slides. Same trap that made :first-child match nothing in
   the products row.

   ⚠️ AND NO NESTED COMMENTS. CSS has none. An explanatory /* ... */ opened
   inside this block ended it early, and everything after the first close was
   parsed as CSS — the parser then swallowed the whole 12n+1 rule looking for a
   declaration block. That is what left slide one unsized. If a note is needed
   here, it goes on its own line outside the block.

   The reference hardcodes --stagger and --img-w for exactly 17 slides. A
   collection has an arbitrary number of products, so the pattern here CYCLES
   every 12, and past the twelfth product the rhythm repeats instead of
   collapsing into a plain centred column.

   Widths start at 470px because that is what the longest caption needs to sit
   on ONE line: title 393 + price 46 + gap 18 = 457, measured in the browser.
   Below that the label wraps and the tiles go ragged. Staggers are pulled in
   to match — a 640px tile at +-36vw runs off a 1440 viewport, so |stagger|
   stays under (720 - width/2).

   The alternation of negative and positive --stagger is what keeps the eye
   moving side to side rather than tracking straight down. */

/* BASE, before the cycle. Slot 1 was measuring --img-w as an empty string on
   the live page even though the rule is present in the served stylesheet and
   the slide is the first <figure> in .gallery — cause not established. A base
   declaration makes that unfalsifiable: every slide has a usable width and
   stagger, and the nth-of-type rules below simply override it. No slide can
   be unsized regardless of what the cycle does or does not match. */
.gallery__slide {
  --stagger: -26vw;
  --img-w: 480px;
}

.gallery__slide:nth-of-type(12n + 1)  { --stagger: -26vw; --img-w: 480px; }
.gallery__slide:nth-of-type(12n + 2)  { --stagger: 18vw; --img-w: 540px; }
.gallery__slide:nth-of-type(12n + 3)  { --stagger: -24vw; --img-w: 470px; }
.gallery__slide:nth-of-type(12n + 4)  { --stagger: 22vw; --img-w: 620px; }
.gallery__slide:nth-of-type(12n + 5)  { --stagger: -28vw; --img-w: 490px; }
.gallery__slide:nth-of-type(12n + 6)  { --stagger: 24vw; --img-w: 500px; }
.gallery__slide:nth-of-type(12n + 7)  { --stagger: -26vw; --img-w: 480px; }
.gallery__slide:nth-of-type(12n + 8)  { --stagger: 16vw; --img-w: 640px; }
.gallery__slide:nth-of-type(12n + 9)  { --stagger: -22vw; --img-w: 470px; }
.gallery__slide:nth-of-type(12n + 10) { --stagger: 20vw; --img-w: 510px; }
.gallery__slide:nth-of-type(12n + 11) { --stagger: -26vw; --img-w: 580px; }
.gallery__slide:nth-of-type(12n + 12) { --stagger: 24vw; --img-w: 520px; }

.gallery__img-wrapper {
  position: relative;
  margin: 0;
  width: var(--img-w, 200px);
  height: auto;
  aspect-ratio: 0.8;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
  background: var(--color-background-secondary);
}

.gallery__img-wrapper img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Overscaled at rest so the Flip morph can settle it to 1 rather than
     revealing an edge. */
  transform: scale(1.2);
}

/* Without the gallery there is no morph to settle into, so sit at 1:1. */
.hg:not(.is-live) .gallery__img-wrapper img {
  transform: none;
}

.gallery__caption {
  display: block;
  margin-top: 0.5rem;
  color: rgba(var(--color-text-rgb), 0.66);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.gallery__price {
  margin-left: 0.75em;
  opacity: 0.7;
}

.gallery__sold {
  margin-left: 0.75em;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 10px;
  opacity: 0.6;
}


/* ----------------------------------------------------------------------------
   3. The preview overlay

   `.content__preview-img` is the Flip target: the thumbnail's bounds are
   captured, then this element is animated from them. It is full-viewport-height
   at the same 0.8 aspect, so the product photograph is finally seen whole —
   which is the point of the interaction.
---------------------------------------------------------------------------- */

/* Deliberately NO background. The opening timeline fades the other slides out
   over 0.5s while the preview morphs — an opaque layer here would snap them
   away on frame one and there would be nothing to fade. The page ground shows
   through, which is what the reference relies on too. */
/* ⚠️ SCOPED TO .hg — `.content` IS NOT OURS ALONE.

   Unscoped, this rule reached `snippets/cart-form.liquid:39`, where the vendor
   theme wraps each cart line's title, variant and price in a plain
   `<div class="content">`. Every cart item's text was therefore
   `display: none; position: fixed` — measured on /cart: the title span
   0x0 inside a `.content` that was 0x0 and `display: none`, while the
   photograph beside it rendered normally. Reported as "item shows photo, but
   no title".

   Both preview panels sit inside `.hg` — verified in a browser on
   /collections/all (`hg is-live`) and on a product page
   (`hg is-live hlb-scope`) — so scoping costs nothing and the panels behave
   exactly as before. haiku-preview.js still reads `display` on `.content` as
   its open/closed state; that contract is untouched. */
.hg .content {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
}

.content__preview-img {
  position: fixed;
  margin: 0;
  top: 0;
  left: 0;
  height: 100vh;
  height: 100dvh;
  aspect-ratio: 0.8;
  overflow: hidden;
}

.content__preview-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.2);
}

.content__group-list {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  /* Clears the preview column: 80vh is the preview's width at aspect 0.8. */
  padding-inline: calc(80vh + 1.5vw) var(--hg-pad, 1.5rem);
  padding-block: var(--hg-pad, 1.5rem);
}

.content__back {
  font: inherit;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  align-self: flex-start;
  border: none;
  background: none;
  color: var(--color-text);
  cursor: pointer;
  padding: 0;
  line-height: inherit;
}

.content__back:hover,
.content__back:focus-visible {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.content__group {
  display: none;
}

.content__group.active {
  display: block;
}

.content__title {
  font-family: var(--font-stack-headings);
  font-weight: 400;
  font-size: clamp(2.5rem, 10vw, 6rem);
  line-height: 1;
  margin-bottom: 2rem;
  margin-top: 40vh;
  color: var(--color-text);
}

.content__title:focus {
  outline: none;
}

.content__price {
  font-size: clamp(1rem, 2vw, 1.25rem);
  margin-bottom: 1.5rem;
  color: var(--color-text);
}

.content__description {
  margin-right: 10vw;
  max-width: 50ch;
  font-size: clamp(1rem, 2.5vw, 1.5rem);
  color: rgba(var(--color-text-rgb), 0.66);
}

/* The preview is a staging post; this is the way to the actual product. */
.content__cta {
  display: inline-block;
  margin-top: 2.5rem;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 4px;
}

.content__cta:hover,
.content__cta:focus-visible {
  color: var(--color-accent);
}

/* SplitText leaves these behind; they must not intercept the overlay. */
.content .char {
  will-change: opacity;
}


/* ----------------------------------------------------------------------------
   4. Modes, motion, small screens
---------------------------------------------------------------------------- */

/* Ink and grounds come from the theme's tokens, so both appearance modes are
   correct with no remapping — same contract as haiku-icons. */

@media (prefers-reduced-motion: reduce) {
  /* The script bails entirely, so this only has to make the plain list good. */
  .gallery__img-wrapper img {
    transform: none;
  }
}

/* Below the tablet breakpoint the horizontal scatter costs more than it gives:
   at 28vw a 450px slide is mostly off-screen. Narrow the stagger and let the
   widths follow the viewport. */
@media screen and (max-width: 1023px) {
  .gallery {
    gap: 8vh;
    padding-top: 10vh;
  }

  .gallery__slide {
    --stagger: 0vw !important;
    --img-w: min(72vw, 420px) !important;
  }

  .content__group-list {
    /* The preview no longer sits beside the text; it sits above it. */
    padding-inline: var(--hg-pad, 1.5rem);
    padding-top: calc(60vh + 2rem);
  }

  .content__preview-img {
    height: 55vh;
    width: 100%;
    aspect-ratio: auto;
  }

  .content__title {
    margin-top: 0;
  }

  .content__description {
    margin-right: 0;
  }
}

/* ============================================================================
   Mobile collection — a plain scrolling single column

   Paired with the `simple` branch in haiku-gallery.js: below 900px no timeline
   is built, so nothing transforms the slides and they can simply sit in flow.
   This undoes the fixed/absolute layout the timeline needs and stacks them.

   `html.hg-simple` is the marker for this mode. `hg-live` — the class that
   takes scrolling away from the document — is deliberately NOT added on
   mobile, so the browser scrolls the page normally: momentum, rubber-banding
   and the address bar all behave as they should.
   ========================================================================== */

@media screen and (max-width: 900px) {
  html.hg-simple,
  html.hg-simple body {
    overflow-y: auto !important;
    height: auto !important;
    position: static !important;
  }

  .hg-simple .gallery,
  .hg-simple .hg .gallery {
    position: static !important;
    display: block !important;
    height: auto !important;
    overflow: visible !important;
    padding: 2rem 1.2rem 6rem;
  }

  /* One column, in flow. Every slide-level variable the timeline used —
     --stagger, --img-w, the per-slide speeds — is irrelevant here. */
  .hg-simple .gallery__slide {
    position: static !important;
    display: block !important;
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    margin: 0 0 3.2rem !important;
    transform: none !important;
    opacity: 1 !important;
    visibility: visible !important;
    --stagger: 0 !important;
    --img-w: 100% !important;
  }

  .hg-simple .gallery__slide:last-child { margin-bottom: 0 !important; }

  .hg-simple .gallery__link,
  .hg-simple .gallery__figure {
    display: block;
    width: 100%;
  }

  .hg-simple .gallery__img {
    position: relative !important;
    width: 100% !important;
    height: auto !important;
    max-width: 100% !important;
    /* `transform: none !important` was here to undo the timeline's transforms.
       In simple mode the timeline never runs, and that !important was killing
       the lens effect's scale on the image — the frame shrank while the image
       stayed put, so nothing appeared to magnify. */
    object-fit: cover;
  }

  /* The hover-reveal alt photograph has no gesture on a phone, and stacking it
     over the primary would double every image's height. */
  .hg-simple .gallery__img--alt { display: none !important; }

  .hg-simple .gallery__caption,
  .hg-simple .gallery__meta {
    position: static !important;
    width: 100% !important;
    max-width: 100% !important;
    margin-top: 0.7rem;
  }

  /* The caption's transform and opacity stay pinned — the desktop timeline
     drove them and does not run here.

     `.gallery__meta` is deliberately NOT in this list. haiku-lens.js animates
     it, and an !important in a stylesheet beats the inline style GSAP writes,
     so leaving it here would have made the caption animation silently do
     nothing — the identical trap that left the image half of the lens dead
     earlier in this file. Animating the parent still dims the caption, since
     opacity composites down. */
  .hg-simple .gallery__caption {
    transform: none !important;
    opacity: 1 !important;
  }

  /* The boot overlay belongs to the timeline's start-up, which never runs. */
  .hg-simple .hg-boot,
  .hg-simple [class*="boot"] { display: none !important; }
}

/* ============================================================================
   Mobile collection — smaller items, more air

   Full-bleed photographs stacked at 3.2rem apart read as a feed: each one
   fills the screen, so the eye never gets a boundary between them and the
   whole column feels relentless.

   Narrower and further apart gives each piece a margin to sit in, and the
   ground between them does the separating instead of an edge. 76% centred is
   still large enough to read the garment; 6.5rem between is roughly twice the
   caption's own height, which is what makes the gap read as deliberate rather
   than as a gap.
   ========================================================================== */

@media screen and (max-width: 900px) {
  .hg-simple .gallery,
  .hg-simple .hg .gallery {
    padding: 3rem 0 8rem !important;
  }

  .hg-simple .gallery__slide {
    width: 76% !important;
    max-width: 76% !important;
    margin: 0 auto 6.5rem !important;
  }

  .hg-simple .gallery__slide:last-child {
    margin-bottom: 0 !important;
  }

  /* The caption keeps the photograph's width so the two read as one object. */
  .hg-simple .gallery__caption,
  .hg-simple .gallery__meta {
    width: 100% !important;
    max-width: 100% !important;
    margin-top: 0.45rem;
  }
}

/* Narrower phones need a little more of the screen, or the photograph becomes
   a postage stamp. */
@media screen and (max-width: 480px) {
  .hg-simple .gallery__slide {
    width: 84% !important;
    max-width: 84% !important;
    margin-bottom: 5.5rem !important;
  }
}


/* ── buy now ──────────────────────────────────────────────────────────────
   The second way out of the preview: `take a close look` goes to the product
   page, this goes straight to checkout. Quieter than the CTA above it on
   purpose — the panel is a look, and the loud control should be the one that
   lets you look closer, not the one that takes your money.

   ⚠️ Rendered only when the variant is available. These are one-of-one
   pieces, so a buy-now on a sold piece would take someone to a checkout that
   cannot complete. */
.content__buy {
  /* Centred UNDER the CTA, not in the column. `.content__acts` wraps both and
     takes its width from the wider one (the CTA), so `margin-inline: auto`
     here centres this against that button rather than against the paragraph.

     ⚠️ Must be a block — `margin-inline: auto` does nothing to an inline box,
     which is why an earlier `inline-block` sat at the panel's left edge. */
  display: block;
  width: fit-content;
  margin-inline: auto;
  margin-top: 0.9rem;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text);
  opacity: 0.62;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 4px;
  transition: opacity 200ms linear, border-color 200ms linear;
}

.content__buy:hover,
.content__buy:focus-visible {
  opacity: 1;
  border-bottom-color: currentColor;
}

/* The two controls stack, so the CTA above must not sit on the same line. */
.content__cta {
  margin-bottom: 0;
}


/* The pair, as one box. Width comes from the wider child so the narrower one
   can centre against it. */
.content__acts {
  display: block;
  width: fit-content;
  max-width: 100%;
}

/* One or zero visible slides: no loop to run. The slide sits in flow, centred,
   without the scatter that only makes sense against neighbours. Set by
   refresh() in haiku-gallery.js. */
.hg.is-static .gallery__slide {
  transform: none !important;
}
.hg.is-static .gallery {
  min-height: 100vh;
  justify-content: center;
  padding-top: 0;
}

/* refresh()'s other half: moved here from the round-one drawer's stylesheet
   when the drawer was removed (2026-09-26). refresh() builds the loop over
   slides WITHOUT [data-hf="out"]; these rules are what make that exclusion,
   and the static mode below 2 slides, real on the page. Without them an
   excluded slide stays in flow and a lone slide can never be scrolled to.

   ⚠️ THE EXCLUSION RULE. `.hg-simple .gallery__slide` (mobile) states
   `display: block !important` at (0,2,0). This is (0,3,1) + !important so it
   wins in both modes. Hidden slides must be display:none, not opacity 0 —
   verticalLoop divides by measured height and 0 is NaN for the whole loop. */
html .hg .gallery__slide[data-hf="out"] { display: none !important; }

/* Static mode (≤1 visible slide): the loop is off and the one slide may be
   taller than the window. Give the document its scroll back, only then.
   Three things lock it in live mode and all three must relax:
   `html.hg-live, html.hg-live body` (height 100%, overflow hidden,
   touch-action none — (0,1,1)/(0,1,2)) and the gallery container
   `.hg.is-live` (100dvh, overflow hidden). Exceeded, not equalled: this file
   is emitted twice (head and tail copies), so order alone decides nothing.
   Known and accepted: the scrollbar stays hidden (`scrollbar-width: none` —
   zy's call), and the page can scroll ~64px past the slide because .hg
   starts below the header and .gallery keeps 100vh. */
html.hg-live.hg-static,
html.hg-live.hg-static body {
  height: auto;
  overflow-y: auto;
  touch-action: auto;
}
.hg.is-live.is-static {
  height: auto;
  min-height: 100dvh;
  overflow: visible;
}
