/* ============================================================
   FONTS — self-hosted.
   These were a render-blocking stylesheet on fonts.googleapis.com plus a
   second connection to fonts.gstatic.com, and Chrome named the three files
   as the page's only layout-shift culprit. Served from our own origin they
   are same-connection, cache under our own rules, and cost no third-party
   round trip before first paint. Variable fonts: one file per axis set.
   ============================================================ */
@font-face{
  font-family:"Fraunces";
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url("../assets/fonts/fraunces-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Fraunces";
  font-style:italic;
  font-weight:300 600;
  font-display:swap;
  src:url("../assets/fonts/fraunces-latin-italic.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:"Karla";
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url("../assets/fonts/karla-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ============================================================
   k-sensual.art
   Direction: "Domestic Noir" — a private room at 11pm.
   Tungsten amber light bleeding into ink-violet shadow.
   System: LIGHT = INTIMACY. Amber marks her voice and the way in.
   ============================================================ */

/* ---------- tokens ---------- */
:root{
  --ink:    #0B0A0E;   /* near-black, violet undertone — the dark room   */
  --umber:  #171015;   /* warm dark — section grounds                    */
  --lamp:   #E8B87F;   /* tungsten amber — her voice, and the door       */
  --flush:  #C4566B;   /* worn lipstick / skin flush — secondary heat    */
  --linen:  #EFE6DC;   /* warm off-white — body copy                     */
  --smoke:  #8A7F86;   /* mauve grey — labels, meta                      */
  --shade:  #120C1A;   /* deep ink-violet — vignettes, the dark she hides in */

  --display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --body:    "Karla", "Segoe UI", system-ui, sans-serif;

  --gut: clamp(1.5rem, 5vw, 5rem);
  --sec: clamp(5.5rem, 13vh, 9.5rem);
  --ease: cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth}
body{
  margin:0;
  background:var(--ink);
  color:var(--linen);
  font-family:var(--body);
  font-size:clamp(1rem,.95rem + .3vw,1.125rem);
  line-height:1.7;
  font-weight:350;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{display:block;max-width:100%;height:auto}
a{color:inherit}

:focus-visible{outline:2px solid var(--lamp); outline-offset:4px; border-radius:2px}

/* ---------- shared type ---------- */
.eyebrow{
  font-family:var(--body);
  font-size:.7rem; font-weight:600;
  letter-spacing:.26em; text-transform:uppercase;
  color:var(--smoke);
  margin:0 0 1.35rem;
}
.eyebrow--lamp{color:var(--lamp); opacity:.85}

.h1,.h2,.h3,.hero__title{
  font-family:var(--display);
  font-weight:400;
  font-variation-settings:"SOFT" 40,"WONK" 1;
  line-height:1.04;
  letter-spacing:-.018em;
  margin:0 0 1.5rem;
}
/* balance is a multi-pass line-break search; on 10 headings it made the first
   layout far more expensive. Only the hero headline is big enough to show it. */
.hero__title{font-size:clamp(2.6rem,7.2vw,5.4rem); text-wrap:balance}
.h1{font-size:clamp(2.35rem,5.6vw,4.4rem)}
.h2{font-size:clamp(1.95rem,4.2vw,3.4rem)}
.h3{font-size:clamp(1.5rem,2.6vw,2.1rem)}
.h2--center{text-align:center}
.h1 em,.h2 em,.hero__title em{
  font-style:italic; font-weight:300; color:var(--lamp);
}

.lede{font-size:clamp(1.08rem,1rem + .4vw,1.3rem); color:#D9CFC6; margin:0 0 1.15rem; max-width:56ch}
.body{margin:0 0 1.15rem; color:#C9BFB8; max-width:58ch}
.body--dim{color:var(--smoke)}
.center{text-align:center}
.center .lede,.center .body,.center .voice{margin-left:auto;margin-right:auto}

/* her voice — lit by the lamp */
.voice{
  font-family:var(--display);
  font-style:italic; font-weight:300;
  font-size:clamp(1.25rem,1.05rem + .95vw,1.85rem);
  line-height:1.4;
  color:var(--lamp);
  max-width:34ch;
  margin:2rem 0;
  position:relative;
  padding-left:1.4rem;
}
.voice::before{
  content:""; position:absolute; left:0; top:.35em; bottom:.35em; width:1px;
  background:linear-gradient(180deg,transparent,var(--lamp),transparent);
  opacity:.7;
}
.voice--big{font-size:clamp(1.5rem,1.1rem + 1.6vw,2.4rem); max-width:24ch}
.center .voice{padding-left:0; text-align:center}
.center .voice::before{display:none}

.fineprint{font-size:.82rem; color:var(--smoke); margin:0 0 1.6rem; max-width:52ch}

/* ---------- buttons ---------- */
.btn{
  --pad:1rem 2rem;
  display:inline-block;
  font-family:var(--body);
  font-size:.86rem; font-weight:700;
  letter-spacing:.12em; text-transform:uppercase;
  text-decoration:none;
  padding:var(--pad);
  border:1px solid transparent;
  border-radius:2px;
  cursor:pointer;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease),
             background-color .3s var(--ease), color .3s var(--ease),
             border-color .3s var(--ease);
}
.btn--lamp{
  background:var(--lamp); color:#160F08;
  box-shadow:0 0 0 0 rgba(232,184,127,.42), 0 14px 40px -16px rgba(232,184,127,.6);
}
.btn--lamp:hover{
  background:#F3CB99;
  transform:translateY(-2px);
  box-shadow:0 0 34px 0 rgba(232,184,127,.34), 0 20px 44px -18px rgba(232,184,127,.75);
}
.btn--ghost{
  background:transparent; color:var(--linen);
  border-color:rgba(239,230,220,.28);
}
.btn--ghost:hover{border-color:var(--lamp); color:var(--lamp); transform:translateY(-2px)}
.btn--lg{--pad:1.25rem 2.6rem; font-size:.95rem}

/* ---------- the hero CTA ----------------------------------------------
   This one button takes 61% of every click the page produces, so it is the
   only element allowed to outshine the photograph. It gets a lamp halo the
   other CTAs don't have, and a slow breathe so the eye returns to it.

   The halo lives on a pseudo-element and animates opacity, not box-shadow:
   opacity is composited, box-shadow repaints the button every frame. */
.btn--beacon{
  /* no isolation/z-index here on purpose: it would create a stacking context
     and trap the -1 halo above the button's own background instead of behind it */
  position:relative;
  --pad:1.4rem 3.1rem;
  font-size:1rem; letter-spacing:.14em;
  box-shadow:0 0 0 1px rgba(255,236,209,.55) inset,
             0 18px 48px -14px rgba(232,184,127,.85);
}
.btn--beacon::before{
  content:"";
  position:absolute; inset:-26px; z-index:-1;
  border-radius:14px; pointer-events:none;
  /* ellipse + farthest-side: closest-side sizes the glow to the button's short
     axis, so it died out vertically and never spread across the width */
  background:radial-gradient(ellipse farthest-side at 50% 50%,
             rgba(255,222,180,.85), rgba(232,184,127,.40) 46%, transparent 76%);
  animation:beacon 4.5s var(--ease) infinite;
}
@keyframes beacon{
  0%,100%{opacity:.42; transform:scale(.93)}
  50%    {opacity:1;   transform:scale(1.07)}
}
.btn--beacon::after{
  content:"  →";
  display:inline-block;
  transition:transform .3s var(--ease);
}
.btn--beacon:hover::after{transform:translateX(5px)}
.btn--beacon:hover{
  box-shadow:0 0 0 1px rgba(255,244,226,.8) inset,
             0 22px 54px -14px rgba(232,184,127,1);
}
.btn--beacon:hover::before{animation:none; opacity:1}
@media (max-width:640px){
  .btn--beacon{--pad:1.25rem 2rem; font-size:.92rem}
}
.btn--sm{--pad:.8rem 1.5rem; font-size:.76rem}

.link-arrow{
  display:inline-block; margin-top:.5rem;
  font-size:.86rem; font-weight:600; letter-spacing:.1em; text-transform:uppercase;
  color:var(--lamp); text-decoration:none;
  border-bottom:1px solid rgba(232,184,127,.35);
  padding-bottom:.35rem;
  transition:border-color .3s var(--ease), gap .3s;
}
.link-arrow::after{content:"\00a0\00a0→"; transition:transform .3s var(--ease); display:inline-block}
.link-arrow:hover{border-color:var(--lamp)}
.link-arrow:hover::after{transform:translateX(5px)}

/* ---------- grain (analog intimacy, also masks upscaling) ---------- */
.grain{
  position:fixed; inset:0;
  pointer-events:none; z-index:3;
  opacity:.12; mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  /* held still: four viewports of animated noise under a blend mode was
     recompositing every frame for the whole session, on desktop too. */
  animation:none;
}
@keyframes grainShift{
  0%{transform:translate(0,0)}      20%{transform:translate(-3%,2%)}
  40%{transform:translate(2%,-3%)}  60%{transform:translate(-2%,-2%)}
  80%{transform:translate(3%,1%)}   100%{transform:translate(0,0)}
}

/* ============================================================
   FIXED HERO — content scrolls over it, she stays behind
   ============================================================ */
.hero{
  position:fixed; inset:0;
  height:100svh;
  z-index:0;
  overflow:hidden;
  display:grid;
  /* 'safe' so a tall copy stack overflows the bottom (recoverable) rather
     than the top, which a fixed, overflow:hidden hero can never scroll back. */
  align-content:safe end;
}
.hero__stage{position:absolute; inset:0}
.hero__slide{
  /* one slide is visible at a time and the crossfade is plain opacity,
     so per-slide GPU layers only cost memory */
  position:absolute; inset:0;
  /* keep the face/mask in frame — square sources crop hard on wide screens */
  background-size:cover; background-position:center 12%;
  opacity:0;
  transform:scale(1.06);
  filter:saturate(.86) contrast(1.06) brightness(.92);
  transition:opacity 2.2s var(--ease);
  will-change:auto;
}
.hero__slide.is-on{
  opacity:1;
  animation:drift 11s linear forwards;
}
@keyframes drift{
  from{transform:scale(1.045) translate3d(0,0,0)}
  to  {transform:scale(1.14)  translate3d(-1.2%,-1.6%,0)}
}
.hero__scrim{
  position:absolute; inset:0; z-index:2;
  background:
    /* violet shadow swallowing the top-right corner, where her face sits.
       Keeps her unreadable — the mask, in gradient form. */
    radial-gradient(72% 82% at 100% -6%,
      rgba(18,12,26,.98) 0%,
      rgba(18,12,26,.88) 26%,
      rgba(18,12,26,.58) 48%,
      rgba(18,12,26,.22) 66%,
      transparent 82%),
    /* dark bed under the copy block, so the headline holds contrast
       whichever slide is showing */
    radial-gradient(78% 62% at 14% 86%, rgba(11,10,14,.90), transparent 66%),
    /* lamp glow, kept off her face so it doesn't undo the vignette */
    radial-gradient(95% 70% at 62% 46%, rgba(232,184,127,.15), transparent 60%),
    linear-gradient(180deg, rgba(11,10,14,.34) 0%, rgba(11,10,14,.16) 28%, rgba(11,10,14,.80) 74%, var(--ink) 100%),
    linear-gradient(90deg, rgba(11,10,14,.80) 0%, rgba(11,10,14,.14) 58%, rgba(11,10,14,.38) 100%);
}
.hero__inner{
  position:relative; z-index:4;
  /* same measure as .wrap so the hero headline lines up with every
     section heading below it instead of hugging the viewport edge */
  width:min(76rem,100% - var(--gut)*2);
  margin-inline:auto;
  padding:0 0 clamp(5rem,12vh,8.5rem);
  will-change:opacity,transform;
}
/* the first thing a visitor arriving for K-sensual needs answered */
.hero__note{
  color:#9C9098;
  letter-spacing:.2em;
  max-width:46ch;
  line-height:2;
}
.hero__note span{display:block; color:var(--lamp)}

.hero__sub{
  font-size:clamp(1.05rem,1rem + .5vw,1.35rem);
  color:#D9CFC6; max-width:38ch;
  margin:0 0 2.25rem;
}
.hero__micro{
  margin:1.5rem 0 0;
  font-size:.72rem; letter-spacing:.13em; text-transform:uppercase;
  color:var(--smoke);
}
.hero__cue{
  position:absolute; z-index:4; bottom:1.6rem; left:50%; translate:-50% 0;
  width:2px; height:4.5rem; overflow:hidden;
  background:rgba(239,230,220,.30);
}
.hero__cue span{
  position:absolute; inset:0; display:block;
  background:linear-gradient(180deg,transparent,var(--lamp));
  animation:cue 2.4s var(--ease) infinite;
}
@keyframes cue{0%{transform:translateY(-100%)}60%,100%{transform:translateY(100%)}}

/* ============================================================
   SCROLLING PAGE
   ============================================================ */
.page{
  position:relative; z-index:1;
  margin-top:100svh;
}
.s{
  position:relative;
  padding:var(--sec) 0;
  background:var(--ink);
}
.s--notice{
  background:
    linear-gradient(180deg, rgba(196,86,107,.07), transparent 42%),
    var(--umber);
  border-top:1px solid rgba(232,184,127,.14);
}
.s--hidden{background:var(--ink)}
.s--bots{
  background:var(--ink);
  padding-block:clamp(6.5rem,16vh,11rem);
}
.s--unlock{background:var(--ink)}
.s--custom{background:var(--umber)}
.s--selective{
  background:
    radial-gradient(70% 60% at 50% 45%, rgba(196,86,107,.13), transparent 72%),
    var(--ink);
}
.s--gallery{background:var(--umber)}

.wrap{
  position:relative; z-index:1;
  width:min(76rem,100% - var(--gut)*2);
  margin-inline:auto;
}
.wrap--narrow{width:min(46rem,100% - var(--gut)*2)}
.wrap--mid{width:min(58rem,100% - var(--gut)*2)}

/* ---------- photo grounds ---------- */
.bg{position:absolute; inset:0; z-index:0; overflow:hidden}
.bg__scrim{
  position:absolute; inset:0;
  background:
    radial-gradient(90% 70% at 50% 40%, rgba(11,10,14,.62), rgba(11,10,14,.90) 78%),
    linear-gradient(180deg, var(--ink) 0%, transparent 18%, transparent 82%, var(--ink) 100%);
}
.bg__scrim--deep{
  background:
    radial-gradient(85% 65% at 50% 42%, rgba(11,10,14,.74), rgba(11,10,14,.93) 76%),
    linear-gradient(180deg, var(--ink) 0%, transparent 16%, transparent 84%, var(--ink) 100%);
}
/* A real <img> rather than a background, so the fade can be masked relative to
   the photo's own top edge instead of the (much taller) section. Sits at its
   natural ratio along the bottom, anchored left, so her mouth — bottom-left of
   the frame — is always the part you see. No parallax: a bottom-anchored photo
   that doesn't fill the box would drift off the edge. */
.bg__photo{
  position:absolute; left:0; bottom:0;
  width:100%; height:auto;
  /* dissolve the top and the trailing edge so the photo has no hard border
     anywhere — it fades into --ink rather than sitting on top of it */
  -webkit-mask-image:
    linear-gradient(180deg, transparent 0, #000 46%),
    linear-gradient(90deg, #000 0, #000 48%, transparent 94%);
  mask-image:
    linear-gradient(180deg, transparent 0, #000 46%),
    linear-gradient(90deg, #000 0, #000 48%, transparent 94%);
  -webkit-mask-composite:source-in;
  mask-composite:intersect;
}
/* graded to the site's own tones: desaturated and warm, not blue */
.s--bots .bg__photo{
  filter:grayscale(.5) sepia(.3) saturate(1.15) brightness(.94) contrast(1.06);
}
/* ink + shade wash, with the same lamp glow the other sections carry */
.s--bots .bg__scrim--deep{
  background:
    radial-gradient(66% 48% at 60% 38%, rgba(232,184,127,.07), transparent 64%),
    radial-gradient(90% 64% at 46% 44%, rgba(18,12,26,.58), rgba(11,10,14,.90) 76%),
    linear-gradient(180deg, var(--ink) 0%, transparent 18%, transparent 78%, var(--ink) 100%);
}

/* ---------- reveal (light sweep) ---------- */
.reveal{
  opacity:0;
  transform:translateY(26px);
  transition:opacity .9s var(--ease), transform .9s var(--ease);
}
.reveal.is-in{opacity:1; transform:none}

/* ---------- media + the signature light band ---------- */
.media{
  position:relative;
  margin:0;
  overflow:hidden;
  background:#100C10;
  border-radius:2px;
}
.media img{
  width:100%; aspect-ratio:1/1; object-fit:cover;
  filter:saturate(.88) contrast(1.05) brightness(.9);
  transition:filter .6s var(--ease), transform 1.1s var(--ease);
}
.media::after{               /* the band of light falling across her */
  content:""; position:absolute; inset:0; z-index:2;
  pointer-events:none;
  background:linear-gradient(105deg,
    transparent 30%,
    rgba(232,184,127,.0) 42%,
    rgba(232,184,127,.42) 50%,
    rgba(255,240,220,.16) 56%,
    transparent 68%);
  transform:translateX(-120%);
}
.media.is-in::after{animation:sweep 1.5s var(--ease) .18s both}
@keyframes sweep{from{transform:translateX(-120%)} to{transform:translateX(120%)}}
.media:hover img{filter:saturate(1) contrast(1.06) brightness(1); transform:scale(1.035)}
.media figcaption{
  position:absolute; z-index:3; left:0; right:0; bottom:0;
  padding:2.5rem 1rem .9rem;
  font-size:.68rem; letter-spacing:.2em; text-transform:uppercase;
  color:rgba(239,230,220,.82);
  background:linear-gradient(180deg,transparent,rgba(11,10,14,.85));
}

/* ---------- split ---------- */
.split{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:clamp(2rem,5vw,4.5rem);
  align-items:center;
}
.split__media{max-width:34rem; width:100%}

/* ---------- the three denials, as one sentence ---------- */
.nots{
  max-width:40ch; margin:1.75rem auto 3.5rem;
  font-size:clamp(.98rem,.94rem + .2vw,1.1rem);
  line-height:1.85;
  color:#9C9098;
}

/* ---------- unlock list ---------- */
.unlock__list{
  list-style:none; padding:0;
  margin:2.5rem 0 1rem;
  columns:2; column-gap:clamp(2rem,5vw,4rem);
}
.unlock__list li{
  break-inside:avoid;
  padding:.85rem 0 .85rem 1.6rem;
  position:relative;
  color:#C9BFB8;
  border-bottom:1px solid rgba(239,230,220,.08);
}
.unlock__list li::before{
  content:""; position:absolute; left:0; top:1.55em;
  width:.5rem; height:1px; background:var(--lamp);
}

/* ---------- rating modes ---------- */
.modes{
  display:flex; flex-wrap:wrap; justify-content:center; gap:.6rem;
  margin:2rem 0;
}
.modes span{
  font-family:var(--display); font-style:italic; font-size:1.05rem;
  padding:.4rem 1.1rem;
  border:1px solid rgba(196,86,107,.4);
  border-radius:999px;
  color:#E7C3CB;
}

/* ---------- gallery grid ---------- */
.grid{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:clamp(.5rem,1.2vw,1rem);
  margin-block:3rem;
}

/* ---------- close: instagram then the paid ask, over one tall figure ------ */
.s--close{
  background:var(--ink);
  min-height:100svh;
  display:grid;
  align-content:center;
  gap:clamp(3rem,7vh,5rem);
  padding-block:clamp(6rem,15vh,10rem);
}
/* Tall enough that a 3:4 portrait at cover keeps her whole standing frame.
   Anchored bottom so the legs stay in shot at every viewport. */
.bg__figure{
  position:absolute; inset:0;
  background-size:cover;
  background-position:bottom center;
  background-repeat:no-repeat;
  /* muted, but still legibly her — she reads through the gradient, not under it */
  filter:grayscale(.2) saturate(.85) brightness(1.15) contrast(1.0);
}
/* the same violet wash the other sections use, laid over her so the whole
   thing reads as one graded field rather than text-on-a-photo */
.bg__scrim--final{
  background:
    radial-gradient(70% 44% at 50% 40%, rgba(196,86,127,.10), transparent 68%),
    radial-gradient(96% 64% at 50% 56%, rgba(18,12,26,.52), rgba(11,10,14,.84) 80%),
    linear-gradient(180deg, var(--ink) 0%, rgba(19,13,28,.58) 22%, rgba(19,13,28,.58) 78%, var(--ink) 100%);
}
.close__rule{
  position:relative; z-index:1;
  width:min(20rem,50%);
  height:1px;
  margin-inline:auto;
  background:linear-gradient(90deg,transparent,rgba(239,230,220,.22),transparent);
}

/* instagram: an icon, deliberately no button — it must not read as loud as
   the amber CTA below it */
.ig{
  display:inline-grid; justify-items:center; gap:.85rem;
  margin-top:2.5rem;
  text-decoration:none;
  color:var(--smoke);
  transition:color .3s var(--ease);
}
.ig__glyph{
  display:grid; place-items:center;
  width:3.5rem; height:3.5rem;
  border:1px solid rgba(239,230,220,.24);
  border-radius:50%;
  transition:border-color .3s var(--ease), transform .3s var(--ease), background-color .3s var(--ease);
}
.ig__glyph svg{width:1.5rem; height:1.5rem}
.ig__label{
  font-size:.68rem; font-weight:600;
  letter-spacing:.22em; text-transform:uppercase;
}
.ig:hover{color:var(--lamp)}
.ig:hover .ig__glyph{
  border-color:var(--lamp);
  background:rgba(232,184,127,.08);
  transform:translateY(-2px);
}
.s--final .lede{color:#E4DAD1}

/* ---------- footer ---------- */
.foot{
  background:#07060A;
  padding:3rem 0 8rem;   /* clears the sticky dock */
  border-top:1px solid rgba(239,230,220,.07);
}
.foot__inner{text-align:center}
.foot__legal{
  font-size:.75rem; line-height:1.7; color:#8A8290;
  max-width:60ch; margin:0 auto 1rem;
}
.foot__meta{font-size:.75rem; color:#8A8290; margin:0}
.foot__meta a{color:#A099AB; text-decoration:none}
.foot__meta a:hover{color:var(--lamp)}

/* ============================================================
   STICKY DOCK
   ============================================================ */
.dock{
  position:fixed; z-index:40;
  left:0; right:0; bottom:0;
  display:flex; align-items:center; justify-content:center;
  gap:clamp(1rem,3vw,2.5rem);
  padding:.9rem var(--gut);
  background:rgba(9,8,12,.96);
  -webkit-backdrop-filter:none;
  backdrop-filter:none;
  border-top:1px solid rgba(232,184,127,.2);
  transform:translateY(110%);
  transition:transform .5s var(--ease);
}
.dock.is-up{transform:none}
.dock__line{
  margin:0; font-size:.9rem; color:#BDB2B8;
}
.dock__line em{font-family:var(--display); font-style:italic; color:var(--lamp); font-size:1.05rem}

/* ============================================================
   LIGHTBOX
   ============================================================ */
.media--open{cursor:zoom-in}

.lb{
  position:fixed; inset:0; z-index:90;
  display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:center;
  gap:clamp(.5rem,2vw,1.5rem);
  padding:clamp(1rem,4vw,3rem);
  background:rgba(6,5,9,.94);
  -webkit-backdrop-filter:blur(18px);
  backdrop-filter:blur(18px);
  animation:lbIn .32s var(--ease) both;
}
.lb[hidden]{display:none}
@keyframes lbIn{from{opacity:0} to{opacity:1}}

.lb__frame{
  margin:0; justify-self:center;
  display:grid; justify-items:center; gap:1rem;
  max-width:100%;
}
.lb__img{
  height:min(66svh,720px);
  max-width:92vw;
  width:auto;
  object-fit:contain;
  border-radius:2px;
  box-shadow:0 40px 90px -30px rgba(0,0,0,.9);
  animation:lbImg .45s var(--ease) both;
}
@keyframes lbImg{from{opacity:0; transform:scale(.97)} to{opacity:1; transform:none}}
.lb__cap{
  margin:0;
  font-size:.7rem; letter-spacing:.22em; text-transform:uppercase;
  color:var(--smoke);
}
.lb__cta{position:absolute; left:50%; bottom:clamp(1rem,4vh,2.5rem); translate:-50% 0}

.lb__close,.lb__nav{
  background:transparent; border:1px solid rgba(239,230,220,.16);
  color:var(--linen);
  border-radius:50%;
  cursor:pointer; line-height:1;
  transition:border-color .3s var(--ease), color .3s var(--ease), background-color .3s var(--ease);
}
.lb__close:hover,.lb__nav:hover{border-color:var(--lamp); color:var(--lamp); background:rgba(232,184,127,.08)}
.lb__nav{width:3rem; height:3rem; font-size:1.7rem; padding:0 0 .22em}
.lb__close{
  position:absolute; top:clamp(1rem,3vw,2rem); right:clamp(1rem,3vw,2rem);
  width:2.6rem; height:2.6rem; font-size:1.5rem; padding:0 0 .1em;
  z-index:2;
}

@media (max-width:640px){
  .lb{grid-template-columns:1fr; grid-template-areas:"frame"}
  .lb__frame{grid-area:frame}
  .lb__nav{position:absolute; bottom:clamp(4.5rem,12vh,7rem); z-index:2}
  .lb__nav--prev{left:1rem}
  .lb__nav--next{right:1rem}
}

/* scroll lock — the lightbox is the only thing that takes over the viewport now */
body.is-locked{overflow:hidden}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width:900px){
  .split{grid-template-columns:1fr}
  .split--flip .split__media{order:2}
  .split__media{max-width:none}
  .denials{grid-template-columns:1fr}
  .grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:640px){
  .unlock__list{columns:1}
  .hero{align-content:safe end}
  .hero__inner{padding-bottom:clamp(3rem,10vh,5rem)}
  .hero__title{font-size:clamp(2.4rem,10vw,3.4rem)}
  .voice{padding-left:1rem}
  .dock{flex-direction:column; gap:.7rem; padding:.85rem var(--gut) 1.1rem}
  .dock__line{font-size:.8rem; text-align:center}
  .hero__cue{display:none}
}

/* Short laptops (1366x768, 1280x800): the hero copy stack is ~656px at full
   desktop type sizes and starts clipping from the top under ~740px of height. */
@media (min-width:641px) and (max-height:780px){
  .hero__inner{padding-bottom:2.5rem}
  .hero__title{font-size:clamp(2.6rem,5vw,4rem)}
  .hero__sub{margin-bottom:1.25rem}
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .reveal{opacity:1; transform:none}
  .wonders li{opacity:1; transform:none}
  .hero__slide.is-on{animation:none; transform:scale(1.02)}
  .grain{animation:none}
}
