/* =============================================================================
   MAKE MY NAILS — components, "Rose Atelier"
   Built on the tokens in core.css. Softer shapes than the previous build:
   pills, generous radii and warm plates. Sharp corners read masculine and
   that is precisely what was rejected.
   ============================================================================= */

/* ── LOADER ───────────────────────────────────────────────────────────
   Holds for the fonts. Bodoni is a high-contrast display face — if it
   swaps in after first paint the wordmark visibly re-flows and the page
   looks broken for a moment. */
.loader{
  position:fixed; inset:0; z-index:9500;
  background:var(--paper);
  display:grid; place-items:center;
  transition:clip-path 1.1s var(--e-out);
  clip-path:inset(0 0 0 0);
}
.loader.done{ clip-path:inset(0 0 100% 0); pointer-events:none; }
.loader__inner{ text-align:center; transition:opacity .45s var(--e-out); }
.loader.done .loader__inner{ opacity:0; }
.loader__mark{
  font-family:'Outfit',system-ui,sans-serif; font-weight:800;
  font-size:clamp(1.5rem,3.6vw,2.2rem); letter-spacing:-.03em;
  color:var(--magenta); margin-bottom:1.4rem;
}
.loader__bar{ width:min(46vw,280px); height:1px; background:var(--line-2); position:relative; overflow:hidden; margin-inline:auto; }
.loader__bar i{ position:absolute; inset:0; background:linear-gradient(90deg,var(--magenta),var(--purple)); transform:scaleX(0); transform-origin:0 50%; }
.loader__pct{ margin-top:.9rem; font-size:var(--t-micro); color:var(--text-4); font-variant-numeric:tabular-nums; letter-spacing:.2em; }

/* ── NAV ──────────────────────────────────────────────────────────── */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:800;
  border-bottom:1px solid transparent;
  transition:transform .55s var(--e-out), background .5s var(--e-out), border-color .5s var(--e-out);
}
.nav.solid{ background:rgba(255,255,255,.86); backdrop-filter:blur(16px) saturate(150%); border-bottom-color:var(--line); }
.nav.hide{ transform:translateY(-100%); }
.nav__in{ display:flex; align-items:center; justify-content:space-between; gap:var(--s-3); height:var(--nav-h); }
.nav__links{ display:flex; align-items:center; gap:var(--s-4); }
.nav__link{ font-size:var(--t-small); color:var(--text-2); position:relative; padding-block:.4em; transition:color var(--d-fast); }
.nav__link::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:linear-gradient(90deg,var(--magenta),var(--purple));
  transform:scaleX(0); transform-origin:100% 50%; transition:transform .45s var(--e-out);
}
.nav__link:hover{ color:var(--text); }
.nav__link:hover::after,.nav__link.active::after{ transform:scaleX(1); transform-origin:0 50%; }
.nav__right{ display:flex; align-items:center; gap:var(--s-2); }

.logo{ display:flex; align-items:center; gap:.7rem; }
.logo__mark{ width:34px; height:34px; flex:none; color:var(--magenta); }
.logo__txt{ font-family:'Outfit',system-ui,sans-serif; font-weight:700; font-size:1.02rem; letter-spacing:.04em; line-height:1; display:block; }
.logo__sub{ font-family:'Karla',sans-serif; font-size:.5rem; letter-spacing:.34em; color:var(--text-4); text-transform:uppercase; margin-top:.3em; display:block; }

.burger{ display:none; width:42px; height:42px; place-items:center; border:1px solid var(--line-2); border-radius:var(--r-pill); }
.burger i{ display:block; width:15px; height:1px; background:var(--text); position:relative; transition:background .2s; }
.burger i::before,.burger i::after{ content:""; position:absolute; left:0; width:15px; height:1px; background:var(--text); transition:transform .4s var(--e-out); }
.burger i::before{ top:-4.5px; } .burger i::after{ top:4.5px; }
.burger.on i{ background:transparent; }
.burger.on i::before{ transform:translateY(4.5px) rotate(45deg); }
.burger.on i::after{ transform:translateY(-4.5px) rotate(-45deg); }

.mob{
  position:fixed; inset:74px 0 auto; z-index:790;
  background:rgba(255,255,255,.98); backdrop-filter:blur(18px);
  border-bottom:1px solid var(--line);
  display:grid; gap:2px; padding:var(--s-3) var(--gutter) var(--s-4);
  clip-path:inset(0 0 100% 0); transition:clip-path .55s var(--e-out);
}
.mob.open{ clip-path:inset(0 0 0 0); }
.mob a{ padding:.85rem 0; border-bottom:1px solid var(--line); font-size:1.1rem; }

/* ── HERO ─────────────────────────────────────────────────────────── */
.hero{ position:relative; min-height:100svh; display:flex; flex-direction:column; justify-content:flex-end; overflow:hidden; padding-bottom:var(--s-5); }
.hero__canvas{ position:absolute; inset:0; width:100%; height:100%; z-index:0; opacity:.9; }
.hero::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:
    radial-gradient(120% 85% at 50% 8%, transparent 0%, rgba(255,255,255,.45) 58%, var(--paper) 100%),
    linear-gradient(180deg, rgba(255,255,255,.88) 0%, transparent 26%, transparent 58%, var(--paper) 100%);
}
.hero__in{ position:relative; z-index:2; width:100%; }
.hero__meta{ display:flex; justify-content:space-between; gap:var(--s-3); flex-wrap:wrap; padding-bottom:var(--s-4); }
.hero__word{ margin-bottom:var(--s-3); }
.hero__word span{ display:block; }
.hero__foot{ display:grid; grid-template-columns:1.1fr .9fr; gap:var(--s-5); align-items:end; padding-top:var(--s-4); border-top:1px solid var(--line); }
.hero__cta{ display:flex; gap:var(--s-2); flex-wrap:wrap; }
/* Search sits above the CTA row and shares the catalogue's .searchbar shell.
   Tighter padding on the left so the submit button can sit flush inside it. */
/* Doubled up as .searchbar.hero__search: .searchbar is defined 300-odd lines
   further down, so a single-class selector here loses on source order and the
   tighter padding silently never lands. */
.searchbar.hero__search{ margin-bottom:var(--s-2); padding:.45em .5em .45em 1.2em; }
.hero__search input{ min-width:0; }
.hero__search .btn{ flex:none; }

.scrollcue{ display:flex; align-items:center; gap:.7rem; }
.scrollcue__line{ width:52px; height:1px; background:var(--line-3); position:relative; overflow:hidden; }
.scrollcue__line::after{ content:""; position:absolute; inset:0; background:var(--magenta); animation:cue 2.4s var(--e-io) infinite; }
@keyframes cue{ 0%{transform:translateX(-100%)} 55%,100%{transform:translateX(100%)} }

/* ── MARQUEE ──────────────────────────────────────────────────────── */
.marq{ border-block:1px solid var(--line); padding-block:var(--s-3); overflow:hidden; position:relative; }
.marq__track{ display:flex; width:max-content; will-change:transform; }
.marq__set{ display:flex; align-items:center; gap:var(--s-5); padding-right:var(--s-5); }
.marq__item{ display:flex; align-items:baseline; gap:.7rem; white-space:nowrap; }
.marq__name{ font-family:'Outfit',system-ui,sans-serif; font-weight:700; font-size:clamp(1.1rem,2vw,1.6rem); letter-spacing:-.02em; color:var(--text-2); transition:color .3s; }
.marq__n{ font-size:var(--t-micro); color:var(--text-4); font-variant-numeric:tabular-nums; }
.marq:hover .marq__name{ color:var(--magenta); }
.marq::before,.marq::after{ content:""; position:absolute; top:0; bottom:0; width:clamp(40px,10vw,160px); z-index:2; pointer-events:none; }
.marq::before{ left:0; background:linear-gradient(90deg,var(--paper),transparent); }
.marq::after{ right:0; background:linear-gradient(270deg,var(--paper),transparent); }

/* ── MANIFESTO ────────────────────────────────────────────────────── */
.manifesto__body{
  font-family:'Outfit',system-ui,sans-serif; font-weight:600;
  font-size:clamp(1.6rem,3.4vw,2.9rem); line-height:1.24; letter-spacing:-.025em;
  max-width:20ch;
}
.manifesto__body em{ font-style:italic; color:var(--magenta); }
.w{ display:inline-block; opacity:.18; transition:opacity .5s var(--e-out); }
.w.lit{ opacity:1; }

.split{ display:grid; grid-template-columns:1fr 1fr; gap:var(--s-6); align-items:center; }

/* ── COUNTER GRID ─────────────────────────────────────────────────── */
.counters{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s-2) var(--s-2); }

/* ── COUNTER TILE ──────────────────────────────────────────────────────
   This was a white card holding a name and a number, seventeen of them,
   1,565px of the page. On a site whose entire product IS colour, a grid
   that shows no colour is the cheapest thing on the page — and it was the
   client's complaint, in as many words.

   Photograph on top, name underneath. Not text over the image: nearly every
   packshot here is shot on white or a pale tray, so white type laid over one
   disappears. The reference sites solve it the same way — the image is a
   plate, the label sits below it on paper. */
.counter{
  position:relative; display:flex; flex-direction:column;
  border:1px solid var(--line); border-radius:var(--r-lg);
  background:var(--paper);
  overflow:hidden; isolation:isolate;
  transition:border-color .5s var(--e-out), transform .5s var(--e-out), box-shadow .5s var(--e-out);
}
.counter__ph{
  position:relative; display:block; aspect-ratio:4/3; overflow:hidden;
  background:linear-gradient(165deg,var(--plate),var(--plate-2));
}
.counter__img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  transition:transform 1.1s var(--e-out);
}
.counter:hover .counter__img{ transform:scale(1.06); }
.counter__body{
  padding:var(--s-3) var(--s-3) var(--s-4);
  display:flex; flex-direction:column; gap:.3rem; flex:1;
}
.counter:hover{ border-color:var(--line-2); transform:translateY(-4px); box-shadow:var(--sh-2); }
.counter__n{
  position:absolute; top:.7rem; left:.8rem; z-index:2;
  font-size:var(--t-micro); color:var(--text-2); font-variant-numeric:tabular-nums; letter-spacing:.18em;
  background:rgba(255,255,255,.9); border-radius:var(--r-pill); padding:.15rem .5rem;
}
.counter__name{ font-family:'Outfit',system-ui,sans-serif; font-weight:700; font-size:clamp(1.02rem,1.5vw,1.28rem); line-height:1.12; letter-spacing:-.02em; }
.counter__blurb{ font-size:var(--t-small); color:var(--text-4); line-height:1.5; transition:color .4s; }
.counter:hover .counter__blurb{ color:var(--text-3); }
.counter__count{ font-size:var(--t-micro); color:var(--text-4); margin-top:.85rem; font-variant-numeric:tabular-nums; }
.counter__arrow{ position:absolute; top:.6rem; right:.7rem; z-index:2; opacity:0; transform:translate3d(-6px,6px,0); transition:all .45s var(--e-out); color:var(--magenta); }
.counter:hover .counter__arrow{ opacity:1; transform:none; }
.counter__vid{
  position:absolute; inset:0; z-index:1; width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity .55s var(--e-out);
  filter:saturate(1.05) brightness(1.02);
}
/* This was .18 — 2.2MB of footage downloaded to produce an 18%-strength
   wash behind opaque text, the worst bytes-to-perception ratio on the site.
   If the bytes are being spent the buyer should actually see the stock, so
   the clip now reads properly and a scrim carries the type instead. */
/* the clip now sits OVER the still inside the photo well, so it can play
   at full strength — it is showing the same shelf, not tinting a card */
.counter:hover .counter__vid{ opacity:1; }
.counter__vid + *, .counter > :not(.counter__vid){ position:relative; }
/* the old hover scrim existed to keep type readable over a tinted card.
   The type lives on paper below the photo now, so it is gone. */

/* ── PRODUCT CARD ─────────────────────────────────────────────────────
   Every packshot was photographed on white. On a wine ground a white JPEG
   reads as a mistake, so the image sits on a warm blush PLATE. The plate is
   slightly pink rather than pure white so it belongs to this palette rather
   than looking like a hole cut in the page. */
.pgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); gap:var(--s-3); }
.pcard{
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg);
  display:flex; flex-direction:column; position:relative; overflow:hidden;
  transition:border-color .45s var(--e-out), transform .45s var(--e-out);
}
.pcard:hover{ border-color:var(--line-2); transform:translateY(-3px); box-shadow:var(--sh-2); }
.pcard__plate{
  position:relative; aspect-ratio:1; overflow:hidden;
  background:linear-gradient(160deg,var(--plate) 0%,var(--plate-2) 100%);
}
.pcard__plate img{ width:100%; height:100%; object-fit:cover; transition:transform 1.2s var(--e-out), opacity .5s var(--e-out); }
.pcard__plate img.alt{ position:absolute; inset:0; opacity:0; }
.pcard:hover .pcard__plate img.main{ transform:scale(1.06); }
.pcard:hover .pcard__plate img.alt{ opacity:1; transform:scale(1.06); }
.pcard__plate video{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:0; transition:opacity .5s; }
.pcard:hover .pcard__plate video{ opacity:1; }
.pcard__ph{
  width:100%; height:100%;
  display:grid; place-items:center; gap:.6rem;
  background:linear-gradient(160deg,var(--plate),var(--plate-2));
  color:var(--magenta-dp);
  position:relative;
}
/* A handful of lines have no photograph yet. Rather than a bare icon on a
   dark hole, the card keeps the same blush plate as every other card and
   states plainly that the photo is coming — so a gap reads as pending
   rather than broken, and the grid stays even. */
.pcard__ph::after{
  content:"Photograph on the way";
  font-size:.6rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--magenta-dp); opacity:.75;
}
.pcard__ph svg{ opacity:.5; }
.pcard__body{ padding:var(--s-3); display:flex; flex-direction:column; gap:.4rem; flex:1; }
.pcard__brand{ font-size:var(--t-micro); letter-spacing:.18em; text-transform:uppercase; color:var(--text-4); }
.pcard__name{ font-family:'Karla',sans-serif; font-weight:600; font-size:.98rem; line-height:1.3; }
/* Clamped to three lines. The counter writes these by hand and they run to
   very different lengths; without the clamp a long one stretches its card and
   ragged row heights make the grid look broken. */
.pcard__desc{
  font-size:var(--t-micro); line-height:1.55; color:var(--text-3);
  display:-webkit-box; -webkit-line-clamp:3; line-clamp:3;
  -webkit-box-orient:vertical; overflow:hidden;
}
.pcard__pack{ font-size:var(--t-micro); color:var(--text-4); margin-top:auto; padding-top:.5rem; }
.pcard__foot{ display:flex; align-items:center; justify-content:space-between; gap:.5rem; padding:0 var(--s-3) var(--s-3); }
.pcard__rate{ font-size:var(--t-micro); letter-spacing:.1em; text-transform:uppercase; color:var(--text-4); }
.badge{ position:absolute; top:.7rem; left:.7rem; z-index:2; display:flex; gap:.3rem; flex-wrap:wrap; }
.badge span{
  font-size:.62rem; letter-spacing:.16em; text-transform:uppercase;
  padding:.34em .7em; background:rgba(255,255,255,.92); color:var(--magenta-dp);
  border:1px solid var(--line-2); border-radius:var(--r-pill); backdrop-filter:blur(4px);
}
.badge .limited{ color:var(--purple); border-color:var(--purple-lt); }
.addbtn{
  font-size:var(--t-micro); letter-spacing:.1em; text-transform:uppercase; font-weight:600;
  color:var(--text-2); border:1px solid var(--line-2); border-radius:var(--r-pill);
  padding:.42em .95em; transition:all .3s var(--e-out);
}
.addbtn:hover{ color:#fff; background:var(--magenta); border-color:var(--magenta); }
.addbtn.added{ color:#fff; background:var(--purple); border-color:var(--purple); }

/* ── AUTO-SCROLLING PRODUCT ROWS ──────────────────────────────────────
   The client asked for products that move on their own. Two rows running
   in OPPOSITE directions reads as designed; one row reads as a widget.
   Transform-only so it stays on the compositor, and it pauses whenever it
   is off screen, hovered or touched. */
.pscroll{ overflow:hidden; position:relative; padding-block:var(--s-1); }
.pscroll__track{ display:flex; gap:var(--s-3); width:max-content; will-change:transform; }
.pscroll__card{ flex:none; width:clamp(150px,20vw,230px); }
.pscroll__plate{
  aspect-ratio:1; border-radius:var(--r-lg); overflow:hidden;
  background:linear-gradient(160deg,var(--plate),var(--plate-2));
  border:1px solid var(--line);
}
.pscroll__plate img{ width:100%; height:100%; object-fit:cover; }
.pscroll__meta{ padding-top:.6rem; display:grid; gap:.15rem; }
.pscroll__brand{ font-size:.62rem; letter-spacing:.18em; text-transform:uppercase; color:var(--text-4); }
.pscroll__name{ font-size:.85rem; line-height:1.35; color:var(--text-2); }
.pscroll::before,.pscroll::after{ content:""; position:absolute; top:0; bottom:0; width:clamp(40px,8vw,140px); z-index:2; pointer-events:none; }
.pscroll::before{ left:0; background:linear-gradient(90deg,var(--paper),transparent); }
.pscroll::after{ right:0; background:linear-gradient(270deg,var(--paper),transparent); }

/* ── BRAND SCROLLER ───────────────────────────────────────────────────
   Stands where a testimonials block would normally go. This business has
   no reviews yet, and inventing them on a live trade site is not an
   option — so it shows what a wholesale buyer actually wants to know:
   which vendors are on the shelf and how deep each one goes. */
.bscroll{ display:grid; gap:var(--s-2); overflow:hidden; }
.bscroll__row{ overflow:hidden; position:relative; }
.bscroll__track{ display:flex; gap:var(--s-2); width:max-content; will-change:transform; }
.bcard{
  flex:none; display:flex; align-items:baseline; gap:1rem;
  padding:1.1rem 1.6rem; border:1px solid var(--line); border-radius:var(--r-pill);
  background:var(--surface); white-space:nowrap;
}
.bcard__name{ font-family:'Outfit',system-ui,sans-serif; font-weight:700; font-size:clamp(1rem,1.6vw,1.3rem); letter-spacing:-.02em; color:var(--text); }
.bcard__n{ font-size:var(--t-micro); color:var(--magenta); font-variant-numeric:tabular-nums; letter-spacing:.1em; }
.bcard__note{ font-size:var(--t-micro); color:var(--text-4); }
.bscroll::before,.bscroll::after{ content:""; position:absolute; top:0; bottom:0; width:clamp(40px,8vw,140px); z-index:2; pointer-events:none; }

/* ── PINNED HORIZONTAL RAIL ───────────────────────────────────────────
   Pinning needs a tall parent and a sticky child. If an ancestor ever gets
   overflow:hidden this silently stops working — see the body rule in core. */
.rail{ position:relative; }
.rail__stick{ position:sticky; top:0; height:100svh; display:flex; align-items:center; overflow:hidden; }
.rail__track{ display:flex; gap:var(--s-4); padding-inline:var(--gutter); will-change:transform; }
.rail__card{ flex:none; width:clamp(240px,30vw,400px); }
.rail__plate{ aspect-ratio:4/5; background:linear-gradient(160deg,var(--plate),var(--plate-2)); overflow:hidden; position:relative; border-radius:var(--r-lg); border:1px solid var(--line); }
.rail__plate img,.rail__plate video{ width:100%; height:100%; object-fit:cover; }
.rail__meta{ padding-top:var(--s-2); display:flex; justify-content:space-between; gap:1rem; align-items:baseline; }

/* ── VIDEO BAND ───────────────────────────────────────────────────────
   The footage is phone-shot, so it is GRADED rather than used raw:
   pushed warm and dark until it stops reading as a clip someone took in a
   shop and starts reading as texture. */
.vband{ position:relative; height:clamp(340px,62vh,640px); overflow:hidden; border-block:1px solid var(--line); }
.vband__v{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  filter:saturate(1.05) contrast(1.02) brightness(1.02);
  transform:scale(1.06);
}
.vband::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(180deg,var(--paper) 0%,rgba(255,255,255,.18) 20%,rgba(255,255,255,.3) 72%,var(--paper) 100%),
    radial-gradient(95% 75% at 30% 50%,transparent 0%,rgba(255,255,255,.55) 100%);
}
.vband__in{ position:relative; z-index:2; height:100%; display:flex; align-items:center; }
.vband__cap{ max-width:26ch; background:rgba(255,255,255,.86); backdrop-filter:blur(8px);
  padding:var(--s-4); border-radius:var(--r-lg); box-shadow:var(--sh-2); }

/* ── FIGURES ──────────────────────────────────────────────────────── */
.figs{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s-2); }
.fig{ background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg); padding:var(--s-4) var(--s-3); }
.fig__n{ font-family:'Outfit',system-ui,sans-serif; font-weight:800; font-size:clamp(2.2rem,5vw,3.8rem); line-height:1; letter-spacing:-.04em; font-variant-numeric:tabular-nums; color:var(--magenta); }
.fig__l{ font-size:var(--t-micro); letter-spacing:.18em; text-transform:uppercase; color:var(--text-4); margin-top:.6rem; }

/* ── TERMS ────────────────────────────────────────────────────────── */
.terms{ display:grid; grid-template-columns:repeat(3,1fr); gap:var(--s-2); }
.term{ background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg); padding:var(--s-4); display:flex; flex-direction:column; gap:.8rem; }
.term__n{ font-size:var(--t-micro); color:var(--magenta); font-variant-numeric:tabular-nums; letter-spacing:.18em; }

/* ── CONTACT ──────────────────────────────────────────────────────── */
.contact{ display:grid; grid-template-columns:1fr 1fr; gap:var(--s-6); }
.crow{ display:grid; grid-template-columns:auto 1fr; gap:var(--s-3); padding-block:var(--s-3); border-bottom:1px solid var(--line); align-items:baseline; }
.crow__k{ font-size:var(--t-micro); letter-spacing:.18em; text-transform:uppercase; color:var(--text-4); min-width:88px; }
.crow__v{ font-size:1.05rem; }
.crow__v a{ border-bottom:1px solid var(--line-3); transition:border-color .3s,color .3s; }
.crow__v a:hover{ border-color:var(--magenta); color:var(--magenta); }

/* ── FOOTER ───────────────────────────────────────────────────────── */
.foot{ border-top:1px solid var(--line); padding-block:var(--s-5) var(--s-4); }
.foot__grid{ display:grid; grid-template-columns:2fr 1fr 1fr; gap:var(--s-5); padding-bottom:var(--s-5); }
.foot__col h5{ font-size:var(--t-micro); letter-spacing:.18em; text-transform:uppercase; color:var(--text-4); margin-bottom:var(--s-2); font-weight:500; }
.foot__col a{ display:block; padding-block:.32rem; color:var(--text-2); font-size:var(--t-small); transition:color .3s; }
.foot__col a:hover{ color:var(--magenta); }
.foot__bar{ display:flex; justify-content:space-between; gap:var(--s-3); flex-wrap:wrap; padding-top:var(--s-3); border-top:1px solid var(--line); font-size:var(--t-micro); color:var(--text-4); }
.foot__mega{ overflow:hidden; padding-block:var(--s-4) 0; }
.foot__mega span{ display:block; font-family:'Outfit',system-ui,sans-serif; font-weight:800; font-size:clamp(2rem,9vw,8rem); line-height:.94; letter-spacing:-.045em; white-space:nowrap; }

/* ── ENQUIRY TRAY ─────────────────────────────────────────────────── */
.tray{
  position:fixed; right:var(--gutter); bottom:var(--gutter); z-index:820;
  display:flex; align-items:center; gap:.8rem;
  padding:.9rem 1.3rem;
  background:linear-gradient(100deg,var(--magenta),var(--purple));
  color:#fff;
  border-radius:var(--r-pill);
  /* ONE hidden transform for every width. It has to out-travel whatever the
     tray is offset by, and that offset differs per breakpoint — desktop rides
     on --gutter, a phone rides on the action bar plus the home-indicator
     inset. Summing all of them here means no breakpoint needs to restate this,
     which is exactly how the bar previously ended up stranded half on-screen:
     a media query moved `bottom` without moving the transform to match. */
  transform:translate3d(0,calc(100% + var(--gutter) + var(--abar-h) + var(--safe-b) + 1.5rem),0);
  /* visibility flips only AFTER the slide-out finishes, so hiding still
     animates instead of the bar blinking out of existence. */
  transition:transform .6s var(--e-out), visibility 0s linear .6s;
  box-shadow:0 18px 44px -14px rgba(0,0,0,.75);
  font-weight:600;
}
/* Not just moved off-screen — also inert, so a hidden tray can never swallow a
   tap meant for the action bar underneath it or get read out by a screen
   reader as if it were on the page. */
.tray{ pointer-events:none; visibility:hidden; }
.tray.up{ transform:none; pointer-events:auto; visibility:visible;
  transition:transform .6s var(--e-out), visibility 0s linear 0s; }
.tray__n{ min-width:23px; height:23px; display:grid; place-items:center; background:#fff; color:var(--magenta-dp); font-size:.72rem; border-radius:var(--r-pill); font-variant-numeric:tabular-nums; }
.tray__t{ font-size:var(--t-small); letter-spacing:.04em; }

/* ── TOAST ────────────────────────────────────────────────────────── */
.toast{ position:fixed; left:50%; bottom:calc(var(--gutter) + 4.8rem); transform:translate(-50%,20px); z-index:830; padding:.75rem 1.2rem; background:var(--purple); color:#fff; font-size:var(--t-small); font-weight:600; border-radius:var(--r-pill); opacity:0; pointer-events:none; transition:opacity .35s,transform .35s var(--e-out); }
.toast.on{ opacity:1; transform:translate(-50%,0); }

/* ── CURSOR — pointer devices only ────────────────────────────────── */
.cur{ position:fixed; top:0; left:0; width:8px; height:8px; border-radius:50%; background:var(--magenta); pointer-events:none; z-index:9100; transform:translate3d(-50%,-50%,0); transition:width .3s var(--e-out),height .3s var(--e-out),opacity .3s; }
.cur--ring{ width:36px; height:36px; background:transparent; border:1px solid var(--magenta); opacity:.4; }
.cur.big{ width:60px; height:60px; }
@media (hover:none),(pointer:coarse){ .cur{ display:none !important; } }

/* ── SCROLL PROGRESS ──────────────────────────────────────────────── */
.prog{ position:fixed; top:0; left:0; height:2px; background:linear-gradient(90deg,var(--magenta),var(--purple)); z-index:850; transform-origin:0 50%; transform:scaleX(0); width:100%; }

/* ── CATALOGUE ────────────────────────────────────────────────────── */
/* The filter bar is OPAQUE, not translucent. It used to be a blurred glass
   panel, but a blur still lets high-contrast product photos read through it,
   so cards appeared to swim behind the chips as you scrolled and the bar
   looked like it was flickering. A solid ground with a soft shadow reads as
   a layer instead of a smear, and it costs less to composite on a phone. */
/* Sticks BELOW the fixed 74px nav, not behind it. At top:0 this bar slid under
   the header, and the search field — its first child — was the exact strip that
   got covered, so on a phone the catalogue looked like it had no search at all
   while the chip rows underneath stayed visible. */
.filters{
  position:sticky; top:var(--nav-h); z-index:600;
  background:var(--paper);
  border-bottom:1px solid var(--line);
  box-shadow:0 6px 20px -12px rgba(110,37,133,.28);
  padding-block:var(--s-2);
}
/* ...and rides back up to the top edge while the nav is away, so scrolling down
   never opens a bare strip of product cards above the bar. */
.nav.hide ~ main .filters{ top:0; }
.chips{ display:flex; gap:.4rem; overflow-x:auto; padding-bottom:.3rem; scrollbar-width:none; }
.chips::-webkit-scrollbar{ display:none; }
.chip{ flex:none; padding:.55em 1.05em; border:1px solid var(--line-2); border-radius:var(--r-pill); font-size:var(--t-micro); letter-spacing:.09em; text-transform:uppercase; color:var(--text-3); white-space:nowrap; transition:all .3s var(--e-out); }
.chip:hover{ color:var(--text); border-color:var(--line-3); }
.chip.on{ background:linear-gradient(100deg,var(--magenta),var(--purple)); color:#fff; border-color:transparent; font-weight:600; }
.searchbar{ position:relative; display:flex; align-items:center; gap:.75rem; border:1px solid var(--line-2); border-radius:var(--r-pill); padding:.8em 1.2em; background:var(--surface); }

/* ── SEARCH SUGGEST ───────────────────────────────────────────────────
   Anchored to .searchbar, so it lines up under either search field without
   either page needing its own rule. Sits above the sticky filter bar (600)
   but below the nav (800) — it should never cover the way out. */
.sug{
  position:absolute; top:calc(100% + .55rem); left:0; right:0; z-index:700;
  background:var(--paper); border:1px solid var(--line-2);
  border-radius:var(--r-lg); box-shadow:var(--sh-2);
  max-height:min(60vh,26rem); overflow-y:auto; overscroll-behavior:contain;
  display:none;
}
.sug.on{ display:block; }
/* .filters carries z-index:600, which makes it a stacking context — nothing
   inside it can ever paint above the tray (820) no matter what z-index we give
   the panel. So while the list is open the tray steps aside instead. */
.sug-open .tray, .sug-open .abar{ opacity:0; pointer-events:none; }
.sug__row{ display:flex; align-items:center; gap:.8rem; padding:.55rem .7rem; }
.sug__row + .sug__row{ border-top:1px solid var(--line); }
.sug__row:hover, .sug__row.active{ background:var(--surface); }
.sug__thumb{
  flex:none; width:46px; height:46px; border-radius:var(--r-md);
  overflow:hidden; background:var(--surface); display:grid; place-items:center;
}
.sug__thumb img{ width:100%; height:100%; object-fit:cover; }
.sug__noimg{ width:16px; height:16px; border-radius:50%; border:1px solid var(--line-3); }
/* min-width:0 or the ellipsis never kicks in — a flex child defaults to
   min-content width and simply pushes the row wider instead of truncating. */
.sug__txt{ min-width:0; display:flex; flex-direction:column; gap:.15rem; }
.sug__name{
  font-size:var(--t-small); font-weight:600; line-height:1.25;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.sug__meta{
  font-size:var(--t-micro); color:var(--text-4);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.searchbar input{ flex:1; border:none; background:none; outline:none; font-size:var(--t-small); }
.searchbar input::placeholder{ color:var(--text-4); }

/* ── RESPONSIVE ───────────────────────────────────────────────────── */
@media (max-width:1100px){
  .counters{ grid-template-columns:repeat(3,1fr); }
  .kits{ grid-template-columns:repeat(2,1fr); }
  .figs{ grid-template-columns:repeat(2,1fr); }
  .foot__grid{ grid-template-columns:1fr 1fr; }
}
@media (max-width:860px){
  .nav__links{ display:none; }
  .burger{ display:grid; }
  .hero__foot{ grid-template-columns:1fr; gap:var(--s-4); }
  .split{ grid-template-columns:1fr; gap:var(--s-4); }
  .counters{ grid-template-columns:repeat(2,1fr); }
  .counter{ min-height:168px; padding:var(--s-3); }
  .terms{ grid-template-columns:1fr; }
  .contact{ grid-template-columns:1fr; gap:var(--s-4); }
  .pgrid{ grid-template-columns:repeat(2,1fr); }
  .rail__stick{ height:auto; position:static; padding-block:var(--s-3); }
  .rail__track{ overflow-x:auto; scroll-snap-type:x mandatory; padding-bottom:var(--s-2); }
  .rail__card{ scroll-snap-align:start; }
}
@media (max-width:560px){
  /* NOT 1fr. With a photograph in every tile, one column is 19 stacked
     images — 8,558px measured, ten screens of nothing but this grid. Two
     columns halves it and is what every mobile storefront actually does. */
  .counters{ grid-template-columns:repeat(2,1fr); gap:var(--s-1); }
  .kits{ grid-template-columns:repeat(2,1fr); gap:var(--s-1); }
  .counter__body{ padding:var(--s-2) var(--s-2) var(--s-3); }
  .counter__blurb{ display:none; }
  .counter__name{ font-size:.95rem; }
  .figs{ grid-template-columns:repeat(2,1fr); }
  .foot__grid{ grid-template-columns:1fr; gap:var(--s-4); }
  .hero__meta{ display:none; }
  /* At two columns on a 390px phone the card is ~180px wide and
     "RATE ON REQUEST" broke onto two lines, which pushed the ADD control
     out of alignment across the grid. */
  .pcard__rate{ white-space:nowrap; font-size:.66rem; letter-spacing:.06em; }
  .pcard__foot{ gap:.4rem; }
  .addbtn{ white-space:nowrap; }
}

/* On a 390px phone the wordmark wrapped to two lines and pushed the nav
   out of alignment. Keep it on one line and step the size down instead. */
@media (max-width:560px){
  .logo__txt{ white-space:nowrap; font-size:.95rem; }
  .logo__mark{ width:28px; height:28px; }
  .logo__sub{ font-size:.44rem; letter-spacing:.3em; }
}

/* ── STARTER KITS ─────────────────────────────────────────────────────
   Three cards, the middle one lifted. The feature card is raised by a
   warm surface and a rose hairline rather than by scale, so the row
   still reads as one set. */
.kits{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s-2); align-items:stretch; }
/* ── KIT CARD ──────────────────────────────────────────────────────────
   These were four white cards with a price and nothing else. A buyer
   spending Rs 9,999 on a boxed kit wants to see what is IN the box, and
   the client had already filmed exactly that — so each card now opens on
   its own footage and the copy sits underneath. */
.kit{
  display:flex; flex-direction:column; gap:.8rem;
  padding:0 var(--s-3) var(--s-3);
  overflow:hidden;
  border:1px solid var(--line); border-radius:var(--r-lg);
  background:var(--surface);
  transition:border-color .5s var(--e-out), transform .5s var(--e-out);
}
.kit:hover{ border-color:var(--line-2); transform:translateY(-4px); box-shadow:var(--sh-2); }
.kit__ph{
  position:relative; display:block; margin:0 calc(var(--s-3) * -1) var(--s-2);
  aspect-ratio:4/3; overflow:hidden;
  background:linear-gradient(165deg,var(--plate),var(--plate-2));
}
.kit__m{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.kit__v{ opacity:0; transition:opacity .6s var(--e-out); z-index:1; }
.kit__v.ready{ opacity:1; }
.kit__ask{ font-size:var(--t-small); font-weight:600; color:var(--magenta-dp); letter-spacing:.02em; }
.kit--student{ border-color:var(--line-2); }
.kit--feature{
  background:linear-gradient(170deg,var(--surface-3),var(--surface-2));
  border-color:rgba(233,167,174,.32);
}
.kit__top{ display:flex; align-items:center; justify-content:space-between; gap:1rem; }
.kit__n{ font-size:var(--t-micro); color:var(--text-4); letter-spacing:.2em; font-variant-numeric:tabular-nums; }
.kit__tag{
  font-size:.62rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--magenta); border:1px solid rgba(233,167,174,.3);
  border-radius:var(--r-pill); padding:.3em .8em;
}
.kit__name{ font-family:'Outfit',system-ui,sans-serif; font-weight:700; font-size:clamp(1.25rem,2vw,1.6rem); line-height:1.12; letter-spacing:-.02em; }
.kit__desc{ font-size:var(--t-small); color:var(--text-3); line-height:1.6; flex:1; }
.kit__price{
  font-family:'Outfit',system-ui,sans-serif; font-size:clamp(1.8rem,3vw,2.4rem);
  color:var(--magenta); font-variant-numeric:tabular-nums; padding-block:.3rem;
  border-top:1px solid var(--line); margin-top:.4rem;
}

/* ── ACADEMY ──────────────────────────────────────────────────────── */
.acad{ display:grid; grid-template-columns:1.05fr .95fr; gap:var(--s-6); align-items:start; }
.acad__meta{ display:flex; flex-wrap:wrap; gap:var(--s-4); margin-top:var(--s-4); padding-top:var(--s-3); border-top:1px solid var(--line); }
.acad__meta div{ display:flex; flex-direction:column; gap:.25rem; }
.acad__meta b{ font-family:'Outfit',system-ui,sans-serif; font-size:1.35rem; color:var(--text); font-weight:400; }
.acad__cta{ margin-top:var(--s-4); }
.acad__list{ list-style:none; display:grid; gap:0; }
.acad__list li{
  display:flex; align-items:baseline; gap:1rem;
  padding:.9rem 0; border-bottom:1px solid var(--line);
  font-size:1.02rem; color:var(--text-2);
  transition:color .4s var(--e-out), padding-left .4s var(--e-out);
}
.acad__list li::before{
  content:""; flex:none; width:5px; height:5px; border-radius:50%;
  background:var(--magenta); opacity:.5; transition:opacity .4s, transform .4s var(--e-out);
}
.acad__list li:hover{ color:var(--text); padding-left:.5rem; }
.acad__list li:hover::before{ opacity:1; transform:scale(1.6); }

/* ── STUDIO SERVICES ──────────────────────────────────────────────── */
.svcs{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s-2); }
.svc{
  display:flex; flex-direction:column; gap:.5rem;
  padding:var(--s-3) var(--s-3) var(--s-4);
  border:1px solid var(--line); border-radius:var(--r-lg);
  background:var(--surface);
  transition:border-color .45s var(--e-out);
}
.svc:hover{ border-color:var(--line-3); }
.svc__name{ font-size:var(--t-small); color:var(--text-3); letter-spacing:.05em; }
.svc__p{ font-family:'Outfit',system-ui,sans-serif; font-size:clamp(1.3rem,2.2vw,1.8rem); color:var(--magenta); }

@media (max-width:980px){
  .acad{ grid-template-columns:1fr; gap:var(--s-4); }
  .svcs{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:760px){
  .kits{ grid-template-columns:1fr; }
}

/* ── COUNTER LIST ─────────────────────────────────────────────────────
   Requested by the client to match the sister site. A scannable index:
   name, count, arrow. Rows grow a magenta rule on hover rather than a
   background fill — a filled row at this width reads as a button. */
.clist{ border-top:1px solid var(--line); }
.clist__row{
  display:grid; grid-template-columns:1fr auto auto; gap:1.2rem; align-items:center;
  padding:1.15rem .4rem; border-bottom:1px solid var(--line);
  position:relative; transition:padding-left .4s var(--e-out);
}
.clist__row::after{
  content:""; position:absolute; left:0; right:0; bottom:-1px; height:1px;
  background:var(--magenta); transform:scaleX(0); transform-origin:0 50%;
  transition:transform .5s var(--e-out);
}
.clist__row:hover{ padding-left:1rem; }
.clist__row:hover::after{ transform:scaleX(1); }
.clist__name{
  font-family:'Karla',sans-serif; font-size:clamp(.92rem,1.5vw,1.05rem);
  font-weight:500; letter-spacing:.13em; text-transform:uppercase;
  transition:color .35s;
}
.clist__row:hover .clist__name{ color:var(--magenta-dp); }
.clist__n{ font-size:var(--t-small); color:var(--text-3); font-variant-numeric:tabular-nums; }
.clist__a{ color:var(--magenta); transition:transform .4s var(--e-out); }
.clist__row:hover .clist__a{ transform:translateX(5px); }

/* ── FOOTER CREDIT ────────────────────────────────────────────────── */
.foot__by a{ color:var(--magenta-dp); border-bottom:1px solid var(--line-2); transition:border-color .3s; }
.foot__by a:hover{ border-color:var(--magenta); }

/* ── MOBILE ACTION BAR ────────────────────────────────────────────── */
.abar{ display:none; }
@media (max-width:860px){
  /* ONE dock, not two things fighting for the same corner. Nearly all of this
     shop's traffic is a phone, so the bottom of the screen is the conversion
     surface: it is safe-area aware for the iPhone home indicator, every target
     clears the 48px minimum, and nothing floats on top of anything else. */
  /* The dock only exists below this width, so this is the only place --abar-h
     is non-zero. Everything docked to the bottom follows from it. */
  :root{ --abar-h:58px; }

  .abar{
    position:fixed; left:0; right:0; bottom:0; z-index:810;
    display:grid; grid-template-columns:1fr 1fr;
    background:var(--paper);
    border-top:1px solid var(--line-2);
    box-shadow:0 -8px 26px -14px rgba(110,37,133,.3);
    padding-bottom:var(--safe-b);
  }
  .abar__b{
    display:flex; align-items:center; justify-content:center; gap:.55rem;
    min-height:var(--abar-h);
    padding:.9rem .5rem; font-size:var(--t-small); font-weight:600;
    letter-spacing:.08em; text-transform:uppercase;
    -webkit-tap-highlight-color:transparent;
    transition:filter .2s var(--e-out);
  }
  .abar__b:active{ filter:brightness(.92); }
  .abar__b--wa{ background:#128C7E; color:#fff; }
  .abar__b--enq{ background:#fff; color:var(--purple); border-left:1px solid var(--line-2); }

  /* The enquiry tray becomes a full-width shelf resting ON the dock instead of
     a pill floating over it.

     The old hidden transform was calc(100% + gutter + 1.5rem) — sized for the
     desktop offset of `bottom:var(--gutter)`. This block used to push `bottom`
     2.1rem higher than that, so the "hidden" tray never actually left the
     screen: it sat permanently peeking over the action bar reading "0 Send
     enquiry". Anchoring the slide to its own height (101%) and dropping it
     behind the dock makes the hidden state independent of the offset. */
  .tray{
    left:0; right:0; z-index:805;
    /* Flush to the bottom by default — the catalogue has no action bar, so an
       offset there would leave the shelf hovering over a strip of nothing. */
    bottom:0;
    justify-content:center; gap:.6rem;
    border-radius:0; min-height:52px;
    padding:1rem 1.3rem calc(1rem + var(--safe-b));
    box-shadow:0 -10px 30px -16px rgba(28,10,26,.5);
  }
  /* Only the pages that actually carry the dock lift the shelf above it.
     Set from JS rather than :has() so it holds on older mobile Safari too. */
  .has-abar .tray{
    bottom:calc(var(--abar-h) + var(--safe-b));
    padding-bottom:1rem;
  }
  .toast{ bottom:calc(var(--abar-h) + var(--safe-b) + 4.5rem); }
  body{ padding-bottom:calc(var(--abar-h) + var(--safe-b)); }
}

/* ── MODAL ────────────────────────────────────────────────────────── */
.modal{ position:fixed; inset:0; z-index:9200; display:grid; place-items:center; padding:var(--gutter); }
.modal[hidden]{ display:none; }
.modal__scrim{ position:absolute; inset:0; background:rgba(28,10,26,.5); backdrop-filter:blur(6px); animation:fadeIn .3s var(--e-out); }
.modal__panel{
  position:relative; z-index:1;
  width:min(760px,100%); max-height:88svh; overflow-y:auto;
  background:var(--paper); border-radius:var(--r-lg);
  padding:clamp(1.4rem,4vw,2.6rem);
  box-shadow:0 30px 80px -20px rgba(28,10,26,.4);
  animation:panelUp .45s var(--e-out);
}
@keyframes fadeIn{ from{opacity:0} to{opacity:1} }
@keyframes panelUp{ from{opacity:0; transform:translateY(20px) scale(.985)} to{opacity:1; transform:none} }
.modal__x{ position:absolute; top:.7rem; right:1rem; font-size:1.9rem; line-height:1; color:var(--text-3); transition:color .3s; }
.modal__x:hover{ color:var(--magenta); }
.modal__h{ margin:.35rem 0 var(--s-4); }

.bgrid{ display:grid; gap:var(--s-3); }
.bgroup{ border-top:1px solid var(--line); padding-top:.9rem; }
.bgroup h4{
  font-size:var(--t-micro); letter-spacing:.2em; text-transform:uppercase;
  color:var(--magenta-dp); margin-bottom:.4rem;
}
.bgroup p{ color:var(--text-2); line-height:1.75; font-size:.97rem; }

.pform{ margin-top:var(--s-4); padding-top:var(--s-3); border-top:1px solid var(--line); }
.pform label{ display:block; font-size:var(--t-small); color:var(--text-2); margin-bottom:.6rem; }
.pform__row{ display:flex; gap:.5rem; align-items:stretch; flex-wrap:wrap; }
.pform__cc{
  display:grid; place-items:center; padding:0 .9rem;
  border:1px solid var(--line-2); border-radius:var(--r-pill);
  font-size:var(--t-small); color:var(--text-3); background:var(--surface);
}
.pform input{
  flex:1; min-width:150px; padding:.8em 1.2em;
  border:1px solid var(--line-2); border-radius:var(--r-pill);
  background:var(--surface); outline:none;
}
.pform input:focus{ border-color:var(--magenta); }
.pform__note{ font-size:var(--t-micro); color:var(--text-3); margin-top:.6rem; }
.pform.sent .pform__row{ display:none; }

/* ── IMAGE ZOOM ───────────────────────────────────────────────────── */
.zoom{ position:fixed; inset:0; z-index:9300; display:grid; place-items:center; gap:1rem;
  background:rgba(28,10,26,.9); backdrop-filter:blur(8px); padding:var(--gutter); animation:fadeIn .3s var(--e-out); }
.zoom[hidden]{ display:none; }
.zoom__img{ max-width:min(1000px,92vw); max-height:78svh; object-fit:contain; border-radius:var(--r-md); background:var(--plate); animation:panelUp .4s var(--e-out); }
.zoom__cap{ color:#fff; font-size:var(--t-small); letter-spacing:.06em; text-align:center; }
.zoom__x{ position:absolute; top:1rem; right:1.4rem; font-size:2.2rem; line-height:1; color:#fff; opacity:.8; }
.zoom__x:hover{ opacity:1; }
/* the plate is now a control, so say so */
.pcard__plate{ cursor:zoom-in; }

/* ── COUNTER LIST THUMBNAILS ──────────────────────────────────────────
   The client's note was blunt and right: a list of names with no pictures
   is a table of contents, not a shop. */
.clist__row{ grid-template-columns:auto 1fr auto auto; }
.clist__thumb{
  width:56px; height:56px; flex:none; border-radius:var(--r-md);
  overflow:hidden; background:linear-gradient(160deg,var(--plate),var(--plate-2));
  border:1px solid var(--line);
}
.clist__thumb img{ width:100%; height:100%; object-fit:cover; transition:transform .6s var(--e-out); }
.clist__row:hover .clist__thumb img{ transform:scale(1.09); }

/* ── MOBILE DRAWER — the full counter list, as on the sister site ─── */
.mob{ max-height:calc(100svh - var(--nav-h)); overflow-y:auto; }
.mob__brands{
  text-align:left; padding:.85rem 0; border-bottom:1px solid var(--line);
  font-size:1.05rem; color:var(--magenta-dp); font-weight:600;
}
.mob__label{
  display:block; margin-top:var(--s-3); padding-bottom:.5rem;
  font-size:var(--t-micro); letter-spacing:.22em; text-transform:uppercase; color:var(--text-3);
}
.mob__cats{ display:grid; gap:1px; background:var(--line); border-block:1px solid var(--line); }
.mcat{
  display:grid; grid-template-columns:auto 1fr auto; gap:.85rem; align-items:center;
  background:var(--paper); padding:.6rem .2rem;
}
.mcat__t{ width:42px; height:42px; border-radius:var(--r-sm); overflow:hidden;
  background:linear-gradient(160deg,var(--plate),var(--plate-2)); flex:none; }
.mcat__t img{ width:100%; height:100%; object-fit:cover; }
.mcat__n{ font-size:.92rem; letter-spacing:.06em; text-transform:uppercase; font-weight:500; }
.mcat__c{ font-size:var(--t-micro); color:var(--text-3); font-variant-numeric:tabular-nums; }

@media (max-width:560px){
  .clist__thumb{ width:44px; height:44px; }
  .clist__row{ gap:.8rem; padding:.85rem .2rem; }
  .clist__name{ font-size:.82rem; letter-spacing:.1em; }
}

/* ── INSTAGRAM ────────────────────────────────────────────────────────
   The client asked for Instagram to be reachable. It sits in the nav, the
   contact block and the footer — the three places people look for it. */
.ig-btn{
  display:inline-flex; align-items:center; justify-content:center;
  width:40px; height:40px; border-radius:var(--r-pill);
  border:1px solid var(--line-2); color:var(--magenta-dp);
  transition:all .35s var(--e-out); flex:none;
}
.ig-btn:hover{ color:#fff; border-color:transparent; background:linear-gradient(135deg,#F9A03F,#E5177F 45%,#6E2585); }
@media (max-width:860px){ .nav__right .ig-btn{ display:none; } }

/* ══════════════════════════════════════════════════════════════════════
   MOTION LAYER — added after the client asked for video animation
   ----------------------------------------------------------------------
   Every video on this page obeys the same three rules, because the buyers
   here are salon owners on mid-range Android phones on 4G:

     1. NOTHING downloads until it is near the viewport. Every <video> ships
        with preload="none" and no src at all — the src is attached by JS.
     2. A poster JPEG always carries the frame. If the video never loads,
        never plays, or autoplay is refused, the section still looks
        finished rather than showing a black hole.
     3. Reduced-motion, Save-Data and 2g/3g get the poster and NO video
        request is ever made.

   Footage is the client's own, from his channel. Every clip was reviewed
   frame by frame and cropped before use — the source reels carry a burned-in
   watermark naming the other shop, and several were rejected outright.
   ══════════════════════════════════════════════════════════════════════ */

/* ── THE REEL RAIL ─────────────────────────────────────────────────────
   A drifting strip of counter footage. This is the section that answers
   "is this a real supplier or a stock-photo website" faster than any
   paragraph can, which is why it sits directly under the hero. */
.reel{ position:relative; padding-block:var(--s-6); overflow:hidden; }
.reel__head{ display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--s-3); margin-bottom:var(--s-4); }
.reel__vp{ overflow:hidden; -webkit-mask-image:linear-gradient(90deg,transparent,#000 4%,#000 96%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 4%,#000 96%,transparent); }
.reel__track{ display:flex; gap:var(--s-2); width:max-content; will-change:transform; }

.rc{
  position:relative; flex:0 0 auto;
  width:clamp(158px,21vw,244px); aspect-ratio:4/5;
  border-radius:var(--r-lg); overflow:hidden;
  background:var(--plate-2);
  border:1px solid var(--line);
  box-shadow:var(--sh-1);
  transition:transform .55s var(--e-out), box-shadow .55s var(--e-out);
}
.rc__m{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
/* the video sits ON the poster and fades in once it actually has frames,
   so there is never a flash of black between poster and first paint */
.rc__v{ opacity:0; transition:opacity .5s var(--e-out); }
.rc__v.ready{ opacity:1; }
.rc__cap{
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  padding:2.6rem var(--s-2) var(--s-2);
  font-size:var(--t-micro); font-weight:600; letter-spacing:.14em;
  text-transform:uppercase; color:#fff;
  background:linear-gradient(180deg,transparent,rgba(28,10,26,.72));
  transform:translateY(8px); opacity:.92;
  transition:transform .5s var(--e-out), opacity .5s var(--e-out);
}
@media (hover:hover){
  .rc:hover{ transform:translateY(-6px); box-shadow:var(--sh-2); }
  .rc:hover .rc__cap{ transform:none; opacity:1; }
}
/* the live dot is the only thing on the page that loops forever — it is
   1 element and it animates opacity only */
.reel__live{ display:inline-flex; align-items:center; gap:.5rem; }
.reel__live::before{
  content:""; width:7px; height:7px; border-radius:50%;
  background:var(--magenta); animation:reelpulse 2s var(--e-io) infinite;
}
@keyframes reelpulse{ 0%,100%{ opacity:1; transform:scale(1) } 50%{ opacity:.35; transform:scale(.8) } }

/* ── HERO WORDMARK, FILLED WITH FOOTAGE ────────────────────────────────
   Desktop only, and strictly an upgrade on top of the gradient wordmark
   that is already there. `mix-blend-mode:lighten` over a white plate keeps
   the white opaque and lets the footage through the black glyphs only.
   It is a real compositing cost, which is why a phone never gets it —
   a phone gets the reel rail instead, which is worth more on a small
   screen anyway. If ANY of the guards fail, .hero__word simply stays as
   it was and nothing is lost. */
.hero__vwrap{ position:relative; isolation:isolate; }
/* Only while the fill is live: shrink the wrapper to the type itself, so the
   plate that `lighten` needs is the size of the wordmark and not a panel
   stretched across the hero. */
.hero__vwrap.vlive{ width:fit-content; max-width:100%; }
.hero__vfill{
  position:absolute; inset:0; z-index:0; overflow:hidden;
  border-radius:var(--r-md); background:#000;
  opacity:0; transition:opacity 1.2s var(--e-out);
}
.hero__vwrap.vlive .hero__vfill{ opacity:1; }
.hero__vfill video{ width:100%; height:100%; object-fit:cover;
  filter:saturate(1.25) contrast(1.1); transform:scale(1.04); }

/* The brand gradient, multiplied straight onto the footage.
   This does two jobs at once, and the second one is structural:
     · the wordmark keeps the poster's magenta-into-purple instead of
       turning the grey of whatever happened to be filmed that day;
     · multiply GUARANTEES the footage is darker than the plate behind
       the type. Without it, any bright frame — a white glove, a lit
       tray — is lighter than the plate and `lighten` lets it bleed
       out of the glyphs and flood the whole hero block. */
.hero__vfill::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(100deg,var(--purple) 0%,var(--magenta) 46%,var(--purple-dp) 100%);
  mix-blend-mode:multiply;
}
.hero__vwrap.vlive .hero__word{
  position:relative; z-index:1;
  /* --surface, not #fff: the hero sits on a soft pink wash, and a pure
     white plate reads as a white box floating on top of it */
  background:var(--surface); color:#000;
  mix-blend-mode:lighten;
}
/* the gradient fill and the video fill are mutually exclusive — leaving
   -webkit-text-fill-color:transparent on would knock the glyphs out
   entirely and the mask would show nothing */
.hero__vwrap.vlive .hero__word .chrome{
  background:none; color:#000; -webkit-text-fill-color:#000;
}

/* ── COUNTER TILES ON TOUCH ────────────────────────────────────────────
   The tiles have had hover video since the first build, which a phone can
   never trigger. On touch the tile that is centred in the viewport plays
   instead — one at a time, never all of them. */
.ctile__v{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity .6s var(--e-out); z-index:1;
}
.counter.playing .ctile__v{ opacity:1; }

@media (max-width:720px){
  .rc{ width:clamp(140px,44vw,180px); }
  .reel{ padding-block:var(--s-5); }
}

@media (prefers-reduced-motion:reduce){
  .reel__track{ transform:none !important; }
  .reel__live::before{ animation:none; }
  .hero__vwrap.vlive .hero__word{ mix-blend-mode:normal; background:none; }
  .hero__vfill{ display:none; }
}

/* ══════════════════════════════════════════════════════════════════════
   THE SHADE BOOK — the hero's centrepiece
   ----------------------------------------------------------------------
   The client sent the new 27-shade book and asked for it in the hero. It
   sits top-right because the hero's whole upper half was empty gradient,
   and because a salon owner deciding whether to open a trade account wants
   to see COLOUR before she reads a line of copy.

   The source card is printed with the OTHER shop's name across its head,
   so the clip is cropped to the swatch grid alone and trimmed to the
   window before the camera drifts — past ~2.5s the printed name comes
   back into frame. See the note in the handover.
   ══════════════════════════════════════════════════════════════════════ */
.shadecard{
  position:absolute; z-index:3;
  top:clamp(76px,13vh,168px); right:var(--gutter);
  width:clamp(132px,25vw,352px);
  /* the whole panel drifts on scroll — one transform, written by the
     shared frame loop, never a layout property */
  will-change:transform;
}
.shadecard__frame{
  position:relative; aspect-ratio:620/514; overflow:hidden;
  border-radius:var(--r-lg);
  background:var(--plate-2);
  border:1px solid rgba(255,255,255,.9);
  box-shadow:
    0 2px 8px rgba(110,37,133,.10),
    0 22px 48px -18px rgba(110,37,133,.34),
    0 60px 90px -60px rgba(28,10,26,.35);
  /* a real bevel: the card should read as an object sitting above the
     page, not a rectangle printed on it */
  transform:rotate(-1.6deg);
  transition:transform 1.1s var(--e-out);
}
.shadecard__m{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.shadecard__v{ opacity:0; transition:opacity .7s var(--e-out); }
.shadecard__v.ready{ opacity:1; }
/* a single slow specular pass — this is what makes a flat packshot read as
   something under a light rather than a JPEG */
.shadecard__sheen{
  position:absolute; inset:-30%; pointer-events:none;
  background:linear-gradient(104deg,transparent 38%,rgba(255,255,255,.52) 48%,transparent 58%);
  transform:translate3d(-60%,0,0);
  animation:sheenpass 7s var(--e-io) 2.2s infinite;
}
@keyframes sheenpass{ 0%{transform:translate3d(-60%,0,0)} 26%,100%{transform:translate3d(70%,0,0)} }

.shadecard__chip{
  position:absolute; left:-10%; bottom:-9%;
  display:flex; align-items:center; gap:.55rem;
  padding:.55rem .85rem .55rem .6rem;
  background:var(--paper); border:1px solid var(--line);
  border-radius:var(--r-pill); box-shadow:var(--sh-2);
}
.shadecard__n{
  font-family:'Outfit',system-ui,sans-serif; font-weight:800;
  font-size:clamp(1.1rem,2.4vw,1.9rem); line-height:1;
  letter-spacing:-.04em; color:var(--magenta); font-variant-numeric:tabular-nums;
}
.shadecard__t{ font-size:.58rem; line-height:1.25; letter-spacing:.1em;
  text-transform:uppercase; color:var(--text-3); }
.shadecard__spec{
  position:absolute; top:-1.6rem; right:.2rem;
  font-size:var(--t-micro); letter-spacing:.18em; text-transform:uppercase;
  color:var(--magenta-dp); white-space:nowrap;
}

/* Entrance: the card lifts in rather than fading, so it arrives as an object
   with weight. The LIFT is on the inner frame and the OPACITY on the outer,
   because the outer element's transform belongs to the scroll drift — if both
   wrote to it the frame loop would overwrite the entrance on its first tick
   and the animation would never be seen. */
.js .shadecard{ opacity:0; }
.js .shadecard.in{ opacity:1; transition:opacity 1s var(--e-out); }
.js .shadecard .shadecard__frame{ transform:rotate(-1.6deg) translate3d(0,28px,0); }
.js .shadecard.in .shadecard__frame{ transform:rotate(-1.6deg); }
.js .shadecard .shadecard__chip,
.js .shadecard .shadecard__spec{ opacity:0; transition:opacity .8s var(--e-out) .35s; }
.js .shadecard.in .shadecard__chip,
.js .shadecard.in .shadecard__spec{ opacity:1; }
@media (hover:hover){
  .shadecard.in:hover .shadecard__frame{ transform:rotate(0deg) scale(1.03); }
}

@media (max-width:900px){
  .shadecard{ top:clamp(64px,10vh,110px); width:clamp(158px,40vw,230px); }
  /* the chip hangs off the LEFT on a phone. On the right it ran past the
     viewport edge and overflow-x:clip silently ate half the label — the
     text was there, it just could not be read. */
  .shadecard__chip{ left:auto; right:64%; bottom:-13%; white-space:nowrap;
    padding:.34rem .55rem .34rem .4rem; gap:.4rem; }
  .shadecard__t{ font-size:.46rem; letter-spacing:.08em; }
  .shadecard__spec{ display:none; }
}
@media (max-width:420px){
  .shadecard__chip{ right:58%; }
}
@media (prefers-reduced-motion:reduce){
  .shadecard__sheen{ animation:none; opacity:0; }
  .shadecard__frame{ transform:none; }
  .js .shadecard{ opacity:1; }
  .js .shadecard .shadecard__frame{ transform:none; }
}
