/* ============================================================
   CUBANO CLAN — luxury homepage (v-lux)
   Scoped entirely under .lux-home so it never touches the rest
   of the site. Reuses the site design tokens (themed dark/light),
   fonts and .btn components from main.css. Mirrors the approved
   homepage-preview.html layout.
   ============================================================ */


.lux-home{
  /* token bridge: preview names → live themed tokens */
  --text:var(--cream);
  --container:var(--maxw);
  --gut:clamp(20px,5vw,40px);
}
.lux-home .flame-text{background:var(--flame);-webkit-background-clip:text;background-clip:text;color:transparent}
.lux-home .eyebrow{
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--font-mono);font-size:.72rem;font-weight:700;
  letter-spacing:.28em;text-transform:uppercase;color:var(--flame-1);
}
.lux-home .eyebrow::before{content:"";width:26px;height:1px;background:var(--flame-1);opacity:.8}
.lux-home .eyebrow.center::before{display:none}
/* 2026-07-06: the bilingual .bn eyebrow chips shipped earlier this day were
   retired the same evening — owner rejected mixed-script design elements
   ("don't add both languages at the same time"). Design chrome is
   English-only; Bangla appears only as authentic content (the Clan Love
   testimonial). Do not reintroduce mixed-language chips/stamps. */

/* ── THE POSTER (2026-07-28) ───────────────────────────────────────────────
   The previous hero fitted the photograph with `contain` and pinned it right,
   which left the whole left half of a very wide box showing a blurred copy of
   the same picture — a photograph with a smear beside it, not a campaign.
   The owner asked for the frame itself: full banner, full poster.

   So the photo now `cover`s the section edge to edge at every width, the
   blurred filler layer is deleted (cover leaves no slack to fill), and the
   copy sits on the floor of the frame rather than in its middle — the shot's
   own burnt-in CUBANO lettering owns the upper half and nothing is allowed to
   sit on top of it. */
.lux-home .hero{position:relative;min-height:calc(100svh - 94px);display:flex;align-items:flex-end;overflow:hidden;
  isolation:isolate;background:#0E0D11}
/* The base64 thumbnail below is the flash fix. In light mode the page ground is
   #F5F5F7; until the hero JPEG decoded there was nothing painted over it inside
   this box, so the first frames showed a pale sheet where the photograph was
   about to be — read as "a flash of white on the hero". A background declared
   in the stylesheet has no second network round-trip: it is there on the first
   paint, at 32x21px and 758 bytes, blown up and blurred by the browser. By the
   time the real photo decodes it fades in over an already-dark, already-
   roughly-correct frame, so there is no light state to see at any point. */
.lux-home .hero-bg{position:absolute;inset:0;z-index:-3;overflow:hidden;
  background:#0E0D11 url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExISEyccHhcgLikxMC4pLSwzOko+MzZGNywtQFdBRkxOUlNSMj5aYVpQYEpRUk//2wBDAQ4ODhMREyYVFSZPNS01T09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0//wAARCAAVACADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDl9R1KfUbx7idtxJyEHT6YqrbxzSTu3lZ+XdgkAAdK00ghbgqAPYYpyWkAYgIvPqAa5NDo5XfUoSWDIkRMSsX42/xZzj8qla4WHFvKH8qJsSIRtBHoCP8Aaz1qfUkt4ZbSAyMsbLmZV42jsM9fU1nWkP266u4ollkLfOADyVznpWns7rUnmtsaPmo0aBIyrDq2/OfwpA7Z60UVLLRn6jBnMzuS+OT0JqqrvamKSBirNHkkfWiitottGMkkz//Z") center/cover no-repeat}
.lux-home .hero-media{position:absolute;inset:0;display:block}
/* Poster fit, TOP-ANCHORED (2026-07-28, owner: "if you really have to cut,
   cut from the bottom"). The file is never cropped on disk — the five
   `hero-clan-*.jpg` steps are proportional resizes of one 1536x1024 master.
   The crop is the browser fitting a 3:2 frame into a box that is nearer 2:1,
   and `object-position: 50% 0%` decides where that difference is taken from:
   pinned to the top, everything lost comes off the BOTTOM of the frame
   (asphalt), and the heads, the car and the burnt-in CUBANO lettering are
   never touched. */
.lux-home .hero-main{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:50% 0%;
  /* main.css dims a generic hero photo to --hero-img-opacity (.52 in dark) so
     text can sit anywhere over it. A poster is not a backdrop: it runs at full
     strength, and legibility comes from the bottom scrim instead. */
  opacity:1;
  animation:heroIn .9s var(--ease) both}
/* THE WHITE, FOUND. main.css paints `.hero::after` with `--hero-grad`, whose
   last layer is `linear-gradient(180deg, transparent 46%, ..., var(--ink) 100%)`
   — and in light mode `--ink` IS the paper colour. That is the pale wash the
   owner kept seeing across the bottom of the hero, in the theme where it shows:
   not a flash, a permanent gradient, painted by a rule this file never touched.
   The lux hero draws its own scrim on `.hero-bg::after`, so the generic one is
   switched off here rather than re-toned. */
.lux-home .hero::after{background:none;content:none}
/* The 2:1 no-crop experiment (aspect-ratio on the section, so `cover` had no
   slack to take) is reverted on the owner's call, 2026-07-29: "add the previous
   image, that you edited or cut a little bit from the bottom". Showing the file
   whole meant a 720px-tall band at 1440 instead of a full-height frame, which
   cost the poster its presence and dropped the copy down the screen with it.
   The hero is a tall frame again and the difference comes off the bottom edge
   (object-position 50% 0% above). */
@keyframes heroIn{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.lux-home .hero-main{animation:none}}

/* Bottom-weighted scrim, not a side one. The copy sits on the floor of the
   frame now, so that is the only place the photograph has to be darkened —
   and it keeps the burnt-in CUBANO type in the upper half completely clear.
   The stops are steep on purpose: legible under the type, gone by 55% up. */
.lux-home .hero-bg::after{content:"";position:absolute;inset:0;
  background:
    linear-gradient(0deg,rgba(8,7,10,.92) 0%,rgba(8,7,10,.72) 18%,rgba(8,7,10,.34) 38%,rgba(8,7,10,0) 58%),
    linear-gradient(96deg,rgba(8,7,10,.55) 0%,rgba(8,7,10,.18) 34%,rgba(8,7,10,0) 62%),
    radial-gradient(120% 70% at 50% 100%,rgba(242,84,27,.14),transparent 60%)}
/* Two tracks again (2026-07-28): copy left, the restored drop deck right, both
   sitting on the floor of the frame. */
.lux-home .hero-grid{position:relative;z-index:2;display:grid;grid-template-columns:minmax(0,1fr) auto;
  align-items:end;gap:clamp(20px,3vw,48px);width:100%;max-width:var(--container);margin-inline:auto;
  padding:clamp(28px,5vh,56px) var(--gut) clamp(56px,9vh,104px)}
.lux-home .hero-copy{max-width:min(52ch,100%)}
/* The copy sat lower after the poster pass than it did before it, and the owner
   asked for it back up ("this part was little bit higher before"). It is still
   anchored to the floor of the frame — the lockup just stands further off it,
   which is also what keeps it clear of the deck's shadow. Desktop only: on a
   phone the frame is short and every pixel of standing room is already spent. */
@media (min-width:900px){
  .lux-home .hero-grid{padding-bottom:clamp(96px,13vh,158px)}
}

/* ═══ HERO DROP DECK ══════════════════════════════════════════════════════
   Restored from commit 4cd93fe. Fanned featured-product cards; the JS in
   home.html sets each card's fan vars from the container's live width, so any
   count (1..n) fits at any size. Smaller than the original (168x236 vs
   188x264) because it now shares the frame with a poster rather than sitting
   in an empty right-hand column. */
/* THE MOTION, SECOND PASS (2026-07-29). The deck used to bob as one solid
   block — three cards welded together sliding up and down, which reads as a
   moving <div>, not as cards. Replaced by three separate motions that layer:

     1. Each card breathes on its own clock (cardBob), phase-staggered by its
        index, with a fraction of a degree of roll. Written on the independent
        `translate`/`rotate` properties, NOT `transform` — the fan geometry
        lives in `transform` via --tx/--ty/--rot, and the two compose instead
        of fighting. That is the whole reason this can animate at all.
     2. The plane tilts toward the cursor (--tiltX/--tiltY, set by the JS in
        home.html). Because the cards sit at different x offsets, one tilt
        parallaxes the whole fan.
     3. On touch, where there is no cursor and no hover, the deck opens and
        closes itself on a timer (.is-open, same vars the hover state uses),
        so the effect is not desktop-only. */
@keyframes cardBob{
  0%{translate:0 0;rotate:0deg}
  50%{translate:0 -11px;rotate:.9deg}
  100%{translate:0 0;rotate:0deg}}
@keyframes deckGlow{0%,100%{opacity:.4}50%{opacity:.7}}
@keyframes shineSwipe{0%{transform:translateX(-130%) skewX(-20deg)}100%{transform:translateX(230%) skewX(-20deg)}}
.lux-home .hero-deck-wrap{justify-self:end;align-self:end}
.lux-home .hero-deck{
  position:relative;
  width:clamp(300px,26vw,380px);height:288px;perspective:950px;
  transform:rotateX(var(--tiltX,0deg)) rotateY(var(--tiltY,0deg));
  transition:transform .45s cubic-bezier(.22,1,.36,1)}
.lux-home .hero-deck::before{content:"";position:absolute;inset:-44px -20px;z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse 72% 56% at 50% 64%,rgba(242,84,27,.22),transparent 68%);
  filter:blur(22px);animation:deckGlow 3.8s ease-in-out 1.4s infinite alternate}
.lux-home .deck-card{
  position:absolute;left:50%;top:50%;width:168px;height:236px;
  border-radius:16px;overflow:hidden;background:#1a1820;display:block;text-decoration:none;
  box-shadow:0 18px 52px rgba(0,0,0,.58),0 4px 14px rgba(0,0,0,.3),inset 0 1px 0 rgba(255,255,255,.07);
  transform:translate(-50%,-50%) translate(var(--tx,0px),var(--ty,0px)) rotate(var(--rot,0deg));
  transform-origin:50% 95%;
  transition:transform .5s cubic-bezier(.22,1,.36,1),filter .3s ease,box-shadow .3s ease;
  will-change:transform,translate;
  animation:cardBob 4.6s ease-in-out infinite;
  /* Negative delay = start mid-cycle, so the three cards are already out of
     phase on the first frame instead of marching together for 4.6s first. */
  animation-delay:calc(var(--i,0) * -1.15s)}
.lux-home .deck-card:hover,.lux-home .deck-card:focus-visible{animation-play-state:paused}
.lux-home .hero-deck:hover .deck-card,
.lux-home .hero-deck:focus-within .deck-card,
.lux-home .hero-deck.is-open .deck-card{
  transform:translate(-50%,-50%) translate(var(--txo,var(--tx)),var(--ty)) rotate(var(--roto,var(--rot)))}
.lux-home .hero-deck .deck-card:hover,
.lux-home .hero-deck .deck-card:focus-visible{
  transform:translate(-50%,-50%) translate(var(--txo,var(--tx)),var(--ty)) rotate(var(--roto,var(--rot))) translateY(-24px) scale(1.07)!important;
  z-index:60!important;filter:brightness(1.08)!important;
  box-shadow:0 36px 80px rgba(0,0,0,.7),0 0 42px rgba(242,84,27,.28),inset 0 1px 0 rgba(255,255,255,.12)!important}
.lux-home .hero-deck:hover .deck-card:not(:hover),
.lux-home .hero-deck:focus-within .deck-card:not(:focus-visible){filter:brightness(.5) saturate(.75)}
.lux-home .deck-media{position:relative;width:100%;height:100%}
.lux-home .deck-media img{width:100%;height:100%;object-fit:cover;display:block}
.lux-home .deck-media::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 36%,rgba(10,9,12,.18) 58%,rgba(10,9,12,.9) 100%)}
.lux-home .deck-badge{
  position:absolute;top:9px;right:9px;z-index:3;
  background:rgba(14,13,17,.62);backdrop-filter:blur(10px) saturate(1.4);
  -webkit-backdrop-filter:blur(10px) saturate(1.4);
  border:1px solid rgba(255,255,255,.14);border-radius:8px;padding:4px 9px;
  font-family:var(--font-mono);font-size:.54rem;font-weight:700;letter-spacing:.12em;
  color:rgba(255,255,255,.88);text-transform:uppercase;white-space:nowrap}
.lux-home .deck-info{position:absolute;bottom:0;left:0;right:0;z-index:3;padding:12px 13px 14px}
.lux-home .deck-name{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  font-size:.74rem;font-weight:600;line-height:1.3;color:#fff;text-shadow:0 1px 5px rgba(0,0,0,.7)}
.lux-home .deck-shine{position:absolute;inset:0;z-index:2;border-radius:inherit;overflow:hidden;pointer-events:none}
.lux-home .deck-shine::before{content:"";position:absolute;top:0;left:0;width:55%;height:100%;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.18),transparent);
  transform:translateX(-130%) skewX(-20deg)}
.lux-home .deck-card:hover .deck-shine::before{animation:shineSwipe .55s ease forwards}
.lux-home .deck-ph{width:100%;height:100%;display:flex;align-items:center;justify-content:center;
  padding:14px;text-align:center;font-family:var(--font-display);font-size:.9rem;color:rgba(255,255,255,.6);
  background:linear-gradient(160deg,#211f28,#161520)}
@media(prefers-reduced-motion:reduce){
  .lux-home .hero-deck{animation:none;transition:none}
  .lux-home .hero-deck::before{animation:none}
  .lux-home .deck-card{animation:none}
}
/* MOBILE/TABLET (2026-07-29, owner: "working in both desktop and mobile").
   The deck used to be display:none below 1024px because in two columns it
   would have landed on the subjects of the photograph. In one column it does
   not: the grid stacks, so the deck sits under the copy on the floor of the
   frame, centred and scaled down. The fan JS reads the live card width, so the
   smaller cards get a correspondingly tighter spread with no second layout. */
@media(max-width:1023px){
  .lux-home .hero-grid{grid-template-columns:minmax(0,1fr)}
  /* main.css hides the generic .hero-deck outright below 560px, from the era
     when the fan could only be opened by a cursor. It opens itself now, so the
     lux hero puts it back. */
  .lux-home .hero-deck-wrap{justify-self:center}
  .lux-home .hero-deck{display:block;width:min(360px,92vw);height:206px;margin-top:4px}
  .lux-home .deck-card{width:124px;height:174px;border-radius:14px}
  .lux-home .deck-info{padding:9px 10px 10px}
  .lux-home .deck-name{font-size:.66rem;-webkit-line-clamp:1}
  .lux-home .deck-badge{font-size:.48rem;padding:3px 7px;top:7px;right:7px}
  .lux-home .hero-deck::before{inset:-30px -14px}
}
@media(max-width:430px){
  .lux-home .hero-deck{height:184px}
  .lux-home .deck-card{width:112px;height:158px}
  .lux-home .hero-grid{padding-bottom:clamp(34px,6vh,64px)}
}
/* The hero sits over a dark campaign photo in BOTH themes, so its copy is always
   light (never the themed --cream, which flips to dark ink in light mode). */
.lux-home .hero-copy,.lux-home .hero h1{color:#F6F2EA}
/* 2026-07-06 campus pass: heavier, tighter, bigger — poster type, not print ad.
   2026-07-15 world-stage tune (G3, desktop only via the min-width block below):
   sized so "MADE FOR / THE HEAT" sets as a two-line lockup with the CTA row
   safely above the fold — presence with air, not a shout. Mobile keeps the
   full-bleed poster scale. */
.lux-home .hero h1{font-size:clamp(2.9rem,10vw,4.6rem);font-weight:900;font-stretch:92%;letter-spacing:-.035em;line-height:.86;text-transform:uppercase}
@media (min-width:900px){
  /* Smaller than it was. The headline is no longer the only thing in the frame:
     the photograph carries its own CUBANO lettering above it, and two display
     wordmarks shouting at each other in one poster is one too many. This one
     now reads as the caption on the floor of the shot.
     2026-08-06: the 08-04 nudge down (clamp(3rem,4.8vw,4.6rem)) is reverted on
     desktop only — owner asked for the hero as it stood three days ago. The
     mobile size set in the same pass stays where it is. */
  .lux-home .hero h1{font-size:clamp(3.4rem,5.4vw,5.2rem);line-height:.9}
}
.lux-home .hero h1 .l2{display:block}
/* The hero standfirst is the serif too — it's the first place on the page where
   the two registers meet, so it's where the contrast has to be established. */
.lux-home .hero-sub{font-family:var(--font-serif);font-weight:400;
  font-size:clamp(1.06rem,1.6vw,1.32rem);color:rgba(246,242,234,.92);
  max-width:44ch;margin:18px 0 28px;line-height:1.5;text-shadow:0 1px 14px rgba(10,9,12,.55);
  text-wrap:pretty}
.lux-home .hero-cta{display:flex;align-items:center;gap:18px;flex-wrap:wrap}

/* ═══ DROP STICKER (2026-07-06 campus pass) ═══════════════════════════════
   Rotated street-sticker in the CTA row: "No restocks / when it's gone,
   it's gone" — the drop-culture promise, slapped on rather than typeset.
   One rotation, no texture (grain/smoke stays retired). English-only per
   the same-day mixed-language reversal. */
.lux-home .swag-stamp{
  display:inline-flex;flex-direction:column;gap:4px;
  transform:rotate(-4deg);
  padding:9px 15px 10px;border-radius:9px;
  border:1.5px solid color-mix(in srgb,#FF8A1E 62%,transparent);
  background:rgba(14,13,17,.55);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  box-shadow:0 6px 22px rgba(10,9,12,.35);
}
.lux-home .swag-stamp .st-line{
  font-family:var(--font-display);font-weight:700;font-size:1.02rem;line-height:1.05;
  text-transform:uppercase;letter-spacing:.02em;color:#F6F2EA;
}
.lux-home .swag-stamp i{
  font-style:normal;font-family:var(--font-mono);font-size:.54rem;font-weight:700;
  letter-spacing:.24em;text-transform:uppercase;color:#FF8A1E;
}
/* the reveal transition composes transform — keep the rotation through it */
.js .lux-home .swag-stamp.lx-reveal{transform:rotate(-4deg) translateY(30px)}
.lux-home .swag-stamp.lx-reveal.in{transform:rotate(-4deg)}

/* The scroll cue is gone (2026-07-28, owner's mark-up). It sat in the middle of
   the poster's bottom edge, which is exactly where the headline block now
   lives, and a site whose first screen is one photograph and one button does
   not need to be told which way the page goes.

   Portrait crop. The frame is 3:2; a phone is roughly 1:2, so `cover` throws
   away most of the width. Pushing the crop to 58% keeps both subjects and the
   car in shot instead of centring on empty asphalt. */
@media (max-width:720px){
  .lux-home .hero-main{object-position:60% 0%}
  .lux-home .hero-copy{max-width:100%}
}

/* The trust strip's styles were deleted with the band itself (2026-07-28).
   Its five promises live in the footer trust row, /returns/ and /about/. */

/* ---------- SECTION SCAFFOLD ----------
   Type has two registers now. The h2 is the shout: Clash Display, uppercase,
   tight. The standfirst under it is the other voice — Sentient, an editorial
   serif, lowercase, set at reading size. Neither is interesting on its own; the
   contrast between them is what stops every block reading at one volume, which
   is the single thing that made this page feel templated.

   The h2 also gets real optical tracking now: at 4.8rem, -.02em is too loose —
   large display type needs to close up as it grows or it reads as a word-space
   problem rather than a headline. */
.lux-home .lx-section{padding:clamp(64px,11vh,140px) 0}
/* Always a column, at every width — not a row that switches to a column below
   some breakpoint. A `white-space:nowrap` heading has a fixed intrinsic width
   (see below); sharing a flex row with the "Shop all →" link would mean that
   link eating into the same space the heading needs to not wrap, which is
   exactly the kind of two-different-layouts edge case that broke last time.
   One layout, provably correct at every width, is simpler than two. */
.lux-home .sec-head{display:flex;flex-direction:column;align-items:flex-start;gap:14px;margin-bottom:clamp(34px,5vh,60px)}
/* THE LINK GOES BACK ON THE HEADING'S LINE (2026-07-29, owner: "view all button
   should go to the right side (everyone), horizontal to the new arrival, the
   collections and others"). Every other page in the store already does this —
   the global `.sec-head` in main.css is a space-between row. Only the home page
   stacked, and it stacked for a reason worth restating: the headings here are
   `white-space:nowrap` at a size derived from the FULL container width, so
   anything sharing the row would have been pushed off the end of it.

   So the size is re-derived rather than the rule relaxed. The reserve is
   MEASURED, not guessed: at 1440 the widest right-hand cluster is the
   Collections one — two arrows, the dots and the link — at 251px, against 88px
   for a bare "Shop all →". 283px (251 + a 32px gap) is what comes off the
   container before the same 18.435px-per-1px-of-font-size ratio from §5.12 is
   applied, with the same 4% safety margin:

       (min(100vw - 48px, 1240px) - 283px) x 0.96 / 18.435
         → 5.208vw - 17.24px, ceiling (1240-283) x 0.96 / 18.435 = 3.11rem

   Verified with the real strings at 860/900/1024/1240/1440/1920.

   Below 860px it stays stacked. That is not a cop-out: at 800px the container
   is 752px and the Collections cluster alone is a third of it, which would
   leave the longest heading ("The promise behind every drop", 30 characters and
   unbreakable) about 21px of type — a heading rendered smaller than its own
   body copy to make room for a link. Stacked, it keeps its size and the link
   sits directly under it, which is where a thumb reaches anyway. */
@media(min-width:860px){
  .lux-home .sec-head{flex-direction:row;align-items:flex-end;justify-content:space-between;
    gap:clamp(24px,3vw,44px);flex-wrap:nowrap}
  .lux-home .sec-head>div{min-width:0}
  .lux-home .sec-head h2{font-size:clamp(1.2rem,calc(5.208vw - 17.24px),3.11rem)}
  /* Sits on the heading's baseline rather than its box: the display face has a
     lot of air under the cap line, and flush-bottom alignment reads as low. */
  .lux-home .sec-head-right,.lux-home .sec-head>.sec-link{margin-bottom:clamp(6px,.8vw,12px)}
}
.lux-home .sec-head .eyebrow{margin-bottom:6px}
.lux-home .sec-head .sec-link{margin-top:2px}
/* One line, every viewport, no exceptions — the owner's rule, twice now.
   `text-wrap:balance` is gone: its whole job is choosing attractive
   multi-line breaks, the opposite of "always one line". `white-space:nowrap`
   makes a second line structurally impossible, which only works because the
   font-size is sized to never need one.

   The size is not a guessed vw ratio — it's derived. The longest of the three
   headings this rule serves is "The promise behind every drop" → uppercased
   by this same rule to "THE PROMISE BEHIND EVERY DROP" (30 characters), and a
   live measurement of that exact string in this exact font/weight/tracking
   gave 16.87px of width per 1px of font-size. Available width for the heading
   is (viewport − 48px of .container padding), with a 4% safety margin, which
   solves to `5.7vw − 2.8px` — verified at 320/360/390/414/480/640/768/900/
   1024/1240/1440px with zero overflow at any of them. The 4.3rem ceiling is
   the same formula's value at the container's own 1240px cap, so text never
   grows past what that derivation already proved fits.
   Re-derived 2026-07-28 for Archivo Black (the display face changed; the old
   numbers were measured against Clash Display 700 and would have been wrong
   for anything else). Live measurement of the same 30-character string in
   Archivo 900 at -.028em gives 18.435px of width per 1px of font-size, which
   with the same "(viewport - 48px) with a 4% margin" rule solves to
   `5.2vw - 2.5px`, ceiling 3.85rem at the 1240px container cap. Verified at
   320/360/390/414/768/1024/1240/1440. If the display font changes again,
   re-measure — do not nudge these numbers by eye. */
.lux-home .sec-head h2{font-size:clamp(.85rem,calc(5.2vw - 2.5px),3.85rem);font-weight:900;letter-spacing:-.028em;line-height:.9;margin-top:12px;text-transform:uppercase;white-space:nowrap}
.lux-home .col-copy p{font-family:var(--font-serif);font-size:clamp(1rem,1.3vw,1.16rem);line-height:1.5}
.lux-home .sec-no{color:var(--flame-1);opacity:.7;margin-right:4px}
.lux-home .sec-link{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--flame-1);white-space:nowrap;
  border-bottom:1px solid transparent;padding-bottom:3px;transition:color .2s,border-color .2s}
.lux-home .sec-link:hover{color:var(--cream);border-bottom-color:var(--flame-1)}

/* ---------- COLLECTION BANDS ----------
   Rebuilt 2026-07-28. Two changes the owner asked for: the pinned/stacking
   scroll effect is gone (bands sit in normal flow), and each band now previews
   the actual garments in the series instead of only naming it. The preview rail
   is the point — a section called "The Collections" that shows nothing asks the
   reader to take another step before they see a single shirt.

   The image leads and the copy follows on every band. The old layout alternated
   sides on each row; with exactly two series that alternation just read as an
   inconsistency rather than a rhythm. */
/* ── THE CAROUSEL ────────────────────────────────────────────────────────────
   The bands used to be a stack: N series meant N full-height panels and a home
   page that grew every time the owner added a collection. They ride a track
   now. The viewport clips, the track slides one full width at a time, and the
   section is exactly one band tall no matter how many series exist.

   `overflow:clip` rather than `hidden` on the viewport: `hidden` on one axis
   forces the other axis to become a scroll container, which would have made the
   band's own shadow and the rail's focus rings scrollable inside their own box.
   `clip` cuts without that side effect, and `hidden` stays for the browsers
   that predate it. No radius of its own either: the band inside already has
   one, and two different corner radii — the band's 16px on phones against the
   viewport's — clip each other into a visible notch. */
.lux-home .cols-viewport{position:relative;overflow:hidden;overflow:clip}
/* THE REEL (2026-07-29, owner: "or maybe something like a slot machine
   entirely"). The bands were on a horizontal track; they are stacked in one
   grid cell now and the change of series is a VERTICAL throw — the outgoing
   band is flung up and out, the incoming one arrives from below and lands with
   an overshoot, the way a reel drops into its detent.

   Stacking rather than tracking is what keeps the height honest: the cell is
   the tallest band, always, so nothing reflows when the reel turns and the
   section is one band tall at two series or eight. */
.lux-home .cols-track{display:grid}
.lux-home .cols-track>.col-band{grid-area:1/1;width:100%;
  /* Parked below the frame. `visibility` rather than `display` so the browser
     keeps the band laid out — the grid cell has to know how tall the tallest
     one is even while it is off-frame. */
  transform:translateY(104%);opacity:0;visibility:hidden;
  transition:transform .6s cubic-bezier(.16,1,.3,1),opacity .34s linear,visibility 0s linear .6s}
/* THE DETENT. `cubic-bezier(.2,1.28,.36,1)` overshoots past the stop and comes
   back — the whole difference between a panel sliding into place and a reel
   being caught by its stop. The incoming band is also the one that gets the
   longer curve; the outgoing one leaves fast and linear, because a reel does
   not decelerate on its way past. */
.lux-home .cols-track>.col-band.is-on{
  transform:none;opacity:1;visibility:visible;
  transition:transform .66s cubic-bezier(.2,1.28,.36,1),opacity .26s linear,visibility 0s}
.lux-home .cols-track>.col-band.is-gone{
  transform:translateY(-104%);opacity:0;
  transition:transform .42s cubic-bezier(.5,0,.9,.35),opacity .34s linear,visibility 0s linear .42s}
/* The flash across the seam as the reel lands — one hairline of flame at the
   top and bottom edge of the frame, gone in 400ms. It is the only thing that
   tells the eye the movement STOPPED rather than merely finished. */
.lux-home .cols-viewport::after{content:"";position:absolute;inset:0;z-index:5;
  pointer-events:none;opacity:0;border-radius:inherit;
  background:linear-gradient(180deg,color-mix(in srgb,var(--flame-1) 85%,transparent),transparent 6%,transparent 94%,color-mix(in srgb,var(--flame-2) 85%,transparent))}
.lux-home .cols-viewport.is-landing::after{animation:reelLand .42s ease-out}
@keyframes reelLand{0%{opacity:0}22%{opacity:.85}100%{opacity:0}}
@media(prefers-reduced-motion:reduce){
  .lux-home .cols-track>.col-band,
  .lux-home .cols-track>.col-band.is-on,
  .lux-home .cols-track>.col-band.is-gone{transition:opacity .2s linear,visibility 0s}
  .lux-home .cols-track>.col-band{transform:none}
  .lux-home .cols-viewport.is-landing::after{animation:none}
}
/* Off-frame bands are removed from the tab order and the accessibility tree by
   `inert` in JS; this stops a browser that has already focused something inside
   one from scrolling the clipped viewport sideways to reach it. */
.lux-home .cols-carousel{position:relative}

/* The reel's controls. Deliberately quiet: the section's job is the artwork,
   and a carousel that announces itself with heavy chrome is a slideshow from
   2011. The dots carry the count — the one piece of information that tells a
   visitor there is more here than what is in the frame.

   Centred under the band since 2026-07-29 (owner: "i want it at the bottom
   middle"). They used to sit top-right beside "View all", which put the control
   above the thing it moves and next to a link that leaves the page entirely —
   two different jobs sharing one corner. */
.lux-home .sec-head-right{display:flex;align-items:center;gap:clamp(12px,2vw,22px);flex-wrap:wrap}
.lux-home .cols-ctrl{display:flex;align-items:center;justify-content:center;gap:12px;
  margin-top:clamp(18px,2.4vw,28px)}
.lux-home .cols-ctrl[hidden]{display:none}
/* THE ARROWS, REDONE (2026-07-29, owner: "looks cheap mediocre"). A thin ring
   that tints on hover reads as a default HTML control with a coat of paint.
   This one is a magnetic fill instead: a flame disc grows from the centre on
   hover rather than a background tinting in place, the chevron itself steps
   half a pixel toward the direction it points the moment the disc lands under
   it, and the whole thing lifts off the page on a soft flame-coloured shadow
   — three things a CSS tint transition cannot do at once, which is the
   difference between a control and an interaction. `isolation:isolate` keeps
   the fill's negative z-index scoped to this button alone. */
.lux-home .cc-arrow{width:48px;height:48px;padding:0;position:relative;isolation:isolate;
  display:grid;place-items:center;overflow:hidden;
  border-radius:50%;border:1px solid var(--border-2);background:transparent;color:var(--muted);
  cursor:pointer;
  transition:color .45s var(--ease),border-color .45s var(--ease),
             box-shadow .45s var(--ease),transform .25s var(--ease)}
.lux-home .cc-arrow::before{content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(135deg,var(--flame-1),var(--flame-2));
  transform:scale(0);transition:transform .55s cubic-bezier(.16,1,.3,1)}
.lux-home .cc-arrow svg{transition:transform .45s cubic-bezier(.16,1,.3,1)}
.lux-home .cc-arrow:hover{color:#171216;border-color:transparent;
  box-shadow:0 12px 28px -10px color-mix(in srgb,var(--flame-1) 60%,transparent)}
.lux-home .cc-arrow:hover::before{transform:scale(1)}
.lux-home .cc-arrow[data-cols-step="-1"]:hover svg{transform:translateX(-2px)}
.lux-home .cc-arrow[data-cols-step="1"]:hover svg{transform:translateX(2px)}
.lux-home .cc-arrow:active{transform:scale(.9)}
.lux-home .cc-arrow:focus-visible{outline:2px solid var(--flame-1);outline-offset:3px}
@media(prefers-reduced-motion:reduce){
  .lux-home .cc-arrow,.lux-home .cc-arrow::before,.lux-home .cc-arrow svg{transition:none}
}
.lux-home .cc-dots{display:flex;align-items:center;gap:7px}
/* A dash rather than a circle, and the live one is a longer dash in flame: the
   shape carries the position, so it still reads for anyone who cannot separate
   the two colours. */
.lux-home .cc-dot{width:16px;height:3px;padding:0;border:0;border-radius:2px;cursor:pointer;
  background:var(--border-2);
  transition:background .35s var(--ease),width .45s cubic-bezier(.32,.72,0,1)}
.lux-home .cc-dot:hover{background:var(--muted)}
.lux-home .cc-dot[aria-current="true"]{width:30px;background:linear-gradient(90deg,var(--flame-1),var(--flame-2))}
.lux-home .cc-dot:focus-visible{outline:2px solid var(--flame-1);outline-offset:4px}
/* 1.2fr / 1fr, not an even split: the owner asked for the picture to carry more
   of the band, and it is the half doing the selling — the copy beside it is
   three short lines and a button, which do not need equal billing. */
.lux-home .col-band{position:relative;display:grid;grid-template-columns:1.2fr 1fr;align-items:center;
  gap:clamp(24px,4vw,52px);border-radius:var(--radius);overflow:hidden;
  min-height:440px;padding:clamp(24px,3.4vw,44px);color:#fff;isolation:isolate}
.lux-home .col-band.cb-a{background:linear-gradient(115deg,#3a1d4d 0%,#7a2a63 52%,#c0573b 100%)}
.lux-home .col-band.cb-b{background:linear-gradient(115deg,#0e3550 0%,#1f6f8a 52%,#3bc0b0 100%)}
/* Two more palettes so a third and fourth series never repeat the band above
   them. Same construction as the first two: a deep anchor, a saturated middle,
   a warm or cool exit — they have to sit under white type at 88% opacity. */
.lux-home .col-band.cb-c{background:linear-gradient(115deg,#1b2f14 0%,#3f6b21 52%,#c9a227 100%)}
.lux-home .col-band.cb-d{background:linear-gradient(115deg,#2a1410 0%,#7a3218 52%,#d98324 100%)}
.lux-home .col-band::before{content:"";position:absolute;inset:0;z-index:-1;opacity:.2;pointer-events:none;
  background:radial-gradient(80% 60% at 20% 0%,#fff,transparent 60%)}
.lux-home .col-copy{position:relative;z-index:1;min-width:0}
.lux-home .col-eyebrow{font-family:var(--font-mono);font-size:.7rem;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:#fff;opacity:.82}
.lux-home .col-copy h3{font-size:clamp(2.2rem,5vw,3.8rem);margin:10px 0 12px;text-transform:uppercase;letter-spacing:-.015em;color:#fff;line-height:.94}
.lux-home .col-copy p{max-width:44ch;color:rgba(255,255,255,.88);margin-bottom:22px}
/* SQUARE, AND NOTHING IS CUT (2026-07-29, owner: "i want the full product image
   in there, if i upload any image it should fit there properly"). The frame was
   5:4 and filled by cropping, which is fine for a photograph shot to that shape
   and ruinous for anything else — an upright garment lost its collar and its
   hem, and the owner cannot be asked to crop every upload to one ratio before
   it goes in.

   A square is the one frame that treats a portrait and a landscape upload
   equally badly, which is to say equally well: neither is favoured, and the
   band's height stops depending on what was photographed that week. */
.lux-home .col-art{position:relative;z-index:1;border-radius:16px;overflow:hidden;aspect-ratio:1/1;
  box-shadow:0 26px 60px rgba(10,9,12,.42);background:rgba(0,0,0,.25)}
/* Each slide is two copies of one file. The front one is CONTAINED — the whole
   garment, whatever its shape. The back one is the same picture blown past the
   edges and blurred out, so the space the contained shot does not reach is
   filled with that photograph's own colour and light instead of a black bar.
   It is the treatment a phone gallery uses for the same reason. */
.lux-home .ca-fill{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transform:scale(1.18);filter:blur(28px) saturate(1.3) brightness(.78);
  opacity:.92;pointer-events:none}
.lux-home .ca-shot{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  object-position:50% 50%;transition:transform 1.1s var(--ease)}
.lux-home .col-band:hover .ca-shot{transform:scale(1.035)}
/* THE PUSH (2026-07-29, owner: "pushup, push left transition"). Each piece
   owns one axis for the whole session — vertical or horizontal — and unlike
   the four-doors version this replaces, incoming and outgoing now travel the
   SAME direction on that axis: the new piece enters from the near edge and
   the old one is shoved out the far edge, one continuous filmstrip motion,
   rather than two pieces arriving from opposite edges and passing each other.

   The parked position IS the entry position: a slide waiting its turn already
   sits just past its own near edge at zero opacity, so bringing it in is one
   class and the browser has nothing to set up first. Full-frame travel (100%,
   not a fraction of it) is what sells "push" over "drift" — the piece has to
   visibly leave the frame, not just nudge inside it. */
.lux-home .ca-slide{position:absolute;inset:0;opacity:0;z-index:1;filter:blur(14px);
  transition:opacity 0s linear,transform .68s cubic-bezier(.16,1,.3,1),filter .8s var(--ease)}
.lux-home .ca-slide.dr-up{transform:translate3d(0,100%,0)}
.lux-home .ca-slide.dr-left{transform:translate3d(100%,0,0)}
/* Opacity is a binary visibility flag on every state below, always 0s: all
   the motion reads through transform (the push) and filter (the focus pull),
   never a fade, which is what keeps this a push and not a cross-dissolve. A
   parked slide resets across the FULL frame behind an instant opacity:0, so
   the reset itself is invisible even though its transform still takes .68s. */
.lux-home .ca-slide.is-on{opacity:1;transform:none;filter:blur(0);z-index:2;
  transition:opacity 0s linear,transform .68s cubic-bezier(.16,1,.3,1),filter .8s var(--ease)}
/* Continues off the FAR edge on the same axis it entered by — a push, not a
   swap through opposite edges. Faster than the entrance so the frame never
   looks crowded with two pieces mid-flight. */
.lux-home .ca-slide.is-out{z-index:1;opacity:1;filter:blur(9px);
  transition:opacity 0s linear,transform .5s cubic-bezier(.5,0,.75,.35),filter .4s var(--ease)}
.lux-home .ca-slide.dr-up.is-out{transform:translate3d(0,-100%,0)}
.lux-home .ca-slide.dr-left.is-out{transform:translate3d(-100%,0,0)}
/* Progress hairline along the foot of the frame: it fills over the dwell time
   so the swap is expected rather than startling, and it is the only moving
   thing in the band. It is driven by a CSS animation restarted from JS, so a
   paused slideshow (pointer on the rail) has a visibly paused line too. */
.lux-home .col-art::after{content:"";position:absolute;left:0;bottom:0;height:2px;width:100%;
  z-index:3;pointer-events:none;
  transform-origin:0 50%;transform:scaleX(0);
  background:linear-gradient(90deg,var(--flame-1),var(--flame-2));opacity:.9}
.lux-home .col-art.is-timing::after{animation:caTick var(--ca-dwell,4.6s) linear forwards}
.lux-home .col-art.is-held::after{animation-play-state:paused}
@keyframes caTick{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@media(prefers-reduced-motion:reduce){
  .lux-home .ca-slide{transition:none}
  .lux-home .col-art::after{display:none}
}
/* The two chevrons that sat on the picture were removed on 2026-07-29 (owner:
   "remove this and add auto swap"). Their whole job — paging the pieces — now
   belongs to the rail of thumbnails, which does it by being pointed at, and to
   a swipe on touch. Nothing sits on top of the garment any more.

   THE FLAG. A collection wears it for its first three weeks (see
   Collection.badge_until), and the owner sets both the wording and the day it
   comes off. Flame on the band's own colour, beside the piece count, because
   that line is already the band's small print — the flag belongs with the facts
   about the series, not floating over the artwork. */
.lux-home .col-flag{display:inline-block;margin-left:10px;vertical-align:1px;
  font-family:var(--font-mono);font-size:.58rem;font-weight:800;letter-spacing:.16em;
  text-transform:uppercase;color:#171216;
  background:linear-gradient(100deg,var(--flame-1),var(--flame-2));
  padding:4px 9px;border-radius:100px;
  box-shadow:0 0 0 1px rgba(255,255,255,.25),0 6px 18px rgba(0,0,0,.28)}

/* THE PREVIEW RAIL — the actual pieces, left to right, each one a direct link.
   Horizontal scroll with snap on every size, so it degrades to a swipe on touch
   and never forces a wrapping grid inside a band. */
.lux-home .col-rail{display:flex;gap:10px;margin:0 0 24px;padding-bottom:6px;
  overflow-x:auto;scroll-snap-type:x proximity;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.lux-home .col-rail::-webkit-scrollbar{display:none}
.lux-home .cr-item{flex:0 0 auto;width:96px;scroll-snap-align:start;
  border-radius:11px;overflow:hidden;background:rgba(255,255,255,.10);
  border:1px solid rgba(255,255,255,.20);
  transition:transform .3s var(--ease),border-color .3s var(--ease),background .3s var(--ease)}
.lux-home .cr-item img{display:block;width:100%;aspect-ratio:4/5;object-fit:cover}
.lux-home .cr-name{display:block;padding:7px 8px 8px;
  font-family:var(--font-mono);font-size:.54rem;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:rgba(255,255,255,.86);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lux-home .cr-item:hover,.lux-home .cr-item:focus-visible{
  transform:translateY(-4px);background:rgba(255,255,255,.18);border-color:rgba(255,255,255,.5)}
/* The rail is the slideshow's index: whichever piece is in the big frame is
   marked here, so the two halves of the band are visibly the same thing. */
.lux-home .cr-item.is-current{background:rgba(255,255,255,.22);border-color:#fff}
.lux-home .cr-item.is-current .cr-name{color:#fff}

/* The rail arrives left-to-right as the band reveals — a stagger on the shared
   .in class, so it rides the same IntersectionObserver as everything else and
   never runs off-screen. Enter only; there is no exit to soften. */
@media(prefers-reduced-motion:no-preference){
  .js .lux-home .col-band .cr-item{opacity:0;transform:translateX(-18px)}
  .lux-home .col-band.in .cr-item{opacity:1;transform:none;
    transition:opacity .5s var(--ease),transform .55s var(--ease);
    transition-delay:calc(.18s + var(--ri,0)*80ms)}
  /* Hover must beat the entrance transform once the band has landed. */
  .lux-home .col-band.in .cr-item:hover{transform:translateY(-4px)}
}

.lux-home .cb-btn{position:relative;overflow:hidden;display:inline-flex;align-items:center;gap:10px;
  font-family:var(--font-mono);font-weight:700;font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;color:#fff;
  padding:14px 26px;border-radius:100px;border:1px solid rgba(255,255,255,.6);background:rgba(255,255,255,.1);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:color .3s var(--ease),background .3s var(--ease),border-color .3s var(--ease),transform .3s var(--ease)}
.lux-home .cb-btn svg{transition:transform .3s var(--ease)}
.lux-home .cb-btn:hover{background:#fff;color:#141318;border-color:#fff;transform:translateY(-2px)}
.lux-home .cb-btn:hover svg{transform:translateX(4px)}
.lux-home .cb-btn::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(115deg,transparent 30%,rgba(255,255,255,.55) 48%,transparent 62%);
  transform:translateX(-130%);transition:transform .7s var(--ease)}
.lux-home .cb-btn:hover::after{transform:translateX(130%)}
/* PHONE BAND, SECOND PASS (2026-07-29, owner: "i think it too big"). Measured
   at 390px the band ran ~600px tall, so two series alone were 1200px of scroll
   before anything else. Every number below is a cut, and the two structural
   ones are the rail and the tagline:

     • The rail was a horizontally scrolling strip — the owner's "horizontal
       scroll, do something about it". It is a wrapping auto-fit grid now, so
       the whole series is visible at once with nothing hidden off the right
       edge, and the frame is paged by a swipe or a tap on a thumbnail instead.
     • The tagline is clamped to two lines. It is a supporting sentence; on a
       phone the fourth line of it costs more than it says. */
@media(max-width:760px){
  .lux-home .col-band{grid-template-columns:minmax(0,1fr);padding:16px;min-height:0;
    gap:16px;border-radius:16px}
  /* 16:9 here was the same crop problem in miniature: a letterbox on a phone
     showed a strip of the garment. Square costs about 150px of scroll and is
     the difference between seeing a shirt and seeing part of one. */
  .lux-home .col-art{aspect-ratio:1/1}
  .lux-home .col-flag{margin-left:8px;font-size:.54rem;padding:3px 8px}
  .lux-home .col-copy h3{font-size:clamp(1.75rem,7vw,2.4rem);margin:6px 0 8px}
  .lux-home .col-copy p{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
    overflow:hidden;font-size:.95rem;margin-bottom:16px}
  .lux-home .col-rail{display:grid;grid-template-columns:repeat(auto-fit,minmax(58px,1fr));
    gap:8px;overflow:visible;margin-bottom:18px;padding-bottom:0}
  .lux-home .cr-item{width:auto;border-radius:9px}
  .lux-home .cb-btn{padding:12px 20px;font-size:.68rem}
}
@media(max-width:520px){
  /* The thumbnail is the identifier at this size; the name under it is four
     letters and a number in 8px type, which is decoration, not information. */
  .lux-home .cr-name{display:none}
}

/* ---------- FEATURED PRODUCTS ---------- */
/* minmax(0,..) is load-bearing: a plain 1fr track keeps its min-content floor, so one
   wide card blows the column out, inflates sibling rows, and (Chromium) the grid box
   ends up shorter than its rows — cards then bleed into the next section. */
/* ---------- BRAND STORY ---------- */
.lux-home .story{display:grid;grid-template-columns:1fr 1fr;gap:clamp(36px,6vw,84px);align-items:center}
.lux-home .story-media{position:relative;border-radius:var(--radius);overflow:hidden;aspect-ratio:4/5;display:block}
.lux-home .story-media img{width:100%;height:100%;object-fit:cover;transition:transform 1.2s var(--ease)}
.lux-home .story-media:hover img{transform:scale(1.05)}
.lux-home .story-media .stamp{position:absolute;right:18px;top:18px;width:96px;height:96px;border-radius:50%;
  display:grid;place-items:center;text-align:center;background:rgba(14,13,17,.5);backdrop-filter:blur(8px);
  border:1px solid var(--border-2);font-family:var(--font-mono);font-size:.56rem;letter-spacing:.14em;
  text-transform:uppercase;line-height:1.5;color:#F4F1EA}
.lux-home .story-tag{position:absolute;left:16px;right:16px;bottom:16px;display:flex;flex-direction:column;gap:7px;
  background:rgba(14,13,17,.55);backdrop-filter:blur(12px);border:1px solid var(--border-2);
  border-radius:14px;padding:14px 16px;transition:transform .6s var(--ease)}
.lux-home .story-media:hover .story-tag{transform:translateY(-4px)}
.lux-home .story-tag-eyebrow{font-family:var(--font-mono);font-size:.58rem;font-weight:700;letter-spacing:.22em;
  text-transform:uppercase;color:var(--flame-1)}
.lux-home .story-tag-row{display:flex;align-items:center;justify-content:space-between;gap:14px}
.lux-home .story-tag-name{font-family:var(--font-display);font-weight:600;font-size:1.02rem;color:#F4F1EA;text-transform:uppercase}
.lux-home .story-tag-price{font-family:var(--font-mono);font-weight:700;color:var(--flame-1);font-size:.9rem;white-space:nowrap}
.lux-home .story h2{font-size:clamp(2rem,4vw,3.2rem);margin:18px 0 22px;text-transform:uppercase;overflow-wrap:break-word}
.lux-home .story p{color:var(--muted);max-width:52ch;margin-bottom:18px}
/* ---------- WHY CUBANO (value cards) ---------- */
.lux-home .value-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
.lux-home .value-card{position:relative;background:var(--ink-2);border:1px solid var(--border);border-radius:18px;
  padding:34px 28px;overflow:hidden;transition:transform .4s var(--ease),border-color .4s,box-shadow .4s}
.lux-home .value-card:hover{transform:translateY(-6px);border-color:var(--border-2);box-shadow:var(--shadow)}
.lux-home .value-num{font-family:var(--font-display);font-size:64px;line-height:1;position:absolute;top:6px;right:18px;
  color:color-mix(in srgb,var(--cream) 7%,transparent)}
.lux-home .value-ico{width:48px;height:48px;border-radius:12px;display:grid;place-items:center;
  background:color-mix(in srgb,var(--flame-1) 14%,transparent);color:var(--flame-1);margin-bottom:18px}
.lux-home .value-card h3{font-size:1.28rem;margin-bottom:9px;text-transform:uppercase}
.lux-home .value-card p{color:var(--muted);font-size:.94rem}
@media(max-width:980px){.lux-home .value-grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.lux-home .value-grid{grid-template-columns:1fr}}

/* The full-bleed newsletter section's CSS (.drop, .drop-bg, .drop-form,
   .drop-fine, .drop-msg — 24 rules and a flatlay photograph) went with the
   section itself on 2026-07-29. Capture lives in the footer now and is styled
   in main.css, unscoped, because it appears on every page rather than this one.
   Note .drop-timer below is a DIFFERENT component — the hero countdown — and
   stays. The honeypot's rule also moved out of this file: main.css already
   carries an unscoped .hp-field, which is what the footer form needs. */

/* ---------- REVEAL ---------- */
/* Initial hidden state only applies when JS is running (html.js set in base.html),
   so content stays visible for no-JS visitors and crawlers. */
.js .lux-home .lx-reveal{opacity:0;transform:translateY(30px);transition:opacity .9s var(--ease),transform .9s var(--ease)}
.lux-home .lx-reveal.in{opacity:1;transform:none}
.js .lux-home .lx-stagger>*{opacity:0;transform:translateY(24px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.lux-home .lx-stagger.in>*{opacity:1;transform:none}
.lux-home .lx-stagger.in>*{transition-delay:calc(var(--i,0)*70ms)}

/* THE CURTAIN (2026-07-29). The reel and the four-door swap already made the
   collections themselves feel alive; the section still arrived on screen with
   the same plain fade-and-rise every other block on the page uses. It gets its
   own entrance: the reel rises into view like a curtain lifting, cut once by a
   diagonal flame streak so the section reads as one system with the reel's own
   landing flash rather than a second, unrelated effect.

   The clip lives on `.cols-viewport`, a CHILD of the observed `.lx-reveal`
   element, not on the observed element itself: an IntersectionObserver in this
   browser measures a target's clipped paint area, not its layout box, so an
   element clipped to zero height reports a permanent intersection ratio of 0
   and never earns its `.in` class — the curtain would stay shut forever. The
   observed element (`.cols-carousel`) is left visually inert (opacity/transform
   neutralised, same trick the hero headline uses below) and the clip is
   delegated one level down. */
.js .lux-home .cols-carousel.lx-reveal{opacity:1;transform:none}
.js .lux-home .cols-carousel.lx-reveal .cols-viewport{
  clip-path:inset(0 0 100% 0);
  transition:clip-path 1s cubic-bezier(.16,1,.3,1)}
.lux-home .cols-carousel.lx-reveal.in .cols-viewport{clip-path:inset(0 0 0% 0)}
.lux-home .cols-viewport::before{
  content:"";position:absolute;inset:0;z-index:6;pointer-events:none;opacity:0;
  background:linear-gradient(115deg,transparent 42%,color-mix(in srgb,var(--flame-1) 65%,transparent) 50%,transparent 58%)}
.lux-home .cols-carousel.lx-reveal.in .cols-viewport::before{animation:colsCurtainSweep .9s .2s ease-out}
@keyframes colsCurtainSweep{0%{opacity:0;transform:translateX(-60%)}15%{opacity:1}85%{opacity:1}100%{opacity:0;transform:translateX(60%)}}

/* ---------- RESPONSIVE ---------- */
@media(max-width:1024px){
  .lux-home .hero-grid{grid-template-columns:1fr;gap:30px}
  .lux-home .product-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media(max-width:768px){
  /* A phone viewport is tall and narrow against a 3:2 frame, so `cover` keeps
     only a central slice of the width. Positioned on the subjects+car cluster
     rather than the open road. The scrim gets deeper here than on desktop
     because the copy block takes up a much larger share of a small frame. */
  .lux-home .hero-main{object-position:60% 0%}
  .lux-home .hero-bg::after{background:
    linear-gradient(0deg,rgba(8,7,10,.95) 0%,rgba(8,7,10,.86) 30%,rgba(8,7,10,.6) 48%,rgba(8,7,10,.22) 66%,rgba(8,7,10,0) 82%),
    radial-gradient(120% 60% at 50% 100%,rgba(242,84,27,.14),transparent 62%)}
  .lux-home .story{grid-template-columns:minmax(0,1fr)}   /* minmax(0,..) stops the grid track blowing past the viewport */
  .lux-home .hero h1{font-size:clamp(2.3rem,11vw,3.6rem)}
  /* Owner, 2026-08-04: keep the mobile hero copy as-is, just trimmed — smaller,
     left-aligned (it already was; stated explicitly so nothing upstream can
     re-centre it). */
  .lux-home .hero-copy{text-align:left}
  .lux-home .hero-sub{font-size:1rem}
}
@media(prefers-reduced-motion:reduce){
  .lux-home .lx-reveal,.lux-home .lx-stagger>*{opacity:1!important;transform:none!important;transition:none!important}
  .lux-home .cols-carousel.lx-reveal .cols-viewport{clip-path:none!important}
  .lux-home .cols-carousel.lx-reveal.in .cols-viewport::before{animation:none}
  .lux-home .hero-main{animation:none}
}

/* ═══ HERO KINETIC TYPE ════════════════════════════════════════════════
   Each word sits in an overflow mask (.hl) and its inner (.hl-in) slides
   up + straightens when the reveal system stamps `.in` on the h1. The h1
   itself stays visible (its lx-reveal fade is neutralised below) so only
   the words move — a type-first entrance instead of a block fade. */
.lux-home .hero-h1.lx-reveal{opacity:1;transform:none}
.lux-home .hero-h1 .hl{display:inline-block;overflow:hidden;vertical-align:bottom;padding-bottom:.08em;margin-bottom:-.08em}
.lux-home .hero-h1 .hl-l2{display:block}
.js .lux-home .hero-h1 .hl-in{
  display:inline-block;
  transform:translateY(118%) rotate(2.4deg);
  transform-origin:0 100%;
  transition:transform .95s cubic-bezier(.19,.8,.22,1);
  transition-delay:calc(.14s + var(--wi,0)*.09s);
}
.lux-home .hero-h1.in .hl-in{transform:none}
@media(prefers-reduced-motion:reduce){
  .js .lux-home .hero-h1 .hl-in{transform:none;transition:none}
}

/* SWAG accent: the flame gradient slowly sweeps through the letters. */
@media(prefers-reduced-motion:no-preference){
  .lux-home .hero-h1 .flame-text{
    background-size:230% 100%;
    animation:lxFlameSweep 7s ease-in-out 2.2s infinite;
  }
}
@keyframes lxFlameSweep{0%,100%{background-position:0% 50%}50%{background-position:95% 50%}}

/* The Ken Burns drift on the photo is gone. It made sense when the image was
   cover-cropped and a slow scale just revealed slightly different crop; now the
   whole frame is on screen, so scaling it either clips the edges it exists to
   show or floats it against the filler. It was also the one piece of ambient,
   unstoppable, large-area motion on the page — the kind that reads as vestibular
   discomfort rather than polish. The image holds still. The blurred filler
   behind it drifts instead, which reads as depth without moving the subject. */
@media(prefers-reduced-motion:no-preference){
  /* The drift used to be applied to the blurred filler layer, which no longer
     exists. It now runs on the photograph itself — a 26-second, 4% push-in,
     slow enough to register as depth rather than as movement. */
  .lux-home .hero-main{animation:heroIn .9s var(--ease) both,lxHeroDrift 26s ease-in-out 1s infinite alternate}
}
@keyframes lxHeroDrift{from{scale:1}to{scale:1.04}}

/* ═══ NEXT-DROP COUNTDOWN CHIP ═════════════════════════════════════════ */
.lux-home .drop-timer{
  display:inline-flex;align-items:baseline;gap:12px;
  padding:10px 16px;border-radius:999px;
  border:1px solid rgba(242,84,27,.45);
  background:rgba(14,13,17,.5);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
}
.lux-home .drop-timer .dt-label{
  font-family:var(--font-mono);font-size:.6rem;font-weight:700;
  letter-spacing:.24em;text-transform:uppercase;color:var(--flame-1);
}
.lux-home .drop-timer .dt-units{font-family:var(--font-mono);font-size:.88rem;color:#F6F2EA;white-space:nowrap}
.lux-home .drop-timer .dt-units b{font-weight:700;font-variant-numeric:tabular-nums}
.lux-home .drop-timer .dt-units i{font-style:normal;font-size:.62rem;color:rgba(246,242,234,.55);margin-right:2px}
.lux-home .drop-timer.is-live .dt-label{animation:lxLivePulse 1.2s ease-in-out infinite}
@keyframes lxLivePulse{50%{opacity:.35}}

/* ═══ MOBILE HERO ══════════════════════════════════════════════════════
   Content defines the height on a phone rather than a fixed viewport unit —
   100svh minus a header is a promise mobile browsers keep badly. */
@media(max-width:600px){
  .lux-home .hero{min-height:64svh;padding:clamp(20px,4vh,44px) 0 44px}
}

/* ═══ HERO KINETIC TYPE ════════════════════════════════════════════════
   Each word sits in an overflow mask (.hl) and its inner (.hl-in) slides
   up + straightens when the reveal system stamps `.in` on the h1. The h1
   itself stays visible (its lx-reveal fade is neutralised below) so only
   the words move — a type-first entrance instead of a block fade. */
.lux-home .hero-h1.lx-reveal{opacity:1;transform:none}
.lux-home .hero-h1 .hl{display:inline-block;overflow:hidden;vertical-align:bottom;padding-bottom:.08em;margin-bottom:-.08em}
.lux-home .hero-h1 .hl-l2{display:block}
.js .lux-home .hero-h1 .hl-in{
  display:inline-block;
  transform:translateY(118%) rotate(2.4deg);
  transform-origin:0 100%;
  transition:transform .95s cubic-bezier(.19,.8,.22,1);
  transition-delay:calc(.14s + var(--wi,0)*.09s);
}
.lux-home .hero-h1.in .hl-in{transform:none}
@media(prefers-reduced-motion:reduce){
  .js .lux-home .hero-h1 .hl-in{transform:none;transition:none}
}

/* SWAG accent: the flame gradient slowly sweeps through the letters. */
@media(prefers-reduced-motion:no-preference){
  .lux-home .hero-h1 .flame-text{
    background-size:230% 100%;
    animation:lxFlameSweep 7s ease-in-out 2.2s infinite;
  }
}
@keyframes lxFlameSweep{0%,100%{background-position:0% 50%}50%{background-position:95% 50%}}

/* The Ken Burns drift on the photo is gone. It made sense when the image was
   cover-cropped and a slow scale just revealed slightly different crop; now the
   whole frame is on screen, so scaling it either clips the edges it exists to
   show or floats it against the filler. It was also the one piece of ambient,
   unstoppable, large-area motion on the page — the kind that reads as vestibular
   discomfort rather than polish. The image holds still. The blurred filler
   behind it drifts instead, which reads as depth without moving the subject. */

/* ═══ MOBILE HERO ══════════════════════════════════════════════════════
   Below 1024px the hero is a single column and the photograph fills the frame
   behind it, so a fixed viewport height buys nothing — content defines it.
   (100svh minus a header is also a promise mobile browsers keep badly.) */
@media(max-width:1024px){
  .lux-home .hero{min-height:76svh;padding:clamp(28px,6vh,60px) 0 clamp(40px,8vh,72px)}
  .lux-home .hero-grid{grid-template-columns:minmax(0,1fr)}
}

/* 2026-08-06, owner: "i want it the way it looked 3 days before but with the
   current image, only for desktop." The 08-04 block that stood here locked the
   desktop hero to the photo's own 3:2 aspect so nothing was cropped — which
   also unpinned it from viewport height and turned a full-height frame into a
   short band. Removed. Desktop is back to the tall frame (min-height above),
   with `cover` + `object-position:50% 0%` taking the difference off the bottom
   of the current 3:2 campaign photo. Mobile is untouched: the max-width:768px
   block below still shows that poster whole. */

/* The portrait campaign has no honest text-safe area: both subjects and the
   burnt-in CUBANO lettering fill the frame. Phones therefore show the poster
   whole, followed by a separate ink panel for the copy and product deck. */
@media(max-width:768px){
  .lux-home .hero{display:block;min-height:0;padding:0;background:#0E0D11}
  .lux-home .hero-bg{position:relative;inset:auto;z-index:0;aspect-ratio:1122/1402;background:#0E0D11}
  .lux-home .hero-main{object-fit:cover;object-position:50% 50%;animation:none}
  .lux-home .hero-bg::after{content:none}
  .lux-home .hero-grid{
    z-index:1;grid-template-columns:minmax(0,1fr);gap:30px;
    max-width:none;margin:0;padding:36px var(--gut) 52px;
    border-top:1px solid rgba(246,242,234,.12);background:#0E0D11}
}


/* The sticky collection stack was removed 2026-07-28 on the owner's instruction
   ("I like the collections right now but the effect I don't like while I'm
   scrolling — remove it"). Each band used to pin under the header while the next
   slid over it. It reads well in a demo and badly in use: pinning takes the
   scroll away from the reader, and on a two-item list it bought a card trick in
   exchange for control. Bands now sit in normal flow. Do not reintroduce it. */

/* Light theme keeps the SAME cinematic hero. It used to add a paper haze at the
   top and a fade-to-paper at the bottom so the section dissolved into the page;
   the owner called that out directly ("remove the white thing... don't add any
   white color or effect from top or bottom"), and they were right — it fogged
   the photograph and made the one full-bleed image on the site look washed. The
   hero is now identical in both themes: the photo, a left scrim, a hard edge. */
[data-theme="light"] .lux-home .hero{background:#0E0D11}
[data-theme="light"] .lux-home .hero-main{opacity:1}
/* The eyebrow/timer used to be pinned to sun-gold here because light mode's
   --flame-1 was a darkened terracotta that died on the charcoal scrim. The
   palette is now one set across both themes, so the pins are gone with it. */

/* Mobile performance mode: native touch scrolling should not compete with
   permanent glow/card animations. Desktop keeps the full hero motion. */
@media (max-width:768px), (pointer:coarse){
  .lux-home .hero-deck::before{animation:none;filter:none}
  .lux-home .deck-card{animation:none;will-change:auto}
}
