/* ==========================================================================
   Crimson Luis — brand stylesheet
   Palette: jet black, crimson red, shiny gold, bright white
   Type: Hind Siliguri (Bengali UI) + Cormorant Garamond (Latin display)
   ========================================================================== */

:root{
  --ink:#07070A; --ink-2:#0E0E13; --ink-3:#15151C; --ink-4:#1D1D26;
  --crimson:#C8102E; --crimson-deep:#7A0A1C; --crimson-soft:rgba(200,16,46,.14);
  --gold:#E3B94E; --gold-deep:#A8792B; --gold-light:#F7E6B4;
  --white:#FFFFFF; --mist:#B9B9C0; --dim:#7C7C86;
  --line:rgba(227,185,78,.18); --line-soft:rgba(255,255,255,.07);
  --shadow:0 24px 60px -24px rgba(0,0,0,.9);
  --gold-grad:linear-gradient(135deg,var(--gold-light),var(--gold) 42%,var(--gold-deep));
  --crimson-grad:linear-gradient(135deg,var(--crimson),var(--crimson-deep));
  --r:14px; --r-lg:22px; --r-pill:999px;
  --wrap:1280px; --gut:clamp(16px,4vw,32px);
  --ease:cubic-bezier(.22,1,.36,1);
  --head:'Cormorant Garamond',Georgia,'Times New Roman',serif;
  /* Cormorant is a delicate face — these keep it crisp on dark backgrounds */
  --head-light:300; --head-regular:400; --head-medium:500; --head-semibold:600; --head-bold:700;
  --body:'Hind Siliguri',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;overflow-x:hidden;overflow-x:clip;
  width:100%;max-width:100%}
body{
  margin:0;background:var(--ink);color:var(--mist);
  font-family:var(--body);font-size:16px;line-height:1.75;font-weight:400;
  overflow-x:hidden;overflow-x:clip;width:100%;max-width:100%;
  -webkit-font-smoothing:antialiased;
}
/* nothing in the page chrome may exceed the viewport */
.site-head,.top-strip,.site-foot,.mbar,.section,.hero{max-width:100vw;overflow-x:clip}
body.locked{overflow:hidden}
img{max-width:100%;display:block;height:auto}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font:inherit;color:inherit}
h1,h2,h3,h4,h5{margin:0;color:var(--white);font-weight:600;line-height:1.35}
p{margin:0 0 1em}
::selection{background:var(--crimson);color:#fff}
:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:6px}

/* scrollbar */
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:var(--ink)}
::-webkit-scrollbar-thumb{background:linear-gradient(var(--gold-deep),var(--crimson-deep));border-radius:9px;border:2px solid var(--ink)}

/* ---------- layout ---------- */
.wrap{width:min(100% - var(--gut)*2,var(--wrap));margin-inline:auto;max-width:100%}
/* flex/grid children default to min-width:auto and refuse to shrink — this is the
   single most common cause of mobile horizontal overflow */
.head-in>*,.nav,.p-grid>*,.foot-grid>*,.grid>*{min-width:0}
img,svg,video,iframe{max-width:100%}
pre,table{max-width:100%;overflow-x:auto}
.section{padding-block:clamp(56px,8vw,110px);position:relative}
.section--tight{padding-block:clamp(36px,5vw,64px)}
.grid{display:grid;gap:clamp(16px,2.4vw,28px)}
.center{text-align:center}

/* ---------- type ---------- */
.display{font-family:var(--head);letter-spacing:.13em;text-transform:uppercase;font-weight:700;font-size:1.06em}
/* Two eyebrow treatments, because one cannot serve both scripts.
   Cormorant Garamond contains zero Bengali glyphs, so a Bengali label in it
   silently falls back to another font while still inheriting uppercase (which
   means nothing in Bengali) and .34em tracking (which pulls যুক্তাক্ষর apart —
   "কালেকশন" rendered as ক া ল ে ক শ ন). */
.eyebrow{
  font-size:12px;letter-spacing:.34em;text-transform:uppercase;color:var(--gold);
  font-family:var(--head);font-weight:600;display:flex;align-items:center;gap:12px;justify-content:inherit;
}
/* Bengali: the body face, normal case, and only enough tracking to feel
   deliberate without breaking conjuncts. */
.eyebrow--bn{
  font-family:var(--body);font-weight:600;font-size:13px;
  letter-spacing:.06em;text-transform:none;
}
.eyebrow::before,.eyebrow::after{content:"";height:1px;width:34px;background:linear-gradient(90deg,transparent,var(--gold))}
.eyebrow::after{background:linear-gradient(270deg,transparent,var(--gold))}
.center .eyebrow{justify-content:center}
.h-lg{font-size:clamp(25px,3.6vw,42px)}
.h-md{font-size:clamp(20px,2.4vw,28px)}
.lead{font-size:clamp(15px,1.6vw,18px);color:var(--mist);max-width:62ch}
.muted{color:var(--dim)}
.gold-text{background:var(--gold-grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.tk{font-variant-numeric:tabular-nums}

/* ---------- buttons ---------- */
.btn{
  --bg:var(--crimson-grad);
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  padding:13px 30px;border:0;border-radius:var(--r-pill);background:var(--bg);
  color:#fff;font-weight:600;font-size:15px;cursor:pointer;position:relative;
  overflow:hidden;transition:transform .35s var(--ease),box-shadow .35s var(--ease),filter .3s;
  box-shadow:0 10px 30px -12px rgba(200,16,46,.85);
}
.btn::after{
  content:"";position:absolute;inset:0;transform:translateX(-120%);
  background:linear-gradient(105deg,transparent,rgba(255,255,255,.42),transparent);
  transition:transform .75s var(--ease);
}
.btn:hover{transform:translateY(-2px);box-shadow:0 18px 40px -14px rgba(200,16,46,.95)}
.btn:hover::after{transform:translateX(120%)}
.btn:active{transform:translateY(0)}
.btn--gold{--bg:var(--gold-grad);color:#1A1206;box-shadow:0 10px 30px -12px rgba(227,185,78,.7)}
.btn--gold:hover{box-shadow:0 18px 40px -14px rgba(227,185,78,.85)}
.btn--ghost{
  background:transparent;border:1px solid var(--line);color:var(--white);box-shadow:none;
}
.btn--ghost:hover{border-color:var(--gold);background:rgba(227,185,78,.08);box-shadow:none}
.btn--block{width:100%}
.btn--sm{padding:9px 18px;font-size:14px}
.btn--lg{padding:16px 38px;font-size:16px}
.btn[disabled]{opacity:.45;pointer-events:none}

/* ---------- alpona divider (Bengali floor-art motif, drawn in gold) ---------- */
.notify-box{margin-top:16px;border:1px solid var(--line-soft);border-radius:12px;padding:12px 16px;background:rgba(255,255,255,.02)}
.notify-box summary{cursor:pointer;font-weight:600;color:var(--gold);list-style:none}
.notify-box summary::-webkit-details-marker{display:none}
.notify-box summary::before{content:"🔔 ";}
.notify-row{display:grid;grid-template-columns:1fr 1fr auto;gap:10px}
@media (max-width:620px){.notify-row{grid-template-columns:1fr}}
.opt--out{opacity:.32;cursor:not-allowed;text-decoration:line-through;position:relative}
.opt--out:hover{border-color:var(--line-soft);color:inherit;transform:none}
.opt-stock{font-size:12.5px;color:var(--dim);margin-top:6px}
.opt-stock b{color:var(--gold)}
.opt-stock.low b{color:var(--crimson)}
.alpona{
  height:44px;width:100%;opacity:.65;
  background-repeat:repeat-x;background-position:center;background-size:auto 44px;
  background-image:url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='180' height='44' viewBox='0 0 180 44'>\
<g fill='none' stroke='%23E3B94E' stroke-width='1.1' stroke-linecap='round'>\
<path d='M0 22h34'/><path d='M146 22h34'/>\
<path d='M52 22c0-9 7-16 16-16s16 7 16 16-7 16-16 16-16-7-16-16z'/>\
<path d='M96 22c0-9 7-16 16-16s16 7 16 16-7 16-16 16-16-7-16-16z'/>\
<path d='M34 22c6-8 12-8 18 0-6 8-12 8-18 0z'/><path d='M128 22c6-8 12-8 18 0-6 8-12 8-18 0z'/>\
<path d='M84 22c3-5 6-5 12 0-6 5-9 5-12 0z'/>\
<circle cx='68' cy='22' r='3.2' fill='%23C8102E' stroke='none'/>\
<circle cx='112' cy='22' r='3.2' fill='%23C8102E' stroke='none'/>\
</g></svg>");
}
.alpona--fade{-webkit-mask-image:linear-gradient(90deg,transparent,#000 22%,#000 78%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 22%,#000 78%,transparent)}

/* ---------- header ---------- */
.top-strip{
  background:linear-gradient(90deg,var(--crimson-deep),var(--crimson),var(--crimson-deep));
  color:#fff;font-size:13px;overflow:hidden;white-space:nowrap;padding:7px 0
}
.top-strip .rail{display:inline-flex;gap:46px;animation:slide 26s linear infinite;padding-left:100%}
.top-strip b{color:var(--gold-light)}
@keyframes slide{to{transform:translateX(-100%)}}

.site-head{
  position:sticky;top:0;z-index:900;background:rgba(7,7,10,.72);
  backdrop-filter:blur(16px) saturate(150%);-webkit-backdrop-filter:blur(16px) saturate(150%);
  border-bottom:1px solid var(--line-soft);transition:background .3s,border-color .3s
}
.site-head.stuck{background:rgba(7,7,10,.94);border-bottom-color:var(--line)}
.head-in{display:flex;align-items:center;gap:18px;height:74px;min-width:0}
.brand{display:flex;align-items:center;gap:12px;min-width:0}
.brand>span{display:flex;flex-direction:column;min-width:0}
.brand-mark{
  width:46px;height:46px;object-fit:contain;
  filter:drop-shadow(0 0 12px rgba(227,185,78,.45));
  transition:transform .9s var(--ease),filter .5s
}
.brand:hover .brand-mark{transform:rotate(180deg) scale(1.08);filter:drop-shadow(0 0 20px rgba(227,185,78,.85))}
.brand-name{display:block;font-family:var(--head);font-weight:600;letter-spacing:.18em;font-size:18px;color:var(--white);line-height:1.15;white-space:nowrap}
.brand-tag{display:block;font-family:var(--head);font-weight:500;font-size:10.5px;letter-spacing:.26em;color:var(--gold);line-height:1.3;white-space:nowrap}
.nav{display:flex;gap:6px;margin-inline:auto}
.nav a{
  position:relative;padding:9px 15px;border-radius:var(--r-pill);font-size:15px;
  color:var(--mist);transition:color .25s
}
.nav a::after{
  content:"";position:absolute;left:15px;right:15px;bottom:4px;height:1.5px;
  background:var(--gold-grad);transform:scaleX(0);transform-origin:left;transition:transform .35s var(--ease)
}
.nav a:hover,.nav a.on{color:var(--white)}
.nav a:hover::after,.nav a.on::after{transform:scaleX(1)}
.head-acts{display:flex;align-items:center;gap:8px;margin-left:auto;flex-shrink:0}
.icon-btn{
  width:42px;height:42px;display:grid;place-items:center;border-radius:50%;
  background:rgba(255,255,255,.04);border:1px solid var(--line-soft);color:var(--mist);
  cursor:pointer;position:relative;transition:.28s var(--ease)
}
.icon-btn:hover{color:var(--gold);border-color:var(--gold);background:rgba(227,185,78,.1);transform:translateY(-2px)}
.icon-btn svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.badge{
  position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 5px;border-radius:var(--r-pill);
  background:var(--crimson);color:#fff;font-size:11px;font-weight:600;display:grid;place-items:center;
  border:2px solid var(--ink);
}
.badge.pop{animation:pop .45s var(--ease)}
@keyframes pop{0%{transform:scale(.4)}60%{transform:scale(1.35)}100%{transform:scale(1)}}
.burger{display:none}

/* mobile drawer */
.drawer{
  position:fixed;inset:0 0 0 auto;width:min(86vw,340px);background:var(--ink-2);z-index:1000;
  transform:translateX(105%);transition:transform .45s var(--ease),visibility .45s;
  border-left:1px solid var(--line);padding:22px;overflow-y:auto;
  visibility:hidden;pointer-events:none;   /* closed drawers must not add scroll width */
}
.drawer.open{transform:none;visibility:visible;pointer-events:auto}
.drawer a{display:block;padding:14px 6px;border-bottom:1px solid var(--line-soft);color:var(--mist);font-size:16px}
.drawer a:hover{color:var(--gold);padding-left:12px;transition:.25s}
.scrim{position:fixed;inset:0;background:rgba(0,0,0,.68);backdrop-filter:blur(3px);z-index:999;opacity:0;visibility:hidden;transition:.35s}
.scrim.on{opacity:1;visibility:visible}

/* search overlay */
.search-pane{
  position:fixed;inset:0;z-index:1001;background:rgba(7,7,10,.96);backdrop-filter:blur(12px);
  display:grid;place-items:start center;padding-top:14vh;opacity:0;visibility:hidden;transition:.3s
}
.search-pane.on{opacity:1;visibility:visible}
.search-box{width:min(92vw,660px)}
.search-box input{
  width:100%;padding:18px 22px;border-radius:var(--r-pill);background:var(--ink-3);
  border:1px solid var(--line);color:var(--white);font-size:17px
}
.search-res{margin-top:16px;display:grid;gap:8px;max-height:56vh;overflow:auto}
.search-res a{display:flex;gap:14px;align-items:center;padding:10px;border-radius:var(--r);background:var(--ink-2);border:1px solid var(--line-soft)}
.search-res a:hover{border-color:var(--gold)}
.search-res img{width:52px;height:64px;object-fit:cover;border-radius:8px}

/* ---------- hero ---------- */
.hero{position:relative;min-height:clamp(560px,92vh,900px);display:grid;align-items:center;overflow:hidden}
.hero-bg{position:absolute;inset:0;z-index:0}
.hero-bg::before{
  content:"";position:absolute;left:50%;top:46%;transform:translate(-50%,-50%);
  width:min(150vw,1180px);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(200,16,46,.22),rgba(227,185,78,.08) 42%,transparent 66%);
  filter:blur(10px)
}
.hero-sun{
  position:absolute;left:50%;top:44%;translate:-50% -50%;
  width:min(112vw,900px);opacity:.16;animation:spin 90s linear infinite;
  -webkit-mask-image:radial-gradient(circle,#000 55%,transparent 76%);
  mask-image:radial-gradient(circle,#000 55%,transparent 76%)
}
@keyframes spin{to{transform:rotate(360deg)}}
.hero-grain{position:absolute;inset:0;opacity:.5;pointer-events:none;
  background-image:radial-gradient(rgba(255,255,255,.045) 1px,transparent 1px);background-size:3px 3px}
/* Reading scrim. The lion stays exactly as it is — this only darkens the area
   the text sits on, so the headline reads against calm ground instead of the
   lion's mane. Contrast was already fine (20:1); what this fixes is visual
   busyness, which is a different problem from legibility. */
.hero::before{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(ellipse 62% 46% at 50% 56%,
      rgba(7,7,10,.86) 0%, rgba(7,7,10,.66) 45%, rgba(7,7,10,.24) 72%, transparent 88%),
    linear-gradient(180deg, rgba(7,7,10,.55) 0%, transparent 26%,
      transparent 68%, rgba(7,7,10,.80) 100%)
}
.hero-in{position:relative;z-index:2;text-align:center;padding-block:clamp(60px,10vw,110px)}
.hero-mark{width:clamp(112px,17vw,178px);margin:0 auto 22px;filter:drop-shadow(0 14px 40px rgba(227,185,78,.42));
  animation:floaty 7s ease-in-out infinite}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}
.hero-title{font-size:clamp(30px,6.4vw,68px);color:var(--white);font-weight:700;letter-spacing:-.015em;line-height:1.22}
.hero-title .gold-text{display:inline-block}
.hero-slogan{
  font-family:var(--head);font-weight:500;letter-spacing:.36em;font-size:clamp(12.5px,2.6vw,16px);
  color:var(--gold);text-transform:uppercase;margin-bottom:16px
}
.hero-sub{margin:18px auto 30px;max-width:60ch;font-size:clamp(15px,1.8vw,18px);color:var(--mist)}
.hero-cta{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}
.hero-stats{display:flex;gap:clamp(22px,5vw,64px);justify-content:center;margin-top:46px;flex-wrap:wrap}
.hero-stats div{text-align:center}
.hero-stats b{display:block;font-size:clamp(21px,3vw,32px);color:var(--gold);font-weight:700}
.hero-stats span{font-size:13px;color:var(--dim)}
.scroll-hint{position:absolute;bottom:22px;left:50%;translate:-50%;color:var(--dim);font-size:12px;z-index:2;text-align:center}
.scroll-hint i{display:block;width:1px;height:34px;margin:8px auto 0;background:linear-gradient(var(--gold),transparent);animation:drop 2s ease-in-out infinite}
@keyframes drop{0%,100%{opacity:.3;transform:scaleY(.5)}50%{opacity:1;transform:scaleY(1)}}

/* ---------- product card ---------- */
.p-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:clamp(14px,2vw,26px)}
.card{
  position:relative;background:var(--ink-2);border:1px solid var(--line-soft);border-radius:var(--r-lg);
  overflow:hidden;transition:transform .45s var(--ease),border-color .45s,box-shadow .45s;display:flex;flex-direction:column
}
.card:hover{transform:translateY(-7px);border-color:var(--line);box-shadow:var(--shadow)}
.card-media{position:relative;aspect-ratio:3/4;overflow:hidden;background:var(--ink-3)}
.card-media img{width:100%;height:100%;object-fit:cover;transition:transform .85s var(--ease),filter .5s}
.card:hover .card-media img{transform:scale(1.07)}
.card-media::after{
  content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 52%,rgba(7,7,10,.85));
  opacity:.85;transition:opacity .4s
}
.tag{
  position:absolute;top:12px;left:12px;z-index:2;padding:5px 13px;border-radius:var(--r-pill);
  font-size:11.5px;font-weight:600;background:var(--crimson);color:#fff;letter-spacing:.02em
}
.tag--gold{background:var(--gold-grad);color:#1A1206}
.tag--out{background:rgba(0,0,0,.75);color:var(--mist);border:1px solid var(--line-soft)}
.card-quick{
  position:absolute;left:12px;right:12px;bottom:12px;z-index:3;display:flex;gap:8px;
  transform:translateY(140%);opacity:0;transition:.45s var(--ease)
}
.card:hover .card-quick,.card:focus-within .card-quick{transform:none;opacity:1}
.card-body{padding:15px 16px 18px;display:flex;flex-direction:column;gap:6px;flex:1}
.card-cat{font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--gold);font-weight:500}
.card-title{font-size:16px;color:var(--white);font-weight:600;line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* Three items — price, old price, discount badge — do not fit on one line in a
   narrow card. Without wrapping, the badge was clipped at the card edge and the
   price itself broke between the ৳ and the number ("৳" alone on one line). The
   row now wraps as a whole, and each money value is kept unbreakable. */
.card-price{display:flex;flex-wrap:wrap;align-items:baseline;gap:5px 9px;margin-top:auto;padding-top:6px;min-width:0}
.card-price .now{font-size:18px;font-weight:700;color:var(--gold);white-space:nowrap}
.card-price .was{font-size:13.5px;color:var(--dim);text-decoration:line-through;white-space:nowrap}
.card-price .off{font-size:11.5px;color:var(--crimson);border:1px solid rgba(200,16,46,.4);padding:1px 7px;border-radius:var(--r-pill);white-space:nowrap;flex-shrink:0}

/* ---------- category tiles ---------- */
.cat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:clamp(14px,2vw,22px)}
.cat-tile{
  position:relative;aspect-ratio:4/5;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line-soft);
  display:flex;align-items:flex-end;padding:20px;transition:.5s var(--ease)
}
.cat-tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .9s var(--ease)}
.cat-tile::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(7,7,10,.15),rgba(7,7,10,.9))}
.cat-tile:hover{border-color:var(--gold);transform:translateY(-5px)}
.cat-tile:hover img{transform:scale(1.09)}
.cat-tile span{position:relative;z-index:2}
.cat-tile b{display:block;color:#fff;font-size:19px;font-weight:600}
.cat-tile small{color:var(--gold);font-size:12.5px}

/* ---------- story ---------- */
.story{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(26px,5vw,70px);align-items:center}
.story-art{position:relative;aspect-ratio:1;display:grid;place-items:center}
.story-art .ring{
  position:absolute;inset:6%;border-radius:50%;border:1px solid var(--line);
  animation:spin 46s linear infinite
}
.story-art .ring:nth-child(2){inset:16%;border-style:dashed;border-color:rgba(200,16,46,.32);animation-duration:34s;animation-direction:reverse}
.story-art .ring:nth-child(3){inset:27%;border-color:rgba(227,185,78,.3);animation-duration:60s}
.story-art img{width:56%;filter:drop-shadow(0 20px 48px rgba(227,185,78,.35));animation:floaty 8s ease-in-out infinite}
.pillars{display:grid;gap:14px;margin-top:26px}
.pillar{display:flex;gap:15px;padding:16px;border:1px solid var(--line-soft);border-radius:var(--r);
  background:linear-gradient(180deg,rgba(255,255,255,.03),transparent);transition:.35s}
.pillar:hover{border-color:var(--line);transform:translateX(5px)}
.pillar i{
  flex:0 0 42px;height:42px;border-radius:12px;display:grid;place-items:center;font-style:normal;
  background:var(--crimson-soft);border:1px solid rgba(200,16,46,.34);color:var(--gold);font-size:19px
}
.pillar b{color:var(--white);display:block;font-weight:600}
.pillar p{margin:2px 0 0;font-size:14.5px}

/* ---------- product page ---------- */
.split{align-items:start}
.split--a{grid-template-columns:1.55fr .95fr}
.split--b{grid-template-columns:1.25fr .75fr}
.split--c{grid-template-columns:1fr 1fr}
/* summary rows must never squash their own text */
.sum-row{gap:14px;align-items:baseline}
.sum-row>span:first-child{flex:1;min-width:0}
.sum-row>b,.sum-row>span:last-child{white-space:nowrap;text-align:right}
.pdp{display:grid;grid-template-columns:1.05fr 1fr;gap:clamp(24px,4vw,56px);align-items:start}
.gal-main{
  position:relative;aspect-ratio:3/4;border-radius:var(--r-lg);overflow:hidden;background:var(--ink-2);
  border:1px solid var(--line-soft);
  /* on a phone the frame must not swallow the whole screen before the price */
  max-height:min(74vh,620px)
}
/* "contain" shows the whole photo whatever its shape. With "cover" a square shot
   lost a quarter of its width and a landscape shot nearly half — which is what
   made product photos look zoomed in and cut off. */
.gal-main img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;object-position:center;
  background:var(--ink-3);transition:opacity .35s var(--ease)
}
/* a soft blurred copy fills the leftover bars so a non-3:4 photo still looks
   deliberate instead of sitting on flat grey */
.gal-main::before{
  content:"";position:absolute;inset:0;z-index:0;
  background:var(--bg-blur) center/cover no-repeat;
  filter:blur(26px) saturate(.7) brightness(.45);transform:scale(1.15);opacity:.55
}
.gal-main img{z-index:1}
.gal-nav{
  position:absolute;top:50%;translate:0 -50%;z-index:3;width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;border:1px solid var(--line);background:rgba(10,10,13,.55);
  backdrop-filter:blur(6px);color:var(--gold);cursor:pointer;padding:0;
  opacity:0;transition:opacity .25s;-webkit-tap-highlight-color:transparent
}
.gal-main:hover .gal-nav,.gal-nav:focus-visible{opacity:1}
.gal-nav.prev{left:10px}.gal-nav.next{right:10px}
.gal-dots{position:absolute;left:0;right:0;bottom:10px;z-index:3;display:flex;justify-content:center;gap:6px}
.gal-dots i{width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.35);transition:.3s}
.gal-dots i.on{background:var(--gold);width:18px;border-radius:6px}
@media (hover:none){ .gal-nav{opacity:.85} }
.gal-thumbs{display:flex;gap:10px;margin-top:12px;overflow-x:auto;padding-bottom:4px}
.gal-thumbs button{
  flex:0 0 74px;aspect-ratio:3/4;border-radius:10px;overflow:hidden;border:1px solid var(--line-soft);
  background:none;cursor:pointer;padding:0;transition:.3s
}
.gal-thumbs button.on,.gal-thumbs button:hover{border-color:var(--gold)}
.gal-thumbs img{width:100%;height:100%;object-fit:cover}
.pdp-title{font-size:clamp(23px,3.2vw,36px);margin-bottom:8px}
.price-row{display:flex;align-items:baseline;gap:12px;margin:14px 0 18px}
.price-now{font-size:clamp(26px,3.4vw,36px);font-weight:700;background:var(--gold-grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.price-was{font-size:17px;color:var(--dim);text-decoration:line-through}
.save-pill{background:var(--crimson-soft);border:1px solid rgba(200,16,46,.4);color:#FF8A9C;padding:3px 12px;border-radius:var(--r-pill);font-size:13px}
.opt-group{margin-bottom:18px}
.opt-label{font-size:13.5px;color:var(--dim);margin-bottom:9px;display:flex;justify-content:space-between}
.opts{display:flex;flex-wrap:wrap;gap:9px}
.opt{
  min-width:48px;padding:9px 16px;border-radius:10px;border:1px solid var(--line-soft);
  background:var(--ink-2);color:var(--mist);cursor:pointer;font-size:14.5px;transition:.25s;text-align:center
}
.opt:hover{border-color:var(--gold);color:var(--white)}
.opt.on{border-color:var(--gold);background:rgba(227,185,78,.14);color:var(--gold-light);font-weight:600}
.qty{display:inline-flex;align-items:center;border:1px solid var(--line-soft);border-radius:var(--r-pill);overflow:hidden;background:var(--ink-2)}
.qty button{width:42px;height:44px;background:none;border:0;color:var(--gold);font-size:19px;cursor:pointer;transition:.2s}
.qty button:hover{background:rgba(227,185,78,.12)}
.qty input{width:52px;height:44px;text-align:center;background:none;border:0;color:var(--white);font-weight:600}
.trust{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin-top:22px}
.trust div{display:flex;gap:10px;align-items:center;font-size:13.5px;padding:11px 13px;border:1px solid var(--line-soft);border-radius:var(--r);background:var(--ink-2)}
.trust b{color:var(--white);font-weight:600;font-size:13.5px;display:block;line-height:1.35}
.tabs{display:flex;gap:6px;border-bottom:1px solid var(--line-soft);margin:38px 0 20px;overflow-x:auto}
.tabs button{background:none;border:0;padding:13px 18px;color:var(--dim);cursor:pointer;font-size:15px;position:relative;white-space:nowrap}
.tabs button.on{color:var(--gold)}
.tabs button.on::after{content:"";position:absolute;left:12px;right:12px;bottom:-1px;height:2px;background:var(--gold-grad)}
.tab-body{display:none;animation:fadeIn .4s ease}
.tab-body.on{display:block}
.spec{width:100%;border-collapse:collapse}
.spec td{padding:11px 0;border-bottom:1px solid var(--line-soft);font-size:15px}
.spec td:first-child{color:var(--dim);width:38%}

/* ---------- forms ---------- */
.field{margin-bottom:15px}
.field label{display:block;font-size:13.5px;color:var(--mist);margin-bottom:7px}
.field label .req{color:var(--crimson)}
.input,select.input,textarea.input{
  width:100%;padding:13px 16px;border-radius:12px;background:var(--ink-2);
  border:1px solid var(--line-soft);color:var(--white);font-size:15px;transition:.25s
}
.input::placeholder{color:#55555E}
.input:focus{outline:none;border-color:var(--gold);background:var(--ink-3);box-shadow:0 0 0 3px rgba(227,185,78,.12)}
textarea.input{resize:vertical;min-height:104px}
select.input{appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'><path d='M1 1l5 5 5-5' stroke='%23E3B94E' stroke-width='1.6' fill='none' stroke-linecap='round'/></svg>");
  background-repeat:no-repeat;background-position:right 16px center;padding-right:42px}
.hp{position:absolute;left:-9999px;opacity:0;height:0;width:0}
.two{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.pay-opts{display:grid;gap:10px}
.pay{display:flex;gap:13px;align-items:center;padding:15px;border:1px solid var(--line-soft);border-radius:var(--r);cursor:pointer;transition:.25s;background:var(--ink-2)}
.pay:hover{border-color:var(--line)}
.pay.on{border-color:var(--gold);background:rgba(227,185,78,.08)}
.pay input{accent-color:var(--crimson);width:18px;height:18px}
.pay b{color:var(--white);font-weight:600;display:block;font-size:15px}
.pay small{color:var(--dim);font-size:12.5px}

/* ---------- panels, cart, summary ---------- */
.panel{background:var(--ink-2);border:1px solid var(--line-soft);border-radius:var(--r-lg);padding:clamp(18px,2.6vw,28px)}
.panel--gold{border-color:var(--line);background:linear-gradient(180deg,rgba(227,185,78,.06),transparent)}
.sum-row{display:flex;justify-content:space-between;padding:9px 0;font-size:15px}
.sum-row.total{border-top:1px solid var(--line);margin-top:9px;padding-top:15px;font-size:18px;color:var(--white);font-weight:600}
.sum-row.total b{color:var(--gold);font-size:23px}
.cart-line{display:grid;grid-template-columns:92px 1fr auto;gap:16px;padding:16px 0;border-bottom:1px solid var(--line-soft);align-items:center}
.cart-line img{width:92px;height:114px;object-fit:cover;border-radius:12px}
.cart-line .meta{font-size:13px;color:var(--dim)}
.empty{text-align:center;padding:clamp(40px,8vw,90px) 20px}
.empty img{width:110px;margin:0 auto 20px;opacity:.42;animation:spin 30s linear infinite}

/* ---------- steps / timeline ---------- */
.timeline{position:relative;padding-left:32px}
.timeline::before{content:"";position:absolute;left:9px;top:6px;bottom:6px;width:1px;background:var(--line)}
.tl-item{position:relative;padding:0 0 22px}
.tl-item::before{content:"";position:absolute;left:-28px;top:6px;width:11px;height:11px;border-radius:50%;background:var(--ink);border:2px solid var(--gold)}
.tl-item.done::before{background:var(--gold)}
.tl-item b{color:var(--white);display:block;font-size:15px}
.tl-item small{color:var(--dim)}

/* ---------- faq ---------- */
.acc{border:1px solid var(--line-soft);border-radius:var(--r);margin-bottom:11px;overflow:hidden;background:var(--ink-2)}
.acc summary{padding:17px 20px;cursor:pointer;color:var(--white);font-weight:500;list-style:none;display:flex;justify-content:space-between;gap:14px;font-size:15.5px}
.acc summary::-webkit-details-marker{display:none}
.acc summary::after{content:"+";color:var(--gold);font-size:21px;transition:transform .3s;line-height:1}
.acc[open] summary::after{transform:rotate(45deg)}
.acc .body{padding:0 20px 18px;color:var(--mist);font-size:15px}

/* ---------- footer ---------- */
.site-foot{background:var(--ink-2);border-top:1px solid var(--line);margin-top:auto;position:relative}
.foot-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1.4fr;gap:clamp(22px,3vw,44px);padding-block:clamp(38px,5vw,62px)}
.foot-grid h5{color:var(--white);font-size:15px;margin-bottom:15px;letter-spacing:.02em}
.foot-grid a{display:block;padding:5px 0;font-size:14.5px;color:var(--dim);transition:.25s}
.foot-grid a:hover{color:var(--gold);padding-left:6px}
.socials{display:flex;gap:10px;margin-top:16px}
.socials a{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;border:1px solid var(--line-soft);padding:0}
.socials a:hover{border-color:var(--gold);background:rgba(227,185,78,.1);padding-left:0}
.socials svg{width:17px;height:17px;fill:currentColor}
.foot-bottom{border-top:1px solid var(--line-soft);padding:18px 0 6px;display:flex;justify-content:space-between;
  gap:14px;flex-wrap:wrap;font-size:13.5px;color:var(--dim)}
.foot-legal{display:flex;gap:18px;flex-wrap:wrap}
.foot-legal a{padding:4px 0}
@media (max-width:860px){
  .foot-bottom{flex-direction:column;align-items:center;text-align:center;gap:10px;padding-bottom:18px}
  .foot-legal{justify-content:center;gap:14px 20px}
  .foot-legal a{padding:6px 2px}
}
.pay-logos{display:flex;gap:8px;flex-wrap:wrap}
.pay-logos span{padding:5px 12px;border:1px solid var(--line-soft);border-radius:8px;font-size:12px;color:var(--mist)}

/* ---------- toast + flash ---------- */
.toast-wrap{position:fixed;right:18px;bottom:18px;z-index:1200;display:grid;gap:10px;max-width:min(92vw,360px)}
.toast{
  background:var(--ink-3);border:1px solid var(--line);border-left:3px solid var(--gold);
  padding:14px 18px;border-radius:12px;color:var(--white);font-size:14.5px;box-shadow:var(--shadow);
  animation:toastIn .4s var(--ease)
}
.toast.err{border-left-color:var(--crimson)}
@keyframes toastIn{from{opacity:0;transform:translateY(18px) scale(.96)}}

/* ---------- reveal on scroll ---------- */
.rv{opacity:0;transform:translateY(26px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.rv.in{opacity:1;transform:none}
.rv-d1{transition-delay:.09s}.rv-d2{transition-delay:.18s}.rv-d3{transition-delay:.27s}.rv-d4{transition-delay:.36s}

/* ---------- mobile bottom bar ---------- */
.mbar{
  position:fixed;left:0;right:0;bottom:0;z-index:880;display:none;
  background:rgba(10,10,13,.96);backdrop-filter:blur(14px);border-top:1px solid var(--line);
  padding:8px 6px calc(8px + env(safe-area-inset-bottom))
}
.mbar a{flex:1;display:grid;place-items:center;gap:3px;font-size:11px;color:var(--dim);padding:5px 0;position:relative}
.mbar a.on{color:var(--gold)}
.mbar svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.7}

/* ---------- pagination ---------- */
.pager{display:flex;gap:8px;justify-content:center;margin-top:38px;flex-wrap:wrap}
.pager a,.pager span{min-width:42px;height:42px;display:grid;place-items:center;border-radius:12px;
  border:1px solid var(--line-soft);color:var(--mist);padding:0 12px;transition:.25s}
.pager a:hover{border-color:var(--gold);color:var(--gold)}
.pager .on{background:var(--gold-grad);color:#1A1206;border-color:transparent;font-weight:700}

/* ---------- utility ---------- */
.chips{display:flex;gap:8px;flex-wrap:wrap}
.chip{padding:7px 15px;border-radius:var(--r-pill);border:1px solid var(--line-soft);font-size:13.5px;color:var(--mist);transition:.25s}
.chip:hover{border-color:var(--gold);color:var(--gold)}
.chip.on{background:var(--gold-grad);color:#1A1206;border-color:transparent;font-weight:600}
.stack{display:grid;gap:14px}
.row-between{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap}
.hide{display:none !important}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.stars span{color:#3A3A44;font-size:15px}
.stars span.on{color:var(--gold)}

/* ---------- responsive ---------- */
@media (max-width:1024px){
  .story{grid-template-columns:1fr}
  .story-art{max-width:420px;margin-inline:auto;order:-1}
  .pdp{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr 1fr}
}
@media (max-width:960px){
  .split--a,.split--b,.split--c{grid-template-columns:1fr}
  .split .panel{width:100%}
}
@media (max-width:860px){
  .nav{display:none}
  .burger{display:grid}
  .head-in{height:72px;gap:10px}
  .brand-mark{width:46px;height:46px}
  .brand-name{font-size:15px;letter-spacing:.15em}
  .brand-tag{font-size:9.5px;letter-spacing:.2em}
  .icon-btn{width:42px;height:42px}
  .head-acts{gap:7px}
  .top-strip{font-size:12px}
  .mbar{display:flex}
  body{padding-bottom:calc(88px + env(safe-area-inset-bottom))}
  .p-grid{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px}
  /* Sitting flush against the photo made the button look like it was cutting
     into the image, especially against a light product shot. A little air, and
     the card body starts below it rather than immediately after. */
  .card-quick{
    transform:none;opacity:1;position:static;padding:0 14px 4px;
    /* real separation, not just inner padding: the button's own box has to
       start below the photo or it still reads as sitting on the image */
    margin-top:12px
  }
  .card-media::after{opacity:.6}
  .two{grid-template-columns:1fr}
  .cart-line{grid-template-columns:74px 1fr;gap:12px}
  .cart-line img{width:74px;height:92px}
  .cart-line .price-col{grid-column:2;text-align:left}
}
@media (max-width:520px){
  .head-in{height:66px}
  .brand-mark{width:40px;height:40px}
  .brand-name{font-size:13.5px;letter-spacing:.1em}
  /* 7px was below anything readable; the wordmark above it carries the
     name, so this only needs to be legible, not loud */
  .brand-tag{font-size:9px;letter-spacing:.16em}
  .icon-btn{width:38px;height:38px}
  .icon-btn svg{width:18px;height:18px}
  .head-acts{gap:6px}
  .icon-btn.acct{display:none}   /* account lives in the drawer + bottom bar on phones */
  .foot-grid{grid-template-columns:1fr;gap:26px}
  .hero-stats{gap:18px}
  .card-title{font-size:14.5px}
  .btn{padding:12px 24px;font-size:14.5px}
  .brand-name{font-size:14px}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;scroll-behavior:auto !important}
  .rv{opacity:1;transform:none}
}

/* print — used for the customer invoice */
@media (max-width:360px){
  .brand-name{font-size:12px;letter-spacing:.05em}
  .brand-tag{display:none}
  .brand-mark{width:36px;height:36px}
  .icon-btn{width:36px;height:36px}
  .head-in{height:62px}
}
@media print{
  .site-head,.site-foot,.mbar,.top-strip,.no-print{display:none !important}
  body{background:#fff;color:#000}
  .panel{border:1px solid #ccc}
}

/* ==========================================================================
   Motion polish (S13)
   Everything here is decoration. It must never hide a price, block a tap or
   delay a purchase — so each effect is short, interruptible, and switched off
   entirely for anyone who has asked their device for less motion.
   ========================================================================== */

/* ---- product card: second photo, gold edge ---- */
.card-media{position:relative;overflow:hidden;background:var(--ink-3)}
/* the frame shimmers until its photo arrives, so the grid never flashes empty */
.card-media::before{
  content:"";position:absolute;inset:0;z-index:0;
  background:linear-gradient(100deg,transparent 20%,rgba(227,185,78,.10) 45%,transparent 70%);
  transform:translateX(-100%);animation:skShimmer 1.5s infinite
}
/* Two things are layered here and they must not fight:
     1. a skeleton that fades each photo in once it has loaded, and
     2. the hover swap between the first and second photo.
   The first photo is the one the skeleton reveals. The second is positioned on
   top and stays fully transparent until hover — so its opacity is owned by the
   hover rules alone, never by .loaded. */
.card-media .cm-a{position:relative;z-index:1;opacity:0;transition:opacity .4s var(--ease)}
.card-media .cm-a.loaded{opacity:1}
.card-media:has(img.loaded)::before{display:none}
.card-media .cm-b{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:2;
  opacity:0;transform:scale(1.04);transition:opacity .45s var(--ease),transform .7s var(--ease)
}
.card-media .cm-a{transition:opacity .45s var(--ease),transform .7s var(--ease)}
@media (hover:hover){
  /* Only fade the first photo out when there is a second one behind it. Most
     products have a single image, and hiding it on hover left an empty frame —
     the customer saw the product vanish under the cursor. :has() scopes the
     rule to cards that actually have a .cm-b; the extra :not() rule is the
     fallback for browsers without :has(), where nothing fades at all rather
     than fading to nothing. */
  .card:hover .card-media:has(.cm-b) .cm-b{opacity:1;transform:scale(1)}
  .card:hover .card-media:has(.cm-b) .cm-a{opacity:0;transform:scale(1.04)}
}
/* touch: the swap happens on swipe, handled in app.js */
.card-media.show-b:has(.cm-b) .cm-b{opacity:1;transform:scale(1)}
.card-media.show-b:has(.cm-b) .cm-a{opacity:0}

/* a gold hairline that draws itself around the card */
.card{position:relative}
.card::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  border:1px solid transparent;
  background:linear-gradient(120deg,var(--gold),transparent 32%,transparent 68%,var(--gold)) border-box;
  -webkit-mask:linear-gradient(#000 0 0) padding-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) padding-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
  opacity:0;transition:opacity .4s var(--ease)
}
@media (hover:hover){ .card:hover::after{opacity:.85} }

/* ---- image placeholder while the photo loads ---- */
.sk{position:relative;overflow:hidden;background:var(--ink-3)}
.sk::before{
  content:"";position:absolute;inset:0;
  background:linear-gradient(100deg,transparent 20%,rgba(227,185,78,.10) 45%,transparent 70%);
  transform:translateX(-100%);animation:skShimmer 1.5s infinite
}
@keyframes skShimmer{to{transform:translateX(100%)}}
img.loaded + .sk,.sk.done::before{display:none}

/* ---- add to cart flies to the cart icon ---- */
.fly{
  position:fixed;z-index:1200;border-radius:10px;object-fit:cover;pointer-events:none;
  box-shadow:0 12px 30px rgba(0,0,0,.45);
  transition:transform .75s cubic-bezier(.4,0,.25,1),opacity .75s ease,width .75s ease,height .75s ease
}
.cart-pop{animation:cartPop .45s var(--ease)}
@keyframes cartPop{0%{transform:scale(1)}40%{transform:scale(1.28)}100%{transform:scale(1)}}

/* ---- sticky buy bar on the product page ---- */
.buybar{
  position:fixed;left:0;right:0;bottom:0;z-index:870;
  background:rgba(10,10,13,.96);backdrop-filter:blur(14px);border-top:1px solid var(--line);
  padding:10px clamp(12px,4vw,26px) calc(10px + env(safe-area-inset-bottom));
  transform:translateY(115%);transition:transform .45s var(--ease)
}
.buybar.in{transform:translateY(0)}
.buybar-in{max-width:1180px;margin:0 auto;display:flex;align-items:center;gap:14px}
.buybar img{width:42px;height:54px;object-fit:cover;border-radius:7px;flex-shrink:0}
.buybar .bb-t{flex:1;min-width:0}
.buybar .bb-n{font-size:14px;color:var(--white);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.buybar .bb-p{font-size:16px;font-weight:700;color:var(--gold)}
.buybar .btn{flex-shrink:0}
@media (max-width:520px){
  .buybar{bottom:calc(56px + env(safe-area-inset-bottom))}   /* clear the mobile nav */
  .buybar img{display:none}
  .buybar .bb-n{display:none}
}

/* ---- reading progress rail ---- */
/* Reading-progress bar. Named scroll-rail, not rail: the announcement strip
   already uses .rail for its scrolling row, and a bare .rail here silently
   turned that strip into a 2px fixed element — the whole bar collapsed. */
.scroll-rail{position:fixed;top:0;left:0;height:2px;z-index:1000;width:0;
  background:linear-gradient(90deg,var(--crimson),var(--gold));transition:width .1s linear}

/* ---- order success: a wax seal presses down ---- */
.seal{width:112px;height:112px;margin:0 auto 18px;position:relative;display:grid;place-items:center}
.seal-disc{
  position:absolute;inset:0;border-radius:48% 52% 45% 55%/50% 45% 55% 50%;
  background:radial-gradient(circle at 38% 34%,#E33B54,var(--crimson) 45%,var(--crimson-deep));
  box-shadow:inset 0 -8px 20px rgba(0,0,0,.4),0 8px 26px rgba(200,16,46,.35);
  animation:sealDrop .8s cubic-bezier(.3,1.5,.5,1) both
}
.seal img{width:66px;position:relative;z-index:1;animation:sealMark .5s ease .55s both}
@keyframes sealDrop{0%{transform:translateY(-70px) scale(1.5);opacity:0}60%{opacity:1}100%{transform:none;opacity:1}}
@keyframes sealMark{from{opacity:0;transform:scale(1.4)}to{opacity:1;transform:none}}
.seal-ring{position:absolute;inset:-6px;border-radius:50%;border:2px solid rgba(227,185,78,.55);
  opacity:0;animation:sealRing 1s cubic-bezier(.22,1,.36,1) .6s}
@keyframes sealRing{0%{opacity:.9;transform:scale(.7)}100%{opacity:0;transform:scale(1.7)}}

/* ---- empty cart: a resting lion ---- */
.rest{text-align:center;padding:44px 16px}
.rest img{width:110px;opacity:.30;animation:restBreathe 5s ease-in-out infinite}
@keyframes restBreathe{0%,100%{transform:scale(1);opacity:.30}50%{transform:scale(1.05);opacity:.42}}

/* ---- 404 ---- */
.lost img{width:120px;animation:lostLook 6s ease-in-out infinite}
@keyframes lostLook{0%,100%{transform:rotate(-5deg)}50%{transform:rotate(5deg)}}

@media (prefers-reduced-motion:reduce){
  .card-media .cm-a,.card-media .cm-b,.card::after,.fly,.buybar,.scroll-rail{transition:none!important}
  .sk::before,.cart-pop,.seal-disc,.seal img,.seal-ring,.rest img,.lost img{animation:none!important}
  .seal-disc,.seal img{opacity:1!important;transform:none!important}
  .buybar{transform:none}
}

/* ---------- collapsible shop filters (P2) ----------
   Measured before the change: on a 375px screen the first product began at
   926px, so nobody arriving from an ad saw a single item without scrolling.
   Below 860px the filters live behind a summary button; from 861px up the
   panel is forced open and the page looks exactly as it did. */
.filter-box{margin-bottom:26px}
.filter-box > summary{
  list-style:none;cursor:pointer;display:flex;align-items:center;gap:10px;
  padding:12px 16px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--ink-2);color:var(--mist);font-size:14.5px;font-weight:600
}
.filter-box > summary::-webkit-details-marker{display:none}
.filter-box > summary::before{
  content:"";width:16px;height:16px;flex-shrink:0;
  background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Cpath d='M3 5h18M6 12h12M10 19h4'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Cpath d='M3 5h18M6 12h12M10 19h4'/%3E%3C/svg%3E") center/contain no-repeat
}
.filter-box > summary::after{
  content:"";margin-left:auto;width:9px;height:9px;flex-shrink:0;
  border-right:2px solid var(--dim);border-bottom:2px solid var(--dim);
  transform:rotate(45deg);transition:transform .25s var(--ease)
}
.filter-box[open] > summary::after{transform:rotate(-135deg)}
.filter-box > summary:hover{border-color:var(--gold);color:var(--white)}
.filter-on{
  margin-left:6px;font-size:11.5px;padding:1px 9px;border-radius:20px;
  background:rgba(227,185,78,.16);color:var(--gold)
}
.filter-box > form{
  margin-top:12px;padding:18px;border:1px solid var(--line-soft);
  border-radius:var(--r);background:var(--ink-2)
}
@media (min-width:861px){
  /* Desktop keeps the old always-visible panel. A closed <details> hides its
     content in the browser's shadow DOM, so `display:block` on the form is not
     enough on its own — the summary is hidden AND the form is forced visible. */
  .filter-box > summary{display:none}
  .filter-box > form{display:block !important;margin-top:0;padding:22px}
  .filter-box{display:block}
}

/* ==========================================================================
   Depth pass — subtle 3D, not a gimmick
   The brand is a pressed gold seal on near-black. Real depth here means light
   behaving as it would on metal and card: a card that tips slightly toward the
   pointer, a gold rim that catches light on the side the cursor is on, and a
   hero mark that sits in front of the page rather than on it. Every effect is
   small enough to feel like craft rather than animation, and all of it is off
   for anyone who asked for reduced motion.
   ========================================================================== */

/* --- product cards tip toward the pointer --- */
@media (hover:hover) and (pointer:fine){
  body[data-mo-depth] .p-grid,body[data-mo-depth] .grid{perspective:1200px}
  /* One transform for the card, composed from parts, because two features want
     to move the same element: the scroll reveal slides it up into place, and
     hover lifts and tips it. Writing them as separate `transform` declarations
     meant whichever came later in the file simply erased the other — the
     reveal's settled `transform:none` was cancelling every tilt. Each effect
     now owns a variable instead. */
  body[data-mo-depth] .card{
    transform-style:preserve-3d;
    /* One transform, five owners, each with its own variable — the rule five
       collisions in this project taught. `--float` is the new one: a slow rise
       and fall that makes the card sit above the page rather than printed on
       it. It is added here and nowhere else, so it can never fight the reveal,
       the hover lift or the pointer tilt. */
    transform:translateY(calc(var(--rv-y,0px) + var(--lift,0px) + var(--float,0px)))
              rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg))
              scale(var(--card-scale,1));
    transition:transform .5s cubic-bezier(.22,1,.36,1),box-shadow .5s var(--ease)
  }
  body[data-mo-depth] .card:hover{
    --lift:-6px;
    box-shadow:0 26px 60px rgba(0,0,0,.55),0 0 0 1px rgba(227,185,78,.22)
  }
  /* the gold edge brightens on the side the pointer is on */
  .card::after{
    background:linear-gradient(var(--edge,120deg),var(--gold),transparent 34%,transparent 66%,var(--gold)) border-box
  }
  /* the title and price lift a hair in front of the photo */
  body[data-mo-depth] .card:hover .card-body{transform:translateZ(18px)}
  .card-body{transition:transform .5s cubic-bezier(.22,1,.36,1)}
}

/* --- the hero mark floats in front of the page --- */
.hero-mark{
  filter:drop-shadow(0 14px 40px rgba(227,185,78,.42))
         drop-shadow(0 40px 60px rgba(0,0,0,.55));
  transform-style:preserve-3d
}
@media (hover:hover) and (pointer:fine){
  body[data-mo-hero] .hero{perspective:1400px}
  body[data-mo-hero] .hero-mark{transition:transform .9s cubic-bezier(.22,1,.36,1)}
  body[data-mo-hero] .hero:hover .hero-mark{transform:rotateY(var(--hy,0deg)) rotateX(var(--hx,0deg)) translateZ(30px)}
}

/* --- buttons press like real objects --- */
.btn{transition:transform .18s var(--ease),box-shadow .28s var(--ease),background .3s,color .3s,border-color .3s}
.btn:active{transform:translateY(1px) scale(.985)}
.btn--gold:hover{box-shadow:0 10px 26px rgba(227,185,78,.28),inset 0 1px 0 rgba(255,255,255,.35)}

@media (prefers-reduced-motion:reduce){
  .card,.card-body,.hero-mark,.btn{transition:none!important;transform:none!important}
  .card:hover{transform:none!important}
}

/* --- the gold reveal: each section is pressed in like a seal ---
   A plain fade-up is what every template does. This draws a thin gold line
   across the section first, then lets the content rise through it — the same
   gesture as the wax seal on the order page, so scrolling the shop feels like
   the brand rather than like a generic animation library. */
body[data-mo-reveal] .rv{opacity:0}
@media (prefers-reduced-motion:no-preference){
  body[data-mo-reveal] .rv{
    opacity:0;--rv-y:26px;transform:translateY(var(--rv-y));
    transition:opacity .7s var(--ease),transform .7s cubic-bezier(.22,1,.36,1)
  }
  body[data-mo-reveal] .rv.seen{opacity:1;--rv-y:0px}
  /* a card composes its own transform above, so it must not be overwritten here */
  body[data-mo-reveal] .card.rv{transform:none}
  /* This restated the composed transform for a revealed card, which meant a new
     effect had to be added in two places or it silently lost — `--float` was
     written once and this more specific rule won, so cards computed a drift
     that never appeared on screen. It now adds `--float` too, and is the only
     other place the property is written. */
  body[data-mo-depth] .card.rv{
    transform:translateY(calc(var(--rv-y,0px) + var(--lift,0px) + var(--float,0px)))
              rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg))
              scale(var(--card-scale,1))
  }
  body[data-mo-reveal] .section{position:relative}
  body[data-mo-reveal] .section::before{
    content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:2;
    background:linear-gradient(90deg,transparent,var(--gold),transparent);
    transform:scaleX(0);transform-origin:50% 50%;opacity:0
  }
  body[data-mo-reveal] .section.seen::before{
    animation:sealLine 1.15s cubic-bezier(.22,1,.36,1) forwards
  }
}
@keyframes sealLine{
  0%{transform:scaleX(0);opacity:0}
  30%{opacity:.95}
  60%{transform:scaleX(1);opacity:.95}
  100%{transform:scaleX(1);opacity:0}
}

/* superseded by the richer reflection defined with .mark-wrap below */
@media (prefers-reduced-motion:reduce){
  body[data-mo-reveal] .rv{opacity:1!important;transform:none!important}
  }

/* --- phone hero: pull the composition up ---
   Measured on a 390×844 screen: 145px of dead space sat between the header and
   the mark while the buttons ended 223px short of the fold. The block was
   vertically centred in a hero taller than it needed to be. Sizing the hero to
   the space actually available and tightening the rhythm puts the mark, the
   words and both buttons in the first screen with the composition balanced. */
@media (max-width:640px){
  /* Sizing the hero to a full screen while packing the content upward left a
     dead band underneath. Let the hero be exactly as tall as its content needs,
     with a sensible floor, and centre what is there. */
  .hero{
    min-height:0;
    align-items:center;
    padding-block:26px 34px
  }
  .hero-in{padding-block:0}
  .hero-mark{width:clamp(96px,26vw,132px);margin-bottom:14px}
  .hero-slogan{margin-bottom:10px}
  .hero-title{margin-bottom:12px}
  .hero-sub{margin:12px auto 22px;max-width:34ch}
  .hero-cta{margin-top:4px}
  .hero-stats{margin-top:28px}
}
@supports not (height: 100svh){
  @media (max-width:640px){ .hero{min-height:calc(100vh - 102px)} }
}

/* --- touch equivalents of the pointer effects --- */
@media (hover:none),(pointer:coarse){
  body[data-mo-depth] .card{
    transition:transform .55s cubic-bezier(.22,1,.36,1),box-shadow .55s var(--ease);
    transform:translateY(4px) scale(.985)
  }
  body[data-mo-depth] .card.in-view{
    transform:none;
    box-shadow:0 20px 46px rgba(0,0,0,.5),0 0 0 1px rgba(227,185,78,.20)
  }
  body[data-mo-hero] .hero-mark{transition:transform .25s linear;will-change:transform}
}
@media (prefers-reduced-motion:reduce){
  body[data-mo-depth] .card{transform:none!important}
  }

/* ==========================================================================
   Home banner slots
   Ratios are fixed so any photograph the owner uploads lands tidily: the image
   fills the frame and is cropped, never stretched. The gold hairline and the
   dark mount match the product cards, so a banner reads as part of the shop
   rather than an advert pasted on top.
   ========================================================================== */
.bslot{padding-block:clamp(18px,3vw,34px)}
.btile{
  position:relative;overflow:hidden;border-radius:var(--r-lg);
  background:var(--ink-3);border:1px solid var(--line-soft);
  box-shadow:0 18px 44px rgba(0,0,0,.42)
}
.btile::after{  /* the same gold edge the cards use */
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:3;
  border:1px solid transparent;
  background:linear-gradient(120deg,rgba(227,185,78,.55),transparent 34%,transparent 66%,rgba(227,185,78,.55)) border-box;
  -webkit-mask:linear-gradient(#000 0 0) padding-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) padding-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;opacity:.5
}
.bwide{aspect-ratio:21/9}
.bduo{display:grid;grid-template-columns:1fr 1fr;gap:clamp(12px,2vw,20px)}
.bduo-item{aspect-ratio:4/5}
@media (max-width:760px){
  .bwide{aspect-ratio:16/9}
  .bduo{grid-template-columns:1fr}
  .bduo-item{aspect-ratio:16/10}
}

/* slides stack in one box, so nothing below moves as they change */
.bslide,.bslide-link{position:absolute;inset:0;display:block}
.bslide{opacity:0;transition:opacity .9s var(--ease);z-index:1}
.bslide.on{opacity:1;z-index:2}
.bslide img{width:100%;height:100%;object-fit:cover;display:block}
.bslide-link{z-index:1}
.bslide-link:has(.bslide.on){z-index:2}

/* caption sits on a gradient so text stays readable on any photograph */
.btile-cap{
  position:absolute;left:0;right:0;bottom:0;z-index:3;
  padding:clamp(16px,3vw,30px);
  background:linear-gradient(0deg,rgba(7,7,10,.88),rgba(7,7,10,.45) 55%,transparent);
  color:var(--white)
}
.btile-cap h3{
  margin:0 0 4px;font-family:var(--body);font-weight:700;
  font-size:clamp(17px,2.4vw,27px);line-height:1.28
}
.btile-cap p{margin:0 0 10px;font-size:clamp(12.5px,1.4vw,15px);color:var(--mist);max-width:46ch}
.btile-cap .btn{pointer-events:none}   /* the whole slide is already the link */

.bdots{position:absolute;right:14px;bottom:14px;z-index:4;display:flex;gap:7px}
.bdot{
  width:8px;height:8px;padding:0;border-radius:50%;cursor:pointer;
  border:1px solid rgba(255,255,255,.5);background:transparent;transition:all .3s var(--ease)
}
.bdot.on{background:var(--gold);border-color:var(--gold);width:22px;border-radius:5px}

@media (hover:hover) and (pointer:fine){
  .btile{transition:transform .5s cubic-bezier(.22,1,.36,1),box-shadow .5s var(--ease)}
  .btile:hover{transform:translateY(-4px);box-shadow:0 26px 58px rgba(0,0,0,.55)}
  .btile:hover::after{opacity:.9}
  .btile:hover .bslide.on img{transform:scale(1.03)}
  .bslide img{transition:transform 1.1s var(--ease)}
}
@media (prefers-reduced-motion:reduce){
  .bslide{transition:none}
  .btile,.bslide img{transition:none!important;transform:none!important}
}

/* ==========================================================================
   The promise coins
   Four pressed medallions rather than four boxes. The face carries the icon
   and the promise; the reverse carries the detail. They turn as the reader
   scrolls past, which means the second side is discovered rather than hidden
   behind a hover a phone can never perform. Gated on the same
   data-mo-depth switch as the rest of the depth work.
   ========================================================================== */
.promise{perspective:900px}
.promise-coin{
  position:relative;min-height:168px;
  transform-style:preserve-3d;
  transition:transform .9s cubic-bezier(.22,1,.36,1)
}
.promise-face,.promise-back{
  position:absolute;inset:0;display:grid;place-content:center;justify-items:center;
  gap:8px;padding:22px 18px;text-align:center;
  border:1px solid var(--line);border-radius:var(--r-lg);
  backface-visibility:hidden;-webkit-backface-visibility:hidden
}
.promise-face{
  background:
    radial-gradient(circle at 30% 22%,rgba(227,185,78,.10),transparent 58%),
    var(--ink-2);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 14px 34px rgba(0,0,0,.38)
}
.promise-back{
  transform:rotateY(180deg);
  background:
    radial-gradient(circle at 70% 26%,rgba(200,16,46,.16),transparent 60%),
    var(--ink-3);
  border-color:rgba(227,185,78,.34)
}
.promise-ico{font-size:30px;line-height:1;filter:drop-shadow(0 6px 14px rgba(227,185,78,.35))}
.promise-face b{color:var(--white);font-size:15.5px}
.promise-back p{margin:0;color:var(--mist);font-size:14px;line-height:1.65;max-width:24ch}

/* the rim catches light, like the wax seal on the order page */
.promise-face::after,.promise-back::after{
  content:"";position:absolute;inset:-1px;border-radius:inherit;pointer-events:none;
  background:linear-gradient(140deg,rgba(227,185,78,.55),transparent 38%,transparent 62%,rgba(227,185,78,.35)) border-box;
  -webkit-mask:linear-gradient(#000 0 0) padding-box,linear-gradient(#000 0 0);
          mask:linear-gradient(#000 0 0) padding-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;opacity:.5
}

/* turned by scroll (both phone and desktop), and by hover where there is one */
body[data-mo-depth] .promise.flip .promise-coin{transform:rotateY(180deg)}
@media (hover:hover) and (pointer:fine){
  body[data-mo-depth] .promise:hover .promise-coin{transform:rotateY(180deg)}
}
@media (prefers-reduced-motion:reduce){
  .promise-coin{transition:none}
  /* with no motion, show both sides stacked so nothing is unreachable */
  .promise-coin{min-height:0}
  .promise-face,.promise-back{position:static;transform:none;backface-visibility:visible}
  .promise-back{margin-top:8px}
}

/* ==========================================================================
   Inner pages: the same arrival the home page has
   Only the home page carried reveal markers, so shop, cart, checkout, track,
   contact and account felt static beside it. Rather than edit seven templates
   and risk breaking layouts that are already verified, the reveal is attached
   to the blocks those pages already use — .panel and .section — under the same
   admin switch. Nothing moves position; each block simply arrives.
   ========================================================================== */
@media (prefers-reduced-motion:no-preference){
  /* Both rules must carry the SAME specificity, or the hiding one wins and the
     block stays invisible for ever. A descendant chain like
     `.section > .wrap > .panel` scores higher than `.panel.seen`, which is
     exactly how content got stuck at opacity 0 on nine pages. One class each,
     revealed state written afterwards. */
  body[data-mo-reveal] .panel{
    opacity:0;--rv-y:20px;transform:translateY(var(--rv-y));
    transition:opacity .65s var(--ease),transform .65s cubic-bezier(.22,1,.36,1)
  }
  body[data-mo-reveal] .panel.seen{opacity:1;--rv-y:0px}

  /* the page heading leads, the content follows a beat later */
  body[data-mo-reveal] .sec-head,
  body[data-mo-reveal] .page-head{
    opacity:0;transform:translateY(14px);
    transition:opacity .6s var(--ease),transform .6s cubic-bezier(.22,1,.36,1)
  }
  body[data-mo-reveal] .sec-head.seen,
  body[data-mo-reveal] .page-head.seen{opacity:1;transform:none}
}

/* --- the product photo answers the pointer, like a fabric held to the light --- */
@media (hover:hover) and (pointer:fine){
  body[data-mo-depth] .gal-main{perspective:1100px}
  body[data-mo-depth] .gal-main img{
    transition:transform .55s cubic-bezier(.22,1,.36,1);
    transform:rotateX(var(--grx,0deg)) rotateY(var(--gry,0deg)) scale(var(--gs,1))
  }
  body[data-mo-depth] .gal-main:hover img{--gs:1.06}
  /* a soft highlight tracks the cursor across the glass */
  body[data-mo-depth] .gal-main::after{
    content:"";position:absolute;inset:0;pointer-events:none;z-index:3;opacity:0;
    transition:opacity .4s var(--ease);
    background:radial-gradient(220px circle at var(--gx,50%) var(--gy,50%),
               rgba(255,245,215,.16),transparent 62%)
  }
  body[data-mo-depth] .gal-main:hover::after{opacity:1}
}
@media (prefers-reduced-motion:reduce){
  body[data-mo-reveal] .panel,
  body[data-mo-reveal] .sec-head,
  body[data-mo-reveal] .page-head{opacity:1!important;transform:none!important}
  body[data-mo-depth] .gal-main img{transform:none!important}
}

/* Safety net. If IntersectionObserver never fires — an old browser, a blocked
   script, an element created after the sweep — content must not be left
   invisible. The script adds `mo-ready` to <html> once it has taken over; until
   then everything is simply visible. */
html:not(.mo-ready) body[data-mo-reveal] .panel,
html:not(.mo-ready) body[data-mo-reveal] .sec-head,
html:not(.mo-ready) body[data-mo-reveal] .page-head,
html:not(.mo-ready) body[data-mo-reveal] .rv{opacity:1;transform:none}

/* The gaze wrapper: an image cannot hold children, so the script wraps the mark
   in this span. It must behave exactly like the image did or the hero shifts. */
/* The glints must ride WITH the mark, not beside it. The image is what moves —
   hero rotation on a pointer, scroll drift on a phone — so if the glints sit in
   a static wrapper they drift off the eyes as soon as anything animates. Moving
   the transform onto the wrapper makes the mark and its glints one object: they
   rotate and scale together and the light stays on the eyes on every device. */
/* The wrapper must be EXACTLY the image's box, because the glints are placed
   with percentages of it. The mark carries a bottom margin, and inside an
   inline-block that margin made the wrapper 22px taller than the image on
   desktop and 14px taller on a phone — which pushed both glints below the eyes,
   further on the smaller screen. The margin now lives on the wrapper, and the
   image is flush inside it. */
.mark-wrap{
  position:relative;display:block;width:fit-content;margin-inline:auto;
  line-height:0;font-size:0;transform-style:preserve-3d
}
.mark-wrap > .hero-mark{display:block;margin:0!important;transform:none!important}

/* the wrapper now carries what the image used to */
/* The mark's transform is written by the animation loop and by nothing else.
   The hover rule and the transition that used to live here were exactly the
   "two owners" problem that made the motion stick. */


/* a coin the customer has tapped stays turned until tapped again */
body[data-mo-depth] .promise{cursor:pointer}
@media (hover:none),(pointer:coarse){
  body[data-mo-depth] .promise{-webkit-tap-highlight-color:transparent}
}

/* ---- scroll cue ----
   On a phone the hero is now sized to its content, so an absolutely positioned
   cue landed on top of the statistics row. It is redundant on touch — people
   scroll without being asked — so it is simply not shown there. */
@media (max-width:640px){ .scroll-hint{display:none} }

/* ==========================================================================
   Ambient背景 motion — a slow shift of light behind the page
   The brand is gold on near-black. Rather than add shapes, the existing glow
   drifts very slowly, the way light moves across metal in a room. It is large,
   soft and slow enough never to compete with the product photographs, costs
   nothing to composite, and works identically on every device because it is a
   single background-position animation. Governed by the hero switch.
   ========================================================================== */
body[data-mo-hero]::before{
  content:"";position:fixed;inset:-20% -20% -20% -20%;z-index:0;pointer-events:none;
  background:
    radial-gradient(38vmax 30vmax at 18% 12%,rgba(200,16,46,.075),transparent 60%),
    radial-gradient(34vmax 28vmax at 82% 78%,rgba(227,185,78,.055),transparent 62%),
    radial-gradient(30vmax 26vmax at 60% 30%,rgba(227,185,78,.035),transparent 65%);
  animation:ambientDrift 46s ease-in-out infinite alternate;
  will-change:transform
}
@keyframes ambientDrift{
  0%  {transform:translate3d(0,0,0) scale(1)}
  50% {transform:translate3d(2.2%,-1.8%,0) scale(1.06)}
  100%{transform:translate3d(-1.6%,2.2%,0) scale(1.02)}
}
/* content must sit above it */
/* Lift page content above the ambient background layer.
   Only elements that are STATIC may be given position:relative here. The header
   is sticky, and the bottom bar, the contact cluster and the chat panel are
   fixed — writing `position:relative` on those detached them from the viewport
   and dropped the bottom bar into the footer, which is exactly what happened
   when this rule was widened. They are already positioned, so they need the
   z-index alone. */
.hero,.section,.site-foot{position:relative;z-index:1}
.site-head,.mbar,.talk,.chat-box,.chat-fab,.buybar,.to-top{z-index:auto}
.site-head{z-index:60}
.mbar{z-index:868}
.buybar{z-index:870}
.to-top{z-index:869}
.chat-box{z-index:881}
.chat-fab,.talk{z-index:882}

@media (prefers-reduced-motion:reduce){
  body[data-mo-hero]::before{animation:none}
}

/* ==========================================================================
   A mark that is alive
   The previous version fought itself: a CSS keyframe animation, a 1.4s
   transition on `transform`, and a script that jumped to a new position every
   few seconds. Between the jumps nothing moved, and the transition tried to
   catch up afterwards — which is exactly why it looked like it kept sticking.
   All of that is gone. A single script now writes the transform every frame, so
   the motion is continuous by construction; there is nothing here to interrupt
   it, and no transition to lag behind.
   ========================================================================== */
.mark-wrap{
  transform-origin:50% 54%;
  will-change:transform;
  backface-visibility:hidden           /* keeps the gold crisp while it turns */
}
@media (prefers-reduced-motion:reduce){
  .mark-wrap{transform:none!important}
}

/* the spacing the mark used to provide, now on its wrapper */
/* room for the mark to drift into without touching the slogan */
.mark-wrap{margin-bottom:clamp(26px,3.2vw,34px)}
@media (max-width:640px){ .mark-wrap{margin-bottom:24px} }

/* ==========================================================================
   Price row on a phone
   Measured on a 390px screen: the card is 173px wide, the row has 139px of it,
   and price + old price + discount badge needed 161px — so the badge, and then
   the old price, dropped onto their own lines. Nothing was wrong with the
   wrapping; the three parts were simply carrying desktop sizes.
   These sizes fit all three on one line with room to spare, and the badge is
   allowed to shrink last if a price is unusually long.
   ========================================================================== */
@media (max-width:640px){
  /* These were shrunk to fit price + old price + badge on one line. They fit,
     but 9.5px is below what anyone can comfortably read on a phone — a saving
     the customer cannot read is not a saving. The row now drops the old price
     to a second line if it must, rather than shrinking the type further. */
  .card-price{gap:3px 7px;flex-wrap:wrap;align-items:baseline}
  .card-price .now{font-size:16px;letter-spacing:-.01em;flex:0 0 auto}
  .card-price .was{font-size:12px}
  .card-price .off{font-size:11.5px;padding:2px 7px;border-radius:20px;flex:0 0 auto}
}
/* Below 400px the card is too narrow for price + old price + badge at sizes a
   phone can read. Rather than shrink the type to 9px — which is a saving the
   customer cannot actually read — the struck-through original is dropped here.
   The badge still states the discount, and the full comparison is on the
   product page where there is room for it. */
@media (max-width:399px){
  .card-price .was{display:none}
  /* if a shop ever prices something in six figures, the row wraps rather than
     spilling out of the card — correctness before compactness */
  .card-price:has(.now:only-child){flex-wrap:wrap}
}
/* Tablets sit between the two sets of sizes: the grid is still three or four
   across, so the cards are as narrow as a phone's while the desktop type sizes
   still apply. Measured at 768px: three rows were wrapping. */
@media (min-width:641px) and (max-width:900px){
  .card-price{gap:4px 7px;flex-wrap:nowrap}
  .card-price .now{font-size:16px}
  .card-price .was{font-size:11.5px}
  .card-price .off{font-size:11px;padding:2px 6px;flex-shrink:1;min-width:0}
}

@media (max-width:360px){
  .card-price .now{font-size:15.5px}
  .card-price .off{font-size:11px;padding:2px 6px}
}

/* ==========================================================================
   Product cards on a phone — motion that sells rather than decorates
   A phone shows two cards at a time, so the eye is always on one pair. As a
   pair reaches the middle of the screen the photograph settles into place and
   lifts very slightly toward the reader, the gold frame catches light, and the
   price warms up. Everything is small and quick — the point is that the garment
   feels handled, not that the page performs. Phones only, and silent when the
   customer has asked for reduced motion.
   ========================================================================== */
@media (hover:none),(pointer:coarse){
  body[data-mo-depth] .card{
    transition:transform .5s cubic-bezier(.22,1,.36,1),box-shadow .5s var(--ease),border-color .5s var(--ease)
  }
  body[data-mo-depth] .card .card-media img{
    transition:transform .8s cubic-bezier(.22,1,.36,1),filter .8s var(--ease);
    transform:scale(1.04);filter:saturate(.92) brightness(.94)
  }
  body[data-mo-depth] .card.in-view .card-media img{
    transform:scale(1);filter:none
  }
  /* the gold rim brightens on the card being read */
  body[data-mo-depth] .card.in-view{border-color:rgba(227,185,78,.30)}
  body[data-mo-depth] .card .card-price .now{transition:color .6s var(--ease),transform .6s var(--ease)}
  body[data-mo-depth] .card.in-view .card-price .now{color:var(--gold-hi,#F2CE72)}

  /* pressing a card acknowledges the touch, the way a physical control would */
  body[data-mo-depth] .card:active{transform:scale(.985)}
  body[data-mo-depth] .card-media{overflow:hidden}
}
@media (prefers-reduced-motion:reduce){
  body[data-mo-depth] .card .card-media img{transform:none;filter:none;transition:none}
}

/* ==========================================================================
   Nothing may hide behind the fixed bars
   Two things are pinned to the bottom on a phone: the mobile nav on every page,
   and the sticky buy bar on a product page. The page had no allowance for
   either, so the footer's last row — terms, privacy, returns — sat underneath
   them, half cut. Reserve the height instead of guessing at a magic number.
   ========================================================================== */
@media (max-width:860px){
  body{--bottom-bars:calc(64px + env(safe-area-inset-bottom))}
  /* a product page carries the buy bar as well */
  body:has(.buybar){--bottom-bars:calc(134px + env(safe-area-inset-bottom))}
  .site-foot{padding-bottom:var(--bottom-bars)}
}
/* Fallback for browsers without :has() — the product page's own class, so the
   allowance is still made rather than the footer being clipped. */
@media (max-width:860px){
  .page-product .site-foot{padding-bottom:calc(134px + env(safe-area-inset-bottom))}
}

/* ==========================================================================
   Customers' own words
   A quiet wall of quotes rather than a carousel: a carousel hides most of what
   it holds and demands the reader wait. On a phone the cards slide horizontally
   under the thumb — the gesture people already use — and on a desktop they sit
   as a row that reveals itself as it is reached.
   ========================================================================== */
.voices{position:relative}
.voice-rail{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(268px,1fr);
  gap:16px;overflow-x:auto;scroll-snap-type:x mandatory;
  padding:4px 2px 14px;margin-inline:-2px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch
}
.voice-rail::-webkit-scrollbar{display:none}
@media (min-width:900px){
  .voice-rail{grid-auto-flow:row;grid-template-columns:repeat(3,1fr);overflow:visible}
}

.voice{
  position:relative;scroll-snap-align:start;margin:0;
  padding:26px 22px 20px;border-radius:var(--r-lg);
  border:1px solid var(--line);
  background:
    radial-gradient(120% 90% at 12% 0%,rgba(227,185,78,.055),transparent 58%),
    var(--ink-2);
  box-shadow:0 14px 34px rgba(0,0,0,.32);
  transition:transform .5s cubic-bezier(.22,1,.36,1),border-color .5s var(--ease),box-shadow .5s var(--ease)
}
/* the gold rim answers the pointer, the same language the product cards use */
@media (hover:hover) and (pointer:fine){
  body[data-mo-depth] .voice:hover{
    transform:translateY(-5px);
    border-color:rgba(227,185,78,.34);
    box-shadow:0 22px 48px rgba(0,0,0,.44)
  }
}
.voice-quote{
  position:absolute;top:6px;right:18px;font-family:var(--head);
  font-size:64px;line-height:1;color:rgba(227,185,78,.16);pointer-events:none
}
.voice-stars{display:flex;gap:3px;margin-bottom:10px;font-size:13px;color:rgba(255,255,255,.22)}
.voice-stars i{font-style:normal}
.voice-stars i.on{color:var(--gold)}
.voice blockquote{
  margin:0 0 14px;color:var(--mist);font-size:14.5px;line-height:1.75;
  /* the quote sets the card's height, so a long one never spills */
  display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden
}
.voice figcaption{display:flex;flex-direction:column;gap:2px;font-size:13px}
.voice figcaption b{color:var(--white);font-size:14px}
.voice figcaption a{color:var(--dim);text-decoration:none;transition:color .25s}
.voice figcaption a:hover{color:var(--gold)}

/* each card arrives a beat after the one before it */
body[data-mo-reveal] .voice{transition-delay:calc(var(--vi,0) * 70ms)}

@media (prefers-reduced-motion:reduce){
  .voice{transition:none!important;transform:none!important}
  .voice-rail{scroll-snap-type:none}
}

/* ==========================================================================
   "What you were looking at"
   A single row that scrolls sideways rather than a grid: this is a reminder,
   not a collection, so it should take one line and get out of the way.
   ========================================================================== */
.seen-rail{
  display:grid;grid-auto-flow:column;grid-auto-columns:minmax(168px,1fr);
  gap:14px;overflow-x:auto;scroll-snap-type:x proximity;
  padding-bottom:10px;scrollbar-width:none
}
.seen-rail::-webkit-scrollbar{display:none}
.seen-rail > .card{scroll-snap-align:start}
@media (min-width:900px){
  /* On a desktop the rail stops being a scroller and becomes a grid. The old
     rule left `grid-auto-columns` in place while switching to `row` flow, which
     made auto-fit resolve to a single 1280px column — one enormous card with a
     1700px-tall photograph. Reset the auto sizing so the template can work. */
  .seen-rail{
    overflow:visible;
    grid-auto-flow:row;
    grid-auto-columns:auto;
    grid-template-columns:repeat(auto-fill,minmax(210px,1fr))
  }
}

/* ==========================================================================
   Section headings: a thread of gold draws itself under each title
   The eyebrow rules already carry a short line. This continues the idea to the
   title, so a heading arrives rather than simply being there — the same wax-seal
   gesture as the rest of the page, at the smallest possible scale.
   ========================================================================== */
.sec-title,
.section .h-lg{position:relative;display:inline-block}
.sec-title::after,
.section .h-lg::after{
  content:"";position:absolute;left:0;bottom:-9px;height:1px;width:100%;
  transform-origin:left center;transform:scaleX(0);
  background:linear-gradient(90deg,var(--gold),rgba(227,185,78,.15) 62%,transparent);
  transition:transform 1.05s cubic-bezier(.22,1,.36,1) .12s
}
/* the heading carries .rv, so the reveal observer already marks it .seen —
   the thread draws itself at the moment the heading arrives */
.sec-title.seen::after,
.section .h-lg.seen::after,
.sec-head.seen .sec-title::after{transform:scaleX(1)}
/* with motion off the line is simply there */
@media (prefers-reduced-motion:reduce){
  .sec-title::after,.section .h-lg::after{transform:scaleX(1);transition:none}
}

/* ==========================================================================
   Return to the top — a pressed seal rather than an arrow
   The home page is long now. This appears once the reader is well past the fold
   and sits clear of the chat button and the bottom bars.
   ========================================================================== */
/* Back to the top.
   It used to sit directly above the chat button, so a phone showed a column of
   two circles in the same corner with 18px between them — and on a product page
   the buy bar pushed both up into the order form, where the chat button landed
   on the address field. One floating control per corner: the chat button keeps
   the right, this takes the left, and neither covers what the other is near. */
.to-top{
  position:fixed;z-index:869;left:16px;right:auto;
  bottom:calc(78px + var(--fab-lift,0px) + env(safe-area-inset-bottom));
  width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  border:1px solid rgba(227,185,78,.38);color:var(--gold);cursor:pointer;
  background:radial-gradient(circle at 34% 26%,rgba(30,30,38,.98),rgba(12,12,16,.98));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.10),0 10px 24px rgba(0,0,0,.45);
  opacity:0;transform:translateY(14px) scale(.9);pointer-events:none;
  transition:opacity .4s var(--ease),transform .5s cubic-bezier(.22,1,.36,1),border-color .3s
}
.to-top.on{opacity:1;transform:none;pointer-events:auto}
.to-top:hover{border-color:var(--gold);color:#F6DE9C}
.to-top svg{display:block}
@media (min-width:861px){
  /* On a desktop it returns to the familiar right-hand corner — but it must
     clear the chat button, which sits there too. Stacking them at 96px put the
     two on top of each other; this lifts it a full button's height above. */
  /* The chat button is lifted by --fab-lift whenever the buy bar is showing, so
     a fixed offset here collides on a product page. Stack from the same base:
     the chat button sits at 84px + lift, this clears it by a full button. */
  .to-top{left:auto;right:26px;bottom:calc(154px + var(--fab-lift,0px))}
}
@media (prefers-reduced-motion:reduce){ .to-top{transition:none} }

/* ==========================================================================
   The strip banner
   A short full-width band for a single sentence and a button. The wide banner
   is 21:9 and takes most of a phone screen; this one is 3:1 there, so an offer
   can be announced without pushing the products out of view.
   ========================================================================== */
.bstrip{aspect-ratio:5/1}
@media (max-width:860px){ .bstrip{aspect-ratio:3/1} }
/* the caption sits centred rather than bottom-left: on a band this short the
   corner placement reads as an accident */
.bstrip .btile-cap{
  inset:0;display:grid;place-content:center;justify-items:center;
  text-align:center;padding:14px 18px;gap:8px;
  background:linear-gradient(90deg,rgba(7,7,10,.62),rgba(7,7,10,.28) 45%,rgba(7,7,10,.62))
}
.bstrip .btile-cap h3{font-size:clamp(17px,2.4vw,27px);margin:0}
.bstrip .btile-cap p{display:none}          /* a subtitle would crowd the band */
@media (min-width:861px){ .bstrip .btile-cap p{display:block;margin:0;font-size:14px} }
.bslot--strip{padding-block:clamp(18px,2.6vw,34px)}

/* ==========================================================================
   Card meta: sizes and a low-stock line
   Quiet by design — these answer a question, they do not shout. The sizes read
   as small pressed tokens; the stock line only appears when it is genuinely low,
   because a warning that is always on stops being read.
   ========================================================================== */
.card-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;margin-top:9px}
.card-sizes{display:flex;flex-wrap:wrap;gap:4px}
.card-sizes i{
  font-style:normal;font-size:11.5px;line-height:1;letter-spacing:.02em;
  color:var(--dim);border:1px solid var(--line);border-radius:5px;
  padding:3px 6px;background:rgba(255,255,255,.02);transition:.25s
}
.card:hover .card-sizes i{border-color:rgba(227,185,78,.28);color:var(--mist)}
.card-sizes i.more{border-style:dashed}
.card-left{
  font-size:11px;color:#F0B4B4;
  display:inline-flex;align-items:center;gap:5px
}
.card-left::before{
  content:"";width:5px;height:5px;border-radius:50%;background:var(--crimson);
  box-shadow:0 0 0 0 rgba(200,16,46,.55);animation:leftPulse 2.4s ease-out infinite
}
@keyframes leftPulse{
  0%{box-shadow:0 0 0 0 rgba(200,16,46,.5)}
  70%{box-shadow:0 0 0 7px rgba(200,16,46,0)}
  100%{box-shadow:0 0 0 0 rgba(200,16,46,0)}
}
@media (max-width:640px){
  .card-meta{gap:5px 8px;margin-top:7px}
  .card-sizes i{font-size:11px;padding:3px 6px}
  .card-left{font-size:11.5px}
}
@media (prefers-reduced-motion:reduce){ .card-left::before{animation:none} }

/* ==========================================================================
   The three assurances
   Deliberately quiet: this band has to be believed, not admired. No animation
   beyond the arrival, no colour beyond the brand's own gold on the mark.
   ========================================================================== */
.assure-row{
  display:grid;gap:12px;
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr))
}
.assure-card{
  display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;
  column-gap:13px;row-gap:3px;align-items:start;
  padding:16px 18px;border-radius:var(--r-lg);
  border:1px solid var(--line);
  background:linear-gradient(150deg,rgba(227,185,78,.045),transparent 62%),var(--ink-2);
  transition:border-color .35s var(--ease),transform .45s cubic-bezier(.22,1,.36,1)
}
@media (hover:hover) and (pointer:fine){
  body[data-mo-depth] .assure-card:hover{transform:translateY(-3px);border-color:rgba(227,185,78,.30)}
}
.assure-mark{
  grid-row:1 / span 2;width:38px;height:38px;border-radius:50%;
  display:grid;place-items:center;font-size:17px;line-height:1;color:var(--gold);
  border:1px solid rgba(227,185,78,.34);
  background:radial-gradient(circle at 34% 28%,rgba(227,185,78,.14),transparent 68%)
}
.assure-card b{color:var(--white);font-size:15px;line-height:1.35}
.assure-card p{margin:0;color:var(--dim);font-size:13.5px;line-height:1.6}
body[data-mo-reveal] .assure-card{transition-delay:calc(var(--ai,0) * 80ms)}
@media (max-width:640px){
  .assure-row{gap:10px}
  .assure-card{padding:14px 15px;column-gap:11px}
  .assure-mark{width:34px;height:34px;font-size:15px}
  .assure-card b{font-size:14.5px}
  .assure-card p{font-size:13px}
}
@media (prefers-reduced-motion:reduce){ .assure-card{transition:none!important;transform:none!important} }

/* the WhatsApp order button: its own green, so it is recognised instantly,
   but sized and shaped like every other button on the page */
.btn--wa{
  width:100%;margin-top:11px;gap:9px;
  background:linear-gradient(135deg,#3FA96B,#1F7A48);
  border-color:rgba(63,169,107,.5);color:#fff
}
.btn--wa:hover{
  background:linear-gradient(135deg,#48BC79,#238653);
  border-color:rgba(72,188,121,.7);color:#fff
}
.btn--wa svg{flex-shrink:0}

/* ==========================================================================
   The product page must be able to shrink
   A grid item defaults to `min-width: auto`, which means it refuses to become
   narrower than its widest content. On the product page that content is the
   thumbnail strip: with one or two photos it fitted, but once the owner
   uploaded six the strip's intrinsic width (494px) became the column's minimum,
   and on a 390px phone everything inside — the size row, the "সাইজ চার্ট" link,
   the option labels — was pushed past the screen edge and clipped by the
   section above it. That is why this only appeared after real photos went up.

   Allowing the columns to shrink lets the thumbnail strip do what it was
   already built to do: scroll sideways inside its own box.
   ========================================================================== */
.pdp{min-width:0}
.pdp > *{min-width:0}
.pdp .gal-thumbs{max-width:100%}
/* the same guard wherever a strip of variable length sits in a grid or flex
   child, so a long size list or colour list cannot widen its column either */
.opt-group,.opt-label,.opt-row,.gal,.gal-main{min-width:0;max-width:100%}
.opt-label{gap:12px}
.opt-label a{flex-shrink:0}
.opt-label span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ==========================================================================
   Product page: rows that scroll must LOOK like they scroll
   With one or two photos nothing overflowed, so this never showed in testing.
   With five or six the thumbnail strip runs off the screen and the last one is
   sliced in half at the edge — which reads as a broken layout rather than as
   "there is more this way". Two things fix that: the strip is given the page's
   own padding so a thumbnail can always be scrolled fully into view, and the
   right edge is faded so the cut is deliberate.
   ========================================================================== */
.gal-thumbs{
  scroll-snap-type:x proximity;
  scroll-padding-inline:var(--gut,16px);
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch
}
.gal-thumbs::-webkit-scrollbar{display:none}
.gal-thumbs > *{scroll-snap-align:start;flex:0 0 auto}
/* a little room after the last thumbnail so it never sits flush against the cut */
.gal-thumbs::after{content:"";flex:0 0 4px}
@media (max-width:860px){
  /* The strip stays inside the page's own margins rather than bleeding to the
     screen edge. A first attempt pulled it full-width with negative margins,
     but as a flex child only the left side expanded — it started at 0 and still
     ended at 358, which looks worse than either choice made properly. Kept
     within the text column, with the right edge faded so it is clear the row
     continues. */
  .gal-thumbs{
    -webkit-mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 30px),transparent 100%);
            mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 30px),transparent 100%)
  }
}

/* the tab row scrolls for the same reason and gets the same treatment */
.tabs{scroll-snap-type:x proximity;scroll-padding-inline:4px;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tabs > *{scroll-snap-align:start;flex:0 0 auto}
@media (max-width:860px){
  .tabs{
    -webkit-mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 28px),transparent 100%);
            mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 28px),transparent 100%)
  }
}

/* ---- the option label ----
   "সাইজ নির্বাচন করুন" and the "সাইজ চার্ট" link sat on one line with only a few
   pixels to spare; on a slightly narrower phone, or with a longer label, the
   link was pushed off the right edge and clipped away silently. It now wraps
   instead of being cut, and neither side can force the row wider than the page. */
.opt-label{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;min-width:0}
.opt-label > *{min-width:0}
.opt-label > :first-child{flex:1 1 auto}
.opt-label > a{flex:0 0 auto;white-space:nowrap}

/* ==========================================================================
   Touch targets on a phone
   Several links were only 15–24px tall. They are readable, but a thumb misses
   them — and a missed tap on "সাইজ চার্ট" or a breadcrumb is a customer who
   gives up rather than tries again. The text stays the same size; the tappable
   area around it grows, which costs nothing visually.
   ========================================================================== */
@media (max-width:860px){
  .opt-label a{
    display:inline-flex;align-items:center;min-height:32px;padding:4px 2px;
    margin:-4px -2px               /* the box grows, the layout does not shift */
  }
  .crumbs a,.crumbs span{display:inline-flex;align-items:center;min-height:30px}
  .foot-grid a:not(.socials a){min-height:32px;display:flex;align-items:center;padding-block:2px}
  .foot-legal a{display:inline-flex;align-items:center;min-height:30px;padding-inline:4px}
  /* the contact details on the contact page are links people actually press */
  .contact-list a{display:inline-flex;align-items:center;min-height:32px}
}

/* ==========================================================================
   Tap targets on a phone
   Several links sat only 16px tall — the breadcrumb trail, the "নতুন অ্যাকাউন্ট
   খুলুন" line under the login form, the footer's policy links. A finger pad is
   about 9mm; a 16px target is missed often enough to lose a customer who was
   already halfway to buying. These give each link a comfortable hit area
   WITHOUT changing how it looks: the text stays where it is, the box around it
   grows. Applied on touch devices only, so the desktop layout is untouched.
   ========================================================================== */
@media (hover:none),(pointer:coarse){
  /* Links sitting INSIDE a sentence — these must stay inline, or the sentence
     breaks apart around them. */
  .center a,.muted a,p a:not(.btn),.foot-legal a,.crumbs a{
    display:inline-flex;align-items:center;
    min-height:34px;                  /* the box grows, the type does not */
    padding-block:4px
  }
  /* the phone number and email on the contact page exist to be tapped —
     they open the dialler and the mail app, so they matter more than most */
  /* Text links only. This rule is about a phone number or an email written in a
     sentence — it must never touch a link that is already a laid-out control.
     The chat button is an <a href="…wa.me…">, so an unqualified selector turned
     its grid centring into inline-flex and added padding, shifting the icon 15px
     left of centre. Excluding anything with a class went too far the other way —
     a phone number styled `.gold-text` is still a text link and lost its hit
     area — so only the actual controls are named. */
  /* Round icon buttons centre their own icon and must never be padded. The
     footer's WhatsApp icon only started matching this rule once the number
     began resolving to a wa.me address — a fix in one place reaching an element
     in another, which is the shape of fault this stylesheet keeps producing.
     Every laid-out control is now named, not just the ones that matched before. */
  a[href^="tel:"]:not(.btn):not(.chat-fab):not(.talk-opt):not(.socials a),
  a[href^="mailto:"]:not(.btn):not(.chat-fab):not(.talk-opt):not(.socials a),
  a[href*="wa.me"]:not(.btn):not(.chat-fab):not(.talk-opt):not(.socials a){
    display:inline-flex;align-items:center;min-height:36px;padding-block:5px
  }

  /* a card's photo is already a large target, but the title is what people
     actually aim at when the photo is above the fold */
  .card-title{display:block;min-height:30px;padding-block:3px}

  /* The footer's column links are each their own row — they are `display:block`
     by default. Including them in the inline-flex rule above ran the whole
     column together into one paragraph ("আমাদের গল্প আমাদের সম্পর্কে অর্ডার
     ট্র্যাকিং…"), which read as if the links had gone missing. They stay
     block-level here; only the height grows. */
  /* The social icons live inside .foot-grid too, but they are round buttons that
     already centre their own icon — adding padding pushed it 9.5px below centre.
     Column links only. */
  .foot-grid a:not(.socials a){display:flex;align-items:center;min-height:38px;padding-block:6px}
  /* keep the legal row tidy: it wraps rather than stretching the footer */
  .foot-legal{display:flex;flex-wrap:wrap;justify-content:center;gap:2px 18px}
}

/* The hero's background artwork is decoration, not content.
   It is already clipped by `.hero`, so it causes no overflow — but it was still
   interactive and still read by a screen reader. Neither is wanted from a
   painted sun: a tap that lands on it should fall through to whatever is
   underneath, and the mark itself already carries the brand's name. */
.hero-bg,.hero-bg *{pointer-events:none}

/* follow the brand — quiet, and only as wide as it needs to be */
.follow-box{
  display:flex;flex-wrap:wrap;gap:16px 24px;align-items:center;justify-content:space-between;
  padding:22px 24px;border-radius:var(--r-lg);border:1px solid var(--line);
  background:linear-gradient(120deg,rgba(227,185,78,.05),transparent 60%),var(--ink-2)
}
.follow-box h2{margin:2px 0 4px}
.follow-box p{margin:0;font-size:14px}
.follow-links{display:flex;flex-wrap:wrap;gap:10px}
@media (max-width:640px){
  .follow-box{padding:18px 16px;gap:14px}
  .follow-links{width:100%}
  .follow-links .btn{flex:1 1 auto;min-width:44%}
}

/* a customer's own photo, leading their review */
.voice-shot{
  display:block;margin:-4px -4px 14px;border-radius:12px;overflow:hidden;
  border:1px solid var(--line);background:var(--ink-3);aspect-ratio:4/3
}
.voice-shot img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s var(--ease)}
@media (hover:hover) and (pointer:fine){ .voice:hover .voice-shot img{transform:scale(1.04)} }

/* ==========================================================================
   News & articles
   Cards that read as journalism rather than as more product tiles: a wide lead
   image, a tag, a headline that is allowed to be long, and a date. The image
   box is a fixed ratio so a mixed set of uploads — portrait phone photos and
   wide press shots together — still lines up in a tidy grid.
   ========================================================================== */
.news-grid{
  display:grid;gap:18px;
  /* auto-FILL, not auto-fit: with one article auto-fit collapses the empty
     tracks and stretches that single card across the whole 1280px row, which is
     how a news card ended up with a 799px-tall photograph. auto-fill keeps the
     tracks, so one article is the size of one card. */
  grid-template-columns:repeat(auto-fill,minmax(288px,1fr))
}
/* a card is never wider than it needs to be, however few there are */
.news-card{max-width:520px}
@media (min-width:900px){ .news-grid{gap:22px} }
.news-card{
  display:flex;flex-direction:column;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r-lg);
  background:linear-gradient(160deg,rgba(227,185,78,.045),transparent 55%),var(--ink-2);
  transition:transform .5s cubic-bezier(.22,1,.36,1),border-color .4s var(--ease),box-shadow .5s var(--ease)
}
@media (hover:hover) and (pointer:fine){
  body[data-mo-depth] .news-card:hover{
    transform:translateY(-5px);border-color:rgba(227,185,78,.32);
    box-shadow:0 24px 52px rgba(0,0,0,.42)
  }
}
.news-shot{
  position:relative;display:block;aspect-ratio:16/10;overflow:hidden;background:var(--ink-3)
}
.news-shot img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .7s var(--ease)}
@media (hover:hover) and (pointer:fine){ .news-card:hover .news-shot img{transform:scale(1.05)} }
.news-shot-empty{
  position:absolute;inset:0;display:grid;place-items:center;
  font-size:34px;color:rgba(227,185,78,.28)
}
.news-tag{
  position:absolute;left:12px;top:12px;z-index:2;
  font-size:11px;letter-spacing:.04em;padding:4px 10px;border-radius:var(--r-pill);
  color:var(--gold);background:rgba(7,7,10,.72);border:1px solid rgba(227,185,78,.34);
  backdrop-filter:blur(6px)
}
.news-body{display:flex;flex-direction:column;gap:8px;padding:18px 18px 16px;flex:1}
.news-body h2,.news-body h3{
  margin:0;font-size:17.5px;line-height:1.45;font-family:var(--head);color:var(--white)
}
.news-body h2 a,.news-body h3 a{color:inherit;text-decoration:none;transition:color .25s}
.news-body h2 a:hover,.news-body h3 a:hover{color:var(--gold)}
.news-body p{margin:0;color:var(--dim);font-size:14px;line-height:1.7}
.news-meta{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:auto;padding-top:10px;font-size:12.5px;color:var(--dim)
}
.news-more{color:var(--gold);text-decoration:none;white-space:nowrap}
body[data-mo-reveal] .news-card{transition-delay:calc(var(--ni,0) * 80ms)}

/* ---- reading a single article ---- */
.article .crumbs{margin-bottom:18px;font-size:13px;color:var(--dim)}
.article .crumbs a{color:var(--dim);text-decoration:none}
.article .crumbs a:hover{color:var(--gold)}
.article-head{max-width:44rem;margin-inline:auto;text-align:center}
.h-xl2{font-size:clamp(26px,4.4vw,46px);line-height:1.25;margin:8px 0 10px;font-family:var(--head);color:var(--white)}
.article-meta{color:var(--dim);font-size:13.5px;margin:0}
.article-cover{
  margin:26px auto 0;max-width:56rem;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line)
}
.article-cover img{width:100%;height:auto;display:block}
/* the reading column: narrow on purpose — long lines lose readers */
.article-body{max-width:40rem;margin:30px auto 0;color:var(--mist);font-size:16.5px;line-height:1.95}
.article-body p{margin:0 0 18px}
.article-body h2{font-family:var(--head);color:var(--white);font-size:24px;margin:34px 0 12px}
.article-body h3{font-family:var(--head);color:var(--white);font-size:19px;margin:26px 0 10px}
.article-body ul,.article-body ol{margin:0 0 18px;padding-left:22px}
.article-body li{margin-bottom:8px}
.article-body img{max-width:100%;height:auto;border-radius:12px;margin:20px 0}
.article-body a{color:var(--gold)}
.article-body blockquote{
  margin:24px 0;padding:14px 18px;border-left:2px solid rgba(227,185,78,.5);
  color:var(--white);background:rgba(227,185,78,.045);border-radius:0 10px 10px 0
}
.article-foot{
  display:flex;gap:12px;flex-wrap:wrap;justify-content:center;
  max-width:40rem;margin:34px auto 0;padding-top:24px;border-top:1px solid var(--line)
}
@media (max-width:640px){
  .news-grid{gap:14px}
  .news-body{padding:15px 15px 14px}
  .news-body h2,.news-body h3{font-size:16.5px}
  .article-body{font-size:16px;line-height:1.9}
  .article-foot .btn{flex:1 1 auto}
}

/* News links are what the whole section exists for, so they get a finger-sized
   hit area on touch — the headline and the "পড়ুন" link both measured under 22px,
   which is missed often enough to lose the reader the article was written for. */
@media (hover:none),(pointer:coarse){
  .news-body h2 a,.news-body h3 a{display:block;min-height:30px;padding-block:3px}
  .news-more{display:inline-flex;align-items:center;min-height:34px;padding-block:5px}
}

/* ==========================================================================
   Pictures inside an article
   A figure is allowed to break out wider than the reading column — that is what
   makes a long read feel like a magazine rather than a wall of text — but never
   wider than the page, and it returns to the column width on a phone.
   ========================================================================== */
.article-fig{
  margin:30px auto;max-width:46rem;
  border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);
  background:var(--ink-3)
}
.article-fig img{width:100%;height:auto;display:block}
.article-fig figcaption{
  padding:10px 16px 12px;font-size:13px;line-height:1.6;color:var(--dim);
  text-align:center;border-top:1px solid var(--line-soft)
}
@media (max-width:720px){
  .article-fig{margin:22px 0;max-width:100%;border-radius:12px}
  .article-fig figcaption{font-size:12.5px;padding:9px 12px 10px}
}

/* ---- the reading experience on a wide screen ----
   Everything in the article shares one centred column so the eyebrow, the
   headline, the byline, the lead image and the text all line up on the same
   axis. `.eyebrow` is a flex row, so `text-align` alone never centred it —
   that is why the gold line above the title sat left of the heading. */
.article-head{display:flex;flex-direction:column;align-items:center;gap:2px}
.article-head .eyebrow{justify-content:center}
.article .crumbs{max-width:56rem;margin-inline:auto}
@media (min-width:900px){
  .article-head{max-width:46rem}
  .article-body{font-size:17px;line-height:2.0}
  .article-body p{margin:0 0 20px}
  /* a first line that draws the eye in, the way a magazine opens a piece */
  .article-body > p:first-of-type{font-size:18.5px;color:var(--white);line-height:1.9}
}

/* ==========================================================================
   Cards that float
   A product tile should read as an object resting above the page, not as ink
   printed on it. Two things do that: a soft shadow underneath that grows as the
   card rises, and a drift that never quite repeats — each card is given its own
   period and phase, so a grid breathes rather than pulsing in unison, which
   would look mechanical.
   Written entirely with `--float`, composed into the single transform above.
   ========================================================================== */
@media (prefers-reduced-motion:no-preference){
  body[data-mo-depth] .card{
    animation:cardFloat var(--fl-dur,7s) ease-in-out var(--fl-delay,0s) infinite;
    box-shadow:0 12px 30px rgba(0,0,0,.30)
  }
  /* the drift stops while the pointer is on the card, so the tilt is the only
     thing moving and the card feels held rather than slippery */
  body[data-mo-depth] .card:hover{animation-play-state:paused}
}
@keyframes cardFloat{
  0%,100%{--float:0px}
  50%    {--float:-6px}
}
/* `--float` must be a real animatable number, or the keyframes above do nothing
   in browsers that treat a custom property as a plain string */
@property --float{ syntax:'<length>'; inherits:false; initial-value:0px }

/* the shadow deepens as the card lifts, which is what sells the height */
body[data-mo-depth] .card{transition:transform .5s cubic-bezier(.22,1,.36,1),box-shadow .5s var(--ease)}
@media (hover:hover) and (pointer:fine){
  body[data-mo-depth] .card:hover{box-shadow:0 30px 64px rgba(0,0,0,.55),0 0 0 1px rgba(227,185,78,.22)}
}
@media (prefers-reduced-motion:reduce){
  body[data-mo-depth] .card{animation:none}
}

/* On a touch device the composed transform above lives inside a hover query, so
   nothing was there for `--float` to feed. This is the touch equivalent: the
   drift and the reveal, without the pointer tilt that has no meaning there. */
@media (hover:none),(pointer:coarse){
  @media (prefers-reduced-motion:no-preference){
    body[data-mo-depth] .card,
    body[data-mo-depth] .card.rv{
      transform:translateY(calc(var(--rv-y,0px) + var(--float,0px)));
      transition:transform .5s cubic-bezier(.22,1,.36,1),box-shadow .5s var(--ease)
    }
  }
}
