/* ============================================================
   DAMASCENE — Persistent chrome
   Seal (preloader) · Nav · Store overlay · Scroll seal · Cursor
   ============================================================ */

/* ---------- 00. THE SEAL — preloader ----------------------
   On Citadel Sand, not on black: the page opens on sand, and a dark
   preloader would slam the door before the first scene. The emblem
   inscribes itself clockwise while the real hero images load, a hairline
   fills beneath it, and the whole panel then lifts away to reveal a hero
   that is already composed underneath. */
.seal{
  position:fixed;inset:0;z-index:200;background:var(--sand);color:var(--ink);
  display:grid;place-items:center;
}
.seal[hidden]{display:none;}
.seal__stage{position:relative;display:grid;place-items:center;
  gap:clamp(1.6rem,3.4vh,2.6rem);}

.seal__mark{
  width:clamp(84px,11vw,132px);aspect-ratio:1;color:var(--rose);
  -webkit-mask-image:conic-gradient(from -90deg,#000 var(--seal,0%),transparent 0);
          mask-image:conic-gradient(from -90deg,#000 var(--seal,0%),transparent 0);
  will-change:mask-image;
}
.seal__mark svg{width:100%;height:100%;}

/* the hairline: the same progress, read a second way */
.seal__meta{
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  gap:1rem;width:clamp(190px,26vw,300px);
}
.seal__word{font-size:var(--t-xs);letter-spacing:var(--track-label);
  text-transform:uppercase;opacity:.62;}
/* one hairline reads as both track and fill: the same progress the
   emblem is drawing, said a second way */
.seal__meta::before{
  content:"";height:1px;
  background:linear-gradient(to right,
    var(--rose) var(--seal,0%),
    color-mix(in oklab,var(--ink) 16%,transparent) var(--seal,0%));
}
.seal__pct{font-family:var(--font-ui);font-size:var(--t-xs);
  letter-spacing:var(--track-label);font-variant-numeric:tabular-nums;opacity:.62;}

/* a single quiet pulse when it completes, instead of a stamp */
.seal.is-struck .seal__mark{animation:seal-settle .52s var(--e-out);}
@keyframes seal-settle{0%{transform:scale(1)}40%{transform:scale(1.04)}100%{transform:scale(1)}}
.seal__ring{
  position:absolute;inset:0;margin:auto;width:clamp(84px,11vw,132px);aspect-ratio:1;
  border:1px solid var(--rose);border-radius:50%;opacity:0;pointer-events:none;
}
.seal.is-struck .seal__ring{animation:seal-strike .8s var(--e-out) forwards;}
@keyframes seal-strike{0%{opacity:.55;transform:scale(1)}100%{opacity:0;transform:scale(2.2)}}

/* it lifts away rather than irising out: the hero is already behind it */
.seal.is-open{clip-path:inset(0 0 100% 0);pointer-events:none;
  transition:clip-path .95s var(--e-inout);}
.seal:not(.is-open){clip-path:inset(0 0 0% 0);}
.seal.is-open .seal__stage{opacity:0;translate:0 -22px;
  transition:opacity .42s var(--e-out),translate .7s var(--e-out);}

/* ---------- Masthead --------------------------------------- */
.mast{
  position:fixed;inset:0 0 auto;z-index:120;
  display:flex;align-items:center;justify-content:space-between;gap:var(--gut);
  padding:clamp(.9rem,1.7vw,1.5rem) var(--edge);
  color:var(--mast-fg,var(--sand));
  mix-blend-mode:var(--mast-blend,normal);
  transition:color .5s var(--e-soft);
}
/* a veil, not a bar: it fades in once the page has moved and never
   affects layout, so the header can never appear to jump */
.mast::before{
  content:"";position:absolute;inset:0 0 auto;height:calc(100% + 3rem);z-index:-1;
  pointer-events:none;opacity:0;transition:opacity .55s var(--e-soft);
  background:linear-gradient(to bottom,
    var(--mast-veil,#000) 0%,
    color-mix(in oklab,var(--mast-veil,#000) 88%,transparent) 42%,
    color-mix(in oklab,var(--mast-veil,#000) 40%,transparent) 74%,
    transparent 100%);
}
.mast.is-solid::before{opacity:1;}
/* The mark is Damask Rose, not the chrome's ink — it is the one piece of the
   masthead that carries the house colour rather than the ground's contrast.
   It rides its own custom property so the nav and the button are unaffected. */
.mast__logo{display:block;width:clamp(132px,13.5vw,206px);
  color:var(--logo-fg,currentColor);transition:color .5s var(--e-soft);}
/* inside the overlays the mark is not passing over the scenes, so it takes
   the overlay's own foreground instead of whatever the scroll last set */
.menu__head .mast__logo,.store__head .mast__logo{color:currentColor;}
.mast__logo svg{width:100%;height:auto;}
.mast__index{display:flex;align-items:center;gap:clamp(1.1rem,2.3vw,2.4rem);margin-left:auto;}
.mast__nav{display:flex;align-items:center;gap:clamp(1.1rem,2.3vw,2.4rem);
  margin-left:clamp(1.1rem,2.3vw,2.4rem);}
.navlink{
  position:relative;font-size:var(--t-xs);letter-spacing:var(--track-label);
  text-transform:uppercase;font-weight:400;padding-block:.42rem;
  transition:opacity .45s var(--e-lux);
}
.navlink>span{display:inline-block;transition:transform .55s var(--e-lux);}
.navlink:hover>span,.navlink:focus-visible>span{transform:translateY(-2px);}
.navlink::after{
  content:"";position:absolute;left:0;bottom:.1rem;height:1px;width:100%;
  background:currentColor;transform-origin:100% 50%;scale:0 1;
  transition:scale .55s var(--e-lux);
}
.navlink:hover::after,.navlink:focus-visible::after{transform-origin:0 50%;scale:1 1;}
.navlink.is-current::after{scale:1 1;opacity:.4;}

/* --- the house button ------------------------------------------
   One micro-interaction, used everywhere: the ground wipes up under the
   label, the label swaps for its own copy on the same beat, and the dot
   opens into a ring. Nothing bounces, nothing changes size. */
.shopbtn{
  --pad:clamp(.62rem,1vw,.8rem);
  position:relative;display:inline-flex;align-items:center;gap:.62rem;
  padding:var(--pad) calc(var(--pad) * 1.95);
  border:1px solid var(--mast-fg,var(--ink));border-radius:var(--radius-pill);
  font-size:var(--t-xs);letter-spacing:var(--track-label);text-transform:uppercase;
  font-weight:500;overflow:hidden;isolation:isolate;
  color:var(--mast-fg,var(--ink));
  transition:color .5s var(--e-lux);
}
/* the ground is the resting ink colour and never moves with `color`;
   only the label flips to the ground it is now sitting on */
.shopbtn::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:var(--mast-fg,var(--ink));
  translate:0 101%;transition:translate .62s var(--e-lux);
}
.shopbtn:hover,.shopbtn:focus-visible{color:var(--shopbtn-on,var(--sand));}
.shopbtn:hover::before,.shopbtn:focus-visible::before{translate:0 0;}

/* the label rolls to its duplicate rather than simply changing colour */
.shopbtn__t{position:relative;display:block;overflow:hidden;line-height:1.15;}
.shopbtn__t i{display:block;font-style:normal;
  transition:transform .62s var(--e-lux);}
.shopbtn__t i:last-child{position:absolute;inset:0;transform:translateY(105%);}
.shopbtn:hover .shopbtn__t i,.shopbtn:focus-visible .shopbtn__t i{transform:translateY(-105%);}
.shopbtn:hover .shopbtn__t i:last-child,
.shopbtn:focus-visible .shopbtn__t i:last-child{transform:translateY(0);}

.shopbtn__dot{width:5px;height:5px;border-radius:50%;background:currentColor;flex:none;
  transition:box-shadow .62s var(--e-lux),transform .62s var(--e-lux);}
.shopbtn:hover .shopbtn__dot,.shopbtn:focus-visible .shopbtn__dot{
  transform:scale(.62);box-shadow:0 0 0 3px color-mix(in oklab,currentColor 34%,transparent);}

/* ---------- Scroll seal (progress) ------------------------- */
.progress{
  position:fixed;right:var(--edge);bottom:clamp(1rem,2.4vw,2rem);z-index:110;
  width:clamp(42px,4.4vw,58px);aspect-ratio:1;pointer-events:none;
  color:var(--prog-fg,var(--sand));opacity:0;transition:opacity .5s;
}
.progress.is-on{opacity:.85;}
.progress svg{width:100%;height:100%;overflow:visible;}
.progress__track{fill:none;stroke:currentColor;stroke-opacity:.2;stroke-width:1.4;}
.progress__bar{fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;
  transform:rotate(-90deg);transform-origin:50% 50%;
  transition:stroke-dashoffset .2s linear;}
.progress__num{font-family:var(--font-ui);font-size:22px;font-weight:400;letter-spacing:.06em;
  fill:currentColor;opacity:.75;font-variant-numeric:tabular-nums;}

/* ---------- Store overlay ---------------------------------- */
.store{
  position:fixed;inset:0;z-index:180;display:grid;
  grid-template-rows:auto 1fr auto;
  background:var(--ink);color:var(--sand);
  clip-path:inset(0 0 100% 0);
  transition:clip-path .95s var(--e-inout);
  pointer-events:none;
}
.store.is-open{clip-path:inset(0 0 0 0);pointer-events:auto;}
.store__head{display:flex;justify-content:space-between;align-items:center;
  padding:clamp(.9rem,1.7vw,1.5rem) var(--edge);}
.store__close{display:inline-flex;align-items:center;gap:.6rem;font-size:var(--t-xs);
  letter-spacing:var(--track-label);text-transform:uppercase;}
.store__close svg{width:12px;height:12px;transition:rotate .5s var(--e-out);}
.store__close:hover svg{rotate:90deg;}
.store__body{position:relative;display:grid;grid-template-columns:1fr 1fr;min-height:0;}
/* The question is laid over the panels, and one of the two is Citadel Sand —
   sand on sand is 1:1, no reading at all, and the boundary between the panels
   moves as they open, so no single colour can be made to work. The panels keep
   a veil along their bottom edge for their own names; this is the same idiom
   at the top, so the question always has one ground under it whichever panel
   it happens to be crossing. Out of flow, so it is not a flex item when the
   pointer script switches the row to flex. */
.store__body::before{
  content:"";position:absolute;inset:0 0 auto;z-index:2;pointer-events:none;
  height:clamp(260px,42vh,430px);
  background:linear-gradient(to bottom,
    color-mix(in oklab,var(--ink) 84%,transparent) 0%,
    color-mix(in oklab,var(--ink) 74%,transparent) 58%,
    color-mix(in oklab,var(--ink) 30%,transparent) 85%,
    transparent 100%);
}
.store__ask{
  position:absolute;left:50%;top:calc(clamp(.9rem,1.7vw,1.5rem) + 3.4rem);translate:-50% 0;
  z-index:4;text-align:center;pointer-events:none;width:min(90%,40ch);
}
.market{
  position:relative;display:flex;flex-direction:column;justify-content:flex-end;
  padding:var(--edge);overflow:hidden;isolation:isolate;
  transition:flex-grow .8s var(--e-out);
}

.market__field{position:absolute;inset:0;z-index:-2;transition:scale 1.2s var(--e-out),opacity .7s;}
.market--jo{--m-ink:var(--sand);}
.market--sa{--m-ink:var(--ink);}
.market{color:var(--m-ink,var(--sand));}
.market--jo .market__field{background:var(--rose);}
.market--sa .market__field{background:var(--sand);}
/* the ground carries an image from the first frame; hover only deepens it */
.market__media{position:absolute;inset:0;z-index:-1;opacity:.2;
  transition:opacity .85s var(--e-soft),scale 1.4s var(--e-out);scale:1.08;}
.market--jo .market__media{mix-blend-mode:luminosity;}
.market--sa .market__media{mix-blend-mode:multiply;opacity:.16;}
.market__media img,.market__media video{width:100%;height:100%;object-fit:cover;}
.market__media::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to top,
    color-mix(in oklab,var(--m-veil,#000) 62%,transparent) 2%,transparent 58%);}
.market--jo{--m-veil:var(--rose-120);}
.market--sa{--m-veil:var(--sand-deep);}
.market:hover .market__media,.market:focus-visible .market__media,
.market.is-hot .market__media{opacity:.5;scale:1;}
.market--sa:hover .market__media,.market--sa.is-hot .market__media{opacity:.34;}
.market__num{font-size:var(--t-xs);letter-spacing:var(--track-label);opacity:.8;}
/* In the overlay the index sits inside the veil, so it is on ink there and not
   on its panel's own ground — the sand panel's foreground is Midnight
   Cardamom, which would be black on near-black. It takes the veil's colour
   instead. Only in the overlay: the destination section carries no veil. */
.store .market__num{color:var(--sand);}
.market__where{margin-top:auto;font-size:var(--t-xs);letter-spacing:var(--track-label);
  text-transform:uppercase;opacity:.72;}
.market__name{font-family:var(--font-display);text-transform:uppercase;
  font-size:clamp(1.6rem,3vw,3.4rem);line-height:.98;letter-spacing:-.018em;
  margin-top:.32em;}
.market__go{display:inline-flex;align-items:center;gap:.7rem;margin-top:1.5rem;
  font-size:var(--t-xs);letter-spacing:var(--track-label);text-transform:uppercase;}
.market__goT{position:relative;display:inline-block;}
.market__goT::after{content:"";position:absolute;left:0;right:0;bottom:-.32em;height:1px;
  background:currentColor;transform-origin:0 50%;scale:0 1;
  transition:scale .62s var(--e-lux);}
.market:hover .market__goT::after,.market:focus-within .market__goT::after{scale:1 1;}
.market__go svg{width:26px;height:8px;transition:translate .62s var(--e-lux);}
.market:hover .market__go svg,.market:focus-within .market__go svg{translate:11px 0;}
.market__meta{font-size:var(--t-sm);opacity:.84;margin-top:.75rem;}
.store__foot{padding:clamp(.9rem,1.7vw,1.5rem) var(--edge);display:flex;
  justify-content:space-between;gap:1rem;flex-wrap:wrap;}

/* ---------- Cursor ---------------------------------------- */
.cursor{
  position:fixed;top:0;left:0;z-index:190;width:44px;height:44px;margin:-22px 0 0 -22px;
  pointer-events:none;opacity:0;
  transition:opacity .3s;will-change:transform;
  color:var(--mast-fg,var(--ink));
}
.cursor.is-on{opacity:.55;}
.cursor.is-wide{opacity:.9;}
.cursor__ring{width:100%;height:100%;border:1px solid currentColor;border-radius:50%;
  scale:.2;transition:scale .55s var(--e-lux),background-color .55s var(--e-lux);}
.cursor.is-wide .cursor__ring{background:color-mix(in oklab,currentColor 10%,transparent);}
.cursor.is-wide .cursor__ring{scale:1;}
.cursor__label{position:absolute;inset:0;display:grid;place-items:center;color:currentColor;
  font-size:8.5px;letter-spacing:.16em;text-transform:uppercase;opacity:0;transition:opacity .3s;}
.cursor.is-wide .cursor__label{opacity:1;}
@media (hover:none),(pointer:coarse){.cursor{display:none;}}

/* ---------- Mobile menu -------------------------------------
   The section strip is hidden on a phone because a truncated,
   side-scrolling row reads as broken. This is what replaces it. */
.burger{
  display:none;position:relative;width:42px;height:42px;flex:none;
  border:1px solid currentColor;border-radius:var(--radius-pill);
  transition:background-color .55s var(--e-lux),color .55s var(--e-lux);
}
.burger span{
  position:absolute;left:50%;width:15px;height:1px;background:currentColor;
  translate:-50% 0;transition:translate .5s var(--e-lux),rotate .5s var(--e-lux);
}
.burger span:first-child{top:18px;}
.burger span:last-child{top:23px;}
.is-menu .burger span:first-child{translate:-50% 2.5px;rotate:45deg;}
.is-menu .burger span:last-child{translate:-50% -2px;rotate:-45deg;}
@media (max-width:719px){ .burger{display:block;} }

.menu{
  position:fixed;inset:0;z-index:170;background:var(--ink);color:var(--sand);
  display:flex;flex-direction:column;justify-content:center;gap:var(--stack-l);
  padding:var(--edge);
  clip-path:inset(0 0 100% 0);transition:clip-path .78s var(--e-inout);
  pointer-events:none;
}
.menu.is-open{clip-path:inset(0 0 0% 0);pointer-events:auto;}
/* the panel carries its own chrome: it sits above the masthead, so the
   button that opened it is not reachable from in here */
.menu__head{
  position:absolute;top:0;left:0;right:0;
  display:flex;align-items:center;justify-content:space-between;
  padding:clamp(.9rem,1.7vw,1.5rem) var(--edge);
  opacity:0;transition:opacity .5s .22s;
}
.menu.is-open .menu__head{opacity:1;}
/* .mast__logo carries order:1 from the tablet masthead rules; without a
   matching order here the close button sorts ahead of it and the pair
   comes out reversed */
.menu__head .mast__logo{color:var(--sand);display:block;order:0;}
.menu__head .mast__logo svg{width:100%;height:auto;}
.menu__close{
  order:1;display:inline-flex;align-items:center;gap:.6rem;flex:none;
  font-size:var(--t-xs);letter-spacing:var(--track-label);text-transform:uppercase;
  padding:.7rem 1.1rem;border:1px solid currentColor;border-radius:var(--radius-pill);
  transition:background-color .5s var(--e-lux),color .5s var(--e-lux);
}
.menu__close svg{width:11px;height:11px;transition:rotate .5s var(--e-lux);}
.menu__close:hover,.menu__close:focus-visible{background:var(--sand);color:var(--ink);}
.menu__close:hover svg,.menu__close:focus-visible svg{rotate:90deg;}

.menu__list{display:grid;}
.menu__item{
  display:flex;align-items:baseline;gap:1rem;padding-block:.62rem;
  border-bottom:1px solid color-mix(in oklab,var(--sand) 14%,transparent);
  opacity:0;translate:0 16px;
  transition:opacity .6s var(--e-out),translate .6s var(--e-out),padding-left .45s var(--e-lux);
}
.menu.is-open .menu__item{opacity:1;translate:0 0;}
.menu.is-open .menu__item:nth-child(1){transition-delay:.16s}
.menu.is-open .menu__item:nth-child(2){transition-delay:.22s}
.menu.is-open .menu__item:nth-child(3){transition-delay:.28s}
.menu.is-open .menu__item:nth-child(4){transition-delay:.34s}
.menu.is-open .menu__item:nth-child(5){transition-delay:.40s}
.menu.is-open .menu__item:nth-child(6){transition-delay:.46s}
.menu__item:active{padding-left:.5rem;}
.menu__n{font-size:var(--t-xs);letter-spacing:var(--track-label);opacity:.5;}
.menu__t{font-family:var(--font-display);text-transform:uppercase;
  font-size:clamp(1.8rem,9vw,2.6rem);line-height:1;letter-spacing:-.014em;}
.menu__foot{display:grid;gap:.6rem;opacity:0;transition:opacity .6s .5s;}
.menu.is-open .menu__foot{opacity:.82;}
.menu__wa{font-size:var(--t-sm);border-bottom:1px solid currentColor;justify-self:start;}
@media (min-width:720px){ .menu{display:none;} }
