/** Shopify CDN: Minification failed

Line 210:58 Unexpected "}"

**/
/* Three categories, ONE view. The reference shows rackets, shoes and bags side by
   side as three cards — not three full screens you scroll through. Nothing here
   scrolls: the whole set is legible at a glance and every product in it is a link. */
#panels{position:relative;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(.6rem,1.4vw,1.4rem);width:100%;height:100svh;max-width:100%;
  padding:clamp(.6rem,1.4vw,1.4rem);overflow:hidden}
/* stretch, NOT center: the stage uses `container-type:size`, so its contents
   cannot size it. With a centred (content-sized) chain above, the stage asked
   its parent for a height, the parent asked the contents, and containment
   made that zero — every product collapsed to 0x0 and nothing was clickable.
   Stretching gives the chain a definite height to resolve against. */
.panels__panel{position:relative;isolation:isolate;display:grid;place-content:stretch;
  min-height:0;height:100%;padding:clamp(1rem,2.5vh,2.25rem) clamp(.75rem,1.6vw,1.75rem);
  color:var(--panel-ink,var(--ink));background:linear-gradient(180deg,var(--panel-from),var(--panel-to));
  border-radius:clamp(.9rem,1.8vw,1.6rem);overflow:hidden}
/* no z-index here: it would make this grid item a stacking context, which traps
   the products' mix-blend-mode:multiply against a transparent backdrop instead of
   the panel gradient — the white photo backgrounds would stay white. It already
   paints above the panel's own background without one. */
.panels__inner{display:grid;grid-template-rows:minmax(0,1fr) auto;align-content:stretch;gap:clamp(.8rem,2.4svh,1.8rem);width:100%;height:100%;max-height:100%;margin:auto;text-align:center}
/* two rows: the product stage, then the caption. The caption used to be
   absolutely positioned below the stage, which put it straight over the
   headline — invisible on desktop because it was hover-only, and plainly
   broken on touch where there is no hover. Giving it its own row means it
   cannot overlap anything, at any width. */
/* The stage takes the space the copy LEAVES; it must not demand a fixed
   height. With `height:clamp(...)` the grid compressed the row below the
   element's own height on a short screen, the element overflowed its row,
   and the copy slid up under it — which is what put the caption on top of
   the headline on a real phone. `min-height:0` lets it actually shrink. */
.panels__visual{position:relative;display:grid;grid-template-rows:minmax(0,1fr) auto;justify-items:center;align-items:center;min-width:0;min-height:0;height:100%}
.panels__product{display:block;width:min(82vw,31rem);height:min(46svh,31rem);object-fit:contain;mix-blend-mode:multiply;animation:panels-float 6.5s ease-in-out infinite;will-change:transform}
.panels__copy{align-self:end;max-width:100%;min-width:0}
.panels__title{margin:0 auto;max-width:14ch;font-family:var(--font-display);font-size:clamp(1.05rem,min(2.1vw,3.4svh),2.1rem);font-weight:800;line-height:.98;letter-spacing:-.03em;text-transform:uppercase;text-wrap:balance}
.panels__body{max-width:30ch;margin:clamp(.4rem,1.2svh,.9rem) auto 0;font-family:var(--font-body);font-size:clamp(.72rem,min(.95vw,1.5svh),.92rem);line-height:1.5}
.panels__meta{display:flex;justify-content:center;align-items:center;gap:.5rem .75rem;flex-wrap:wrap;margin-top:clamp(.6rem,1.6svh,1.1rem)}
.panels__cta{min-height:2.4rem;padding:.5rem 0;font-size:.66rem;border:0;border-bottom:2px solid currentColor;color:inherit;background:transparent;font-family:var(--font-display);font-size:.76rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:opacity .2s var(--ease),transform .2s var(--ease)}
.panels__cta:hover{opacity:.68;transform:translateY(-2px)}
.panels__price{display:inline-flex;align-items:baseline;gap:.55rem;font-family:var(--font-display);font-size:.82rem;font-weight:700}.panels__price-now.is-sale{color:var(--orange)}.panels__price-was{opacity:.58;font-family:var(--font-body);font-size:.72rem}
.panels__scroll{display:none;position:absolute;z-index:2;right:clamp(1.25rem,5vw,5rem);bottom:clamp(1.25rem,4svh,2.5rem);display:flex;align-items:center;gap:.55rem;font-family:var(--font-body);font-size:.68rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;opacity:.64}
.panels__scroll::after{content:"";width:1px;height:2.4rem;background:currentColor;transform-origin:top;animation:panels-scroll 1.8s var(--ease) infinite}
.panels__dots{display:none;position:sticky;z-index:5;top:50%;display:grid;justify-items:center;gap:.2rem;width:2.75rem;height:0;margin-left:auto;transform:translateY(-50%);pointer-events:none}
.panels__dot{position:relative;width:2.75rem;height:2.75rem;padding:0;border:0;background:transparent;cursor:pointer;pointer-events:auto}
.panels__dot::before{content:"";position:absolute;inset:50% auto auto 50%;width:.42rem;height:.42rem;border:1px solid currentColor;border-radius:50%;background:transparent;transform:translate(-50%,-50%);transition:background-color .25s var(--ease),transform .25s var(--ease)}
.panels__dot[aria-current="true"]::before{background:currentColor;transform:translate(-50%,-50%) scale(1.45)}
.panels__cta:focus-visible,.panels__dot:focus-visible{outline:3px solid var(--orange);outline-offset:3px}
#panels.panels--enhanced .panels__copy,#panels.panels--enhanced .panels__visual{opacity:0;transform:translateY(1.5rem)}
#panels.panels--enhanced .panels__panel.is-visible .panels__copy,#panels.panels--enhanced .panels__panel.is-visible .panels__visual{opacity:1;transform:none;transition:opacity .7s var(--ease),transform .8s var(--ease)}
@keyframes panels-float{0%,100%{transform:translate3d(0,-.45rem,0) rotate(-1deg)}50%{transform:translate3d(0,.55rem,0) rotate(1deg)}}
@keyframes panels-scroll{0%{opacity:0;transform:scaleY(0)}35%{opacity:.8}100%{opacity:0;transform:scaleY(1)}}
/* deliberately NO two-column rule: the reference is a single centred column
   at every width, product above, type beneath. */
@media (min-width:48rem){.panels__product{width:min(30vw,22rem);height:min(40svh,22rem)}}
@media (prefers-reduced-motion:reduce){#panels{height:auto;overflow:visible;overscroll-behavior:auto;scroll-snap-type:none;scrollbar-width:auto}.panels__panel{min-height:auto;scroll-snap-align:none;scroll-snap-stop:normal}.panels__product,.panels__scroll::after{animation:none}.panels__cta,.panels__dot::before,#panels.panels--enhanced .panels__copy,#panels.panels--enhanced .panels__visual,#panels.panels--enhanced .panels__panel.is-visible .panels__copy,#panels.panels--enhanced .panels__panel.is-visible .panels__visual{opacity:1;transform:none;transition:none}}

@media (max-width:47.99rem) and (max-height:48rem){.panels__panel{padding-top:3.5rem;padding-bottom:1.25rem}.panels__inner{grid-template-rows:minmax(9rem,32svh) auto;gap:.75rem}.panels__product{height:min(31svh,15rem)}.panels__body{margin-top:.5rem;font-size:.9rem;line-height:1.4}.panels__meta{margin-top:.6rem}.panels__scroll{bottom:1rem}}

/* --- falling product cycle (js/fall.js) ---------------------------------- */
/* place-items must stay `stretch`: with `center` the grid area is indefinite,
   so the image's height:100% never resolves and a 4000px-tall racket cutout
   renders at full height straight out of the panel. object-fit does the
   centring instead. */
.fall{position:relative;display:grid;grid-template:1fr/1fr;place-items:stretch;width:min(100%,31rem);height:min(46svh,31rem);text-decoration:none;cursor:pointer;-webkit-tap-highlight-color:transparent}
/* multiply drops the white studio background against the panel's pale gradient
   while keeping every real anti-aliased edge and the product's own shadow.
   No knockout, nothing cut. Panel gradients must stay light for this to hold. */
/* The film must be OUT OF FLOW. In normal flow its height:100% cannot resolve
   against an indefinite grid area, so it fell back to its intrinsic 960x960 and
   pushed the panel to 950px — taller than the 408px scroller, which in turn made
   the intersection ratio unreachable and froze every cycle. One stray layout
   value, and the whole page looked static with no error anywhere. */
/* pointer-events:none — the film is decoration painted over the product's own
   link, and without this it swallowed every click on the flagship. */
.fall__vid{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  pointer-events:none;mix-blend-mode:multiply;will-change:opacity}
/* settle: drop from above, overshoot slightly, come to rest — then breathe */
.fall__img.is-in{animation:fall-drop .78s cubic-bezier(.2,1.5,.36,1) both,fall-float 6.5s ease-in-out .78s infinite}
.fall__img.is-out{animation:fall-leave .5s cubic-bezier(.5,0,.9,.35) both}
.fall:hover .fall__img.is-in{transform:rotate(var(--tilt,0deg)) scale(1.03)}
@keyframes fall-drop{
  0%  {opacity:0;transform:translate3d(0,-130%,0) rotate(calc(var(--tilt,0deg) - 22deg)) scale(.92)}
  60% {opacity:1}
  72% {transform:translate3d(0,2.5%,0) rotate(calc(var(--tilt,0deg) + 3deg)) scale(1.02)}
  100%{opacity:1;transform:translate3d(0,0,0) rotate(var(--tilt,0deg)) scale(1)}
}
@keyframes fall-float{
  0%,100%{transform:translate3d(0,0,0) rotate(var(--tilt,0deg))}
  50%    {transform:translate3d(0,-2.2%,0) rotate(calc(var(--tilt,0deg) + 1.2deg))}
}
@keyframes fall-leave{
  0%  {opacity:1;transform:translate3d(0,0,0) rotate(var(--tilt,0deg))}
  100%{opacity:0;transform:translate3d(0,90%,0) rotate(calc(var(--tilt,0deg) + 14deg)) scale(.9)}
}
/* the name + price under the product, swapping with it */
/* The caption used to render in the middle of the stage, straight across the
   products. It is now pinned under the cluster and only appears when the visitor
   points at something — the panel's own headline is the permanent label. */
.fall__cap{display:flex;flex-direction:column;align-items:center;gap:.1rem;max-width:100%;
  padding-top:.4rem;text-align:center;pointer-events:none}
.fall__cap b{font-weight:600;font-size:.82rem;letter-spacing:.01em;opacity:.72}
.fall__cap i{font-style:normal;font-size:.78rem;opacity:.5;font-variant-numeric:tabular-nums}
@media (min-width:48rem){.fall__cap b{font-size:.95rem}.fall__cap i{font-size:.88rem}}
@media (prefers-reduced-motion:reduce){.fall__img.is-in{animation:none;opacity:1;transform:rotate(var(--tilt,0deg))}.fall__img.is-out{display:none}}
/* the flagship's Grok take: same cell as the stills, revealed on its turn.
   The still underneath stays mounted so the drop animation still reads. */
.fall__vid{opacity:0;pointer-events:none;transition:opacity .45s var(--ease)}
.fall__vid.is-on{opacity:1}
.fall__img.is-under-film{opacity:0;transition:opacity .45s var(--ease)}
.fall__vid.is-on + .fall__cap,.fall:has(.fall__vid.is-on){--flagship:1}
@media (prefers-reduced-motion:reduce){.fall__vid{display:none}.fall__img.is-under-film{opacity:1}}
/* the film's own motion is light only (Grok reframes if asked to move), so the
   gentle drift is done here where it cannot drift */
.fall__vid.is-on{animation:fall-float 6.5s ease-in-out infinite}

/* Glass flagship: the glow/glassmorphic takes CANNOT use multiply — multiply
   erases a bright halo against a pale gradient. They are presented as their own
   rounded glass card instead, blended normally, while the cycling stills keep
   multiply and keep floating free. */
/* The film is composited EXACTLY like the stills: multiply, contain, no card.
   Presenting it as a rounded card with normal blending turned its own near-white
   studio backdrop into a big white rectangle — visually the same defect the
   knockouts had. The glass and the glow come from the CSS pane behind it, which
   is the only layer that should be drawing an effect. */
.fall__vid.is-glass{mix-blend-mode:multiply;object-fit:contain;border-radius:0;box-shadow:none}
.fall.has-glass{overflow:visible}
/* photos shot on black cannot be multiplied — they would read as a dark box.
   Framed as a card instead, which is honest about the source photograph. */
/* Photos shot on black cannot be multiplied — they would paint a dark box. The
   class goes on the IMG, but the blend lives on the SLOT, so the override has to
   target the slot that contains a dark image. (The old selector was
   `.fall__img.is-dark`, a class the cluster images never carry — the rule was
   dead and the dark photos were being multiplied anyway.) */
.fall__slot:has(img.is-dark){mix-blend-mode:normal}
.fall__slot img.is-dark{border-radius:clamp(.5rem,1.4vw,1rem);
  box-shadow:0 .8rem 2rem -.6rem rgba(20,18,15,.35)}

/* The glass pane is GONE. The reference has no card and no frosted panel — the
   products simply float on the bare gradient, which is why they read as objects
   rather than as images pasted onto a surface. Keeping a pane behind them was my
   addition and it was the thing making every panel look like a white box. */
.fall-glass{position:relative;display:grid;grid-template:1fr/1fr;place-items:stretch;
  width:100%;height:100%}
.fall-glass > .fall{width:100%;height:100%}

/* the flagship's Grok take: same cell as the stills, revealed on its turn.
   The still underneath stays mounted so the drop animation still reads. */
.fall__vid{opacity:0;pointer-events:none;transition:opacity .45s var(--ease)}
.fall__vid.is-on{opacity:1}
.fall__img.is-under-film{opacity:0;transition:opacity .45s var(--ease)}
.fall__vid.is-on + .fall__cap,.fall:has(.fall__vid.is-on){--flagship:1}
@media (prefers-reduced-motion:reduce){.fall__vid{display:none}.fall__img.is-under-film{opacity:1}}
/* the film's own motion is light only (Grok reframes if asked to move), so the
   gentle drift is done here where it cannot drift */
.fall__vid.is-on{animation:fall-float 6.5s ease-in-out infinite}

/* Glass flagship: the glow/glassmorphic takes CANNOT use multiply — multiply
   erases a bright halo against a pale gradient. They are presented as their own
   rounded glass card instead, blended normally, while the cycling stills keep
   multiply and keep floating free. */
/* The film is composited EXACTLY like the stills: multiply, contain, no card.
   Presenting it as a rounded card with normal blending turned its own near-white
   studio backdrop into a big white rectangle — visually the same defect the
   knockouts had. The glass and the glow come from the CSS pane behind it, which
   is the only layer that should be drawing an effect. */
.fall__vid.is-glass{mix-blend-mode:multiply;object-fit:contain;border-radius:0;box-shadow:none}
.fall.has-glass{overflow:visible}
/* photos shot on black cannot be multiplied — they would read as a dark box.
   Framed as a card instead, which is honest about the source photograph. */
/* Photos shot on black cannot be multiplied — they would paint a dark box. The
   class goes on the IMG, but the blend lives on the SLOT, so the override has to
   target the slot that contains a dark image. (The old selector was
   `.fall__img.is-dark`, a class the cluster images never carry — the rule was
   dead and the dark photos were being multiplied anyway.) */
.fall__slot:has(img.is-dark){mix-blend-mode:normal}
.fall__slot img.is-dark{border-radius:clamp(.5rem,1.4vw,1rem);
  box-shadow:0 .8rem 2rem -.6rem rgba(20,18,15,.35)}

/* ---- CSS glassmorphism + glow -------------------------------------------
   The glow and the glass pane are drawn HERE, around the product, rather than
   asked of the generator. Two reasons, both learned the hard way today: every
   richer scene description made Grok recompose the shot (28% reframe on the bag,
   a reversed AEROSENSA wordmark on the shuttles), and anything the model paints
   over a product risks the product. Drawn in CSS the photograph is untouched, it
   costs one paint, and it restyles instantly without regenerating anything. */
/* NO isolation here. It makes this a stacking context, and the product's
   mix-blend-mode:multiply then blends against the SEMI-TRANSPARENT glass pane
   instead of the opaque panel gradient — multiply against transparency is a
   no-op, so every white studio background came back as a solid white square.
   Same failure as the z-index on .panels__inner. The blend group must stay the
   panel, which is the only opaque thing in the stack. */
.fall-glass{position:relative;display:grid;grid-template:1fr/1fr;place-items:stretch;
  width:min(100%,31rem);height:min(46svh,31rem)}
/* the frosted pane */

/* the specular sheen that makes it read as glass rather than a pale rectangle */

/* the bloom behind the product */

/* no z-index: it would make .fall a stacking context and kill the multiply */
.fall-glass > .fall{width:100%;height:100%}
/* the product lifts off the glass */
.fall-glass .fall__img{filter:drop-shadow(0 1.25rem 1.75rem rgba(20,18,15,.24))}

@media (min-width:48rem){.fall-glass{width:min(100%,42rem);height:min(64svh,40rem)}}
@media (prefers-reduced-motion:reduce){.fall-glass::after,}
/* names the treatment: the dearest model in the group is the one that gets a film */
.fall__badge{position:absolute;z-index:3;top:.6rem;left:.6rem;padding:.3rem .6rem;border-radius:2rem;
  font-family:var(--font-display);font-size:.6rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--panel-ink,var(--ink));background:rgba(255,255,255,.72);border:1px solid rgba(255,255,255,.9);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);opacity:0;transition:opacity .4s var(--ease);pointer-events:none}
.fall.is-flagship .fall__badge{opacity:1}

/* ---- the falling cluster -------------------------------------------------
   Products tumble in together, settle at fixed offsets, breathe, then drop out
   as the next group arrives. Each one is its own link. No card, no pane: they
   float on the bare gradient, which is what makes them read as objects. */
/* `container-type:size` makes this stage a query container so slots can be sized
   in `cqmin` — 1% of its SMALLER dimension. Sizing by width alone was the bug a
   real phone exposed: Chrome's URL bar shrinks `svh`, the stage got shorter than
   an emulator predicts, and square products sized off the width then overflowed
   vertically into the caption. cqmin makes the products fit both axes by
   construction, whatever the browser chrome does. */
.fall{position:relative;display:block;width:100%;height:100%;container-type:size;
  text-decoration:none;cursor:default;-webkit-tap-highlight-color:transparent}
/* The blend goes on the SLOT, not on the <img> inside it.
   The slot is the element being animated, and an element with a transform — or
   even just `will-change: transform` — forms a stacking context, which traps a
   child's mix-blend-mode against a transparent backdrop and leaves the white
   photo background fully opaque. Third time this bit today (after z-index on
   .panels__inner and isolation on the glass wrapper), so the rule worth keeping:
   whatever element is animated is the element that must carry the blend. */
/* The slot is a SQUARE box and the product is contained inside it. Sizing only
   the width let aspect ratio decide the height, and a trimmed racket is tall and
   narrow — at 33% width its height ran 88px past the stage and into the copy.
   Bounding both axes makes the layout independent of what is photographed. */
.fall__slot{position:absolute;left:var(--x);top:var(--y);width:calc(var(--size) * 1cqmin);aspect-ratio:1;
  transform:translate(-50%,-50%);text-decoration:none;cursor:pointer;
  mix-blend-mode:multiply;will-change:transform,opacity}
/* the cap has to leave room for the tilt and the float: a trimmed racket is
   tall and narrow, so at the old cap its rotated bounding box plus the 3.5%
   float drift reached past the stage. 34svh leaves that headroom. */
.fall__slot img{display:block;width:100%;height:100%;object-fit:contain;
  transform:rotate(var(--rot,0deg));transition:transform .3s var(--ease)}
.fall__slot:hover img{transform:rotate(var(--rot,0deg)) scale(1.06)}
.fall__slot.is-in{animation:cluster-drop .82s cubic-bezier(.2,1.35,.36,1) var(--delay,0s) both,
                            cluster-float 7s ease-in-out calc(var(--delay,0s) + .82s) infinite}
.fall__slot.is-out{animation:cluster-leave .5s cubic-bezier(.5,0,.9,.35) var(--delay,0s) both}
@keyframes cluster-drop{
  0%  {opacity:0;transform:translate(-50%,-190%) scale(.86)}
  62% {opacity:1}
  78% {transform:translate(-50%,-46%) scale(1.03)}
  100%{opacity:1;transform:translate(-50%,-50%) scale(1)}
}
@keyframes cluster-float{
  0%,100%{transform:translate(-50%,-50%)}
  50%    {transform:translate(-50%,-53.5%)}
}
@keyframes cluster-leave{
  0%  {opacity:1;transform:translate(-50%,-50%)}
  100%{opacity:0;transform:translate(-50%,60%) scale(.9)}
}
@media (prefers-reduced-motion:reduce){
  .fall__slot.is-in{animation:none;opacity:1;transform:translate(-50%,-50%)}
  .fall__slot.is-out{display:none}
}

/* Narrow screens can't hold three cards side by side; stack them and let the page
   scroll normally rather than pretending a 375px column can show three. */
@media (max-width:56rem){
  #panels{grid-template-columns:1fr;height:auto;gap:clamp(.6rem,2vw,1rem)}
  /* taller stacked panels: the stage takes what the copy leaves, so a short
     panel squeezed the products to 42px — under the 44px tap minimum. */
  .panels__panel{min-height:min(82svh,38rem)}
  .panels__title{font-size:clamp(1.6rem,6.5vw,2.6rem)}
  .panels__body{font-size:clamp(.85rem,3.4vw,1rem)}
}
/* Nothing scrolls any more, so the dot navigation and the "scroll" cue are not
   just decorative — the dots nav was still a grid ITEM, taking the first cell and
   pushing the third card onto a second row. */
#panels .panels__dots,#panels .panels__scroll{display:none!important}
/* when the flagship's film is playing, its still hides beneath it. The class goes
   on the SLOT (the anchor), which is what fall.js toggles — targeting .fall__img
   here silently did nothing and left the still showing through the video. */
/* visibility, NOT opacity: the slot is running the drop/float animation, and a
   CSS animation overrides a normal opacity declaration, so `opacity:0` here lost
   and the still stayed visible underneath the film — the product appeared
   doubled. `visibility` is not in the animation, so nothing fights it. */
/* Hide the IMAGE, keep the ANCHOR. Hiding the slot made the flagship
   unclickable — the two products with films were the only two that could
   not be opened. The link still covers the film and keeps its href. */
.fall__slot.is-under-film img{visibility:hidden}
