/* ============================================================
   Eventory — "The Lantern Release"
   Night to dawn: the page travels from months out to the day itself.
   ============================================================ */

/* ---------- tokens ---------- */
:root{
  --night:#150E1E;
  --night-2:#241528;
  --wine:#4D0F17;
  --wine-lift:#6E2028;
  --crimson:#C7152D;
  --ember:#FF9E4A;
  --gold:#FFC96E;
  --dawn:#FAEDE3;
  --dawn-2:#F2DFD2;
  --cream:#F6F1E8;
  --ink:#2A1A20;
  --ink-soft:#7A5A61;

  --display:"Fraunces",Georgia,"Times New Roman",serif;
  --body:"Instrument Sans",system-ui,-apple-system,"Segoe UI",sans-serif;

  --t-hero:clamp(2.9rem,8.4vw,7rem);
  --t-h2:clamp(1.95rem,4.3vw,3.5rem);
  --t-h3:clamp(1.5rem,2.7vw,2.35rem);
  --t-body:clamp(1rem,1.15vw,1.1rem);

  --pad:clamp(5rem,10vw,9rem);
  --gut:clamp(1.25rem,5vw,4.5rem);
  --max:1240px;
  --max-wide:1360px;

  --ease:cubic-bezier(.22,.61,.36,1);
  --sky:var(--night);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body,h1,h2,h3,p,ul,figure,address{margin:0}
ul{padding:0;list-style:none}
img,picture,canvas{display:block;max-width:100%}
a{color:inherit}

html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  font-family:var(--body);
  font-size:var(--t-body);
  line-height:1.62;
  color:var(--cream);
  background:var(--night);
  overflow-x:clip;
  -webkit-font-smoothing:antialiased;
}

.skip{
  position:fixed;top:-100px;left:1rem;z-index:200;
  background:var(--cream);color:var(--wine);
  padding:.7rem 1.1rem;border-radius:.4rem;font-weight:600;
  transition:top .18s var(--ease);
}
.skip:focus{top:1rem}

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

/* ---------- atmosphere ---------- */
.sky{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  background:var(--sky);
  transition:background-color .25s linear;
}
.lanterns{
  position:fixed;inset:0;z-index:1;pointer-events:none;
  width:100%;height:100%;
}

/* ---------- shared ---------- */
.wrap{width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gut)}

.eyebrow{
  font-size:.7rem;font-weight:600;letter-spacing:.19em;text-transform:uppercase;
  color:var(--ember);margin-bottom:1rem;
}

.h2{
  font-family:var(--display);
  font-optical-sizing:auto;
  font-variation-settings:"SOFT" 44,"WONK" 1;
  font-size:var(--t-h2);font-weight:600;line-height:1.06;
  letter-spacing:-.022em;text-wrap:pretty;
}
.h3{
  font-family:var(--display);
  font-optical-sizing:auto;
  font-variation-settings:"SOFT" 40,"WONK" 1;
  font-size:var(--t-h3);font-weight:600;line-height:1.12;
  letter-spacing:-.018em;margin-bottom:.9rem;
}

.btn{
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--crimson);color:#fff;
  padding:.95rem 1.7rem;border-radius:999px;
  font-weight:600;font-size:.98rem;text-decoration:none;letter-spacing:.005em;
  box-shadow:0 12px 34px -14px rgba(199,21,45,.9);
  transition:transform .22s var(--ease),background-color .22s var(--ease),box-shadow .22s var(--ease);
}
.btn:hover{background:#E0203A;transform:translateY(-2px);box-shadow:0 18px 40px -14px rgba(199,21,45,.95)}
.btn:active{transform:translateY(0)}
.btn--sm{padding:.6rem 1.15rem;font-size:.88rem;box-shadow:none}
.btn--wine{background:var(--wine);box-shadow:0 12px 34px -16px rgba(77,15,23,.9)}
.btn--wine:hover{background:#6E2028}

.link-quiet{
  color:rgba(246,241,232,.72);text-decoration:none;font-size:.95rem;
  border-bottom:1px solid rgba(246,241,232,.28);padding-bottom:2px;
  transition:color .2s var(--ease),border-color .2s var(--ease);
}
.link-quiet:hover{color:var(--gold);border-color:var(--gold)}

/* scroll reveal — only hide when JS is present to bring it back */
.js .rise{opacity:0;transform:translateY(26px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.js .rise.is-in{opacity:1;transform:none}

/* ---------- nav ---------- */
.nav{
  position:fixed;inset:0 0 auto;z-index:100;
  display:flex;align-items:center;justify-content:space-between;
  gap:1rem;padding:1.05rem var(--gut);
  transition:background-color .4s var(--ease),backdrop-filter .4s var(--ease),padding .4s var(--ease);
}
.nav.is-stuck{
  background:rgba(21,14,30,.74);
  backdrop-filter:blur(14px) saturate(1.2);
  -webkit-backdrop-filter:blur(14px) saturate(1.2);
  padding-block:.72rem;
  box-shadow:0 1px 0 rgba(246,241,232,.09);
}
.nav__brand{display:block;line-height:0}
.nav__brand img{width:auto;height:30px}
.nav__links{display:flex;align-items:center;gap:clamp(.9rem,2vw,1.9rem)}
.nav__links a{
  text-decoration:none;font-size:.92rem;font-weight:500;
  color:rgba(246,241,232,.82);transition:color .2s var(--ease);
}
.nav__links a:hover{color:var(--gold)}
.nav__links .btn{color:#fff}
.nav__links .btn:hover{color:#fff}

/* language switch — a segmented pill. Deliberately not an <a>, so the phone
   rule below (which folds the text links away) leaves it standing. */
.lang{
  display:flex;align-items:center;flex:0 0 auto;
  gap:2px;padding:2px;border-radius:999px;line-height:1;
  background:rgba(246,241,232,.07);
  border:1px solid rgba(246,241,232,.2);
}
.lang__btn{
  -webkit-appearance:none;appearance:none;border:0;background:none;cursor:pointer;
  font-family:var(--body);font-size:.74rem;font-weight:600;letter-spacing:.09em;
  color:rgba(246,241,232,.72);
  padding:.34rem .58rem;border-radius:999px;
  transition:color .2s var(--ease),background-color .2s var(--ease);
}
.lang__btn:hover{color:var(--gold)}
.lang__btn[aria-pressed="true"]{background:var(--cream);color:var(--wine)}
.lang__btn[aria-pressed="true"]:hover{color:var(--wine)}

@media (max-width:820px){
  .nav__links a:not(.btn){display:none}
  .nav__brand img{height:26px}
}
/* small phones: brand + switch + button have to share 320-380px */
@media (max-width:400px){
  .nav{gap:.55rem;padding-inline:1rem}
  .nav__brand img{height:22px}
  .nav__links{gap:.55rem}
  .lang__btn{padding:.3rem .46rem;font-size:.7rem;letter-spacing:.06em}
  .nav__links .btn--sm{padding:.5rem .85rem;font-size:.8rem}
}

/* ---------- hero ---------- */
.hero{
  position:relative;z-index:2;
  min-height:100svh;min-height:100vh;
  display:grid;align-content:end;
  padding:0 var(--gut) clamp(4.5rem,11vh,8rem);
  overflow:hidden;
}
.hero__img{position:absolute;inset:0;z-index:0}
.hero__img img{
  width:100%;height:100%;object-fit:cover;object-position:52% 42%;
  will-change:transform;
}
.hero__veil{
  position:absolute;inset:0;z-index:1;
  background:
    radial-gradient(120% 78% at 68% 24%,rgba(21,14,30,0) 38%,rgba(21,14,30,.62) 100%),
    linear-gradient(180deg,rgba(21,14,30,.72) 0%,rgba(21,14,30,.1) 26%,rgba(21,14,30,.55) 66%,var(--night) 100%);
}
.hero__copy{position:relative;z-index:2;width:100%;max-width:var(--max);margin-inline:auto}
.hero__title{
  font-family:var(--display);
  font-optical-sizing:auto;
  font-variation-settings:"SOFT" 60,"WONK" 1;
  font-size:var(--t-hero);font-weight:500;line-height:.94;
  letter-spacing:-.038em;
  text-shadow:0 2px 40px rgba(21,14,30,.5);
}
.hero__title .i{
  font-style:italic;font-weight:600;
  color:var(--gold);
  text-shadow:0 0 46px rgba(255,201,110,.42);
}
.hero__sub{
  max-width:34rem;margin-top:1.5rem;
  color:rgba(246,241,232,.84);font-size:clamp(1rem,1.5vw,1.16rem);
}
.hero__cta{display:flex;align-items:center;gap:1.5rem;flex-wrap:wrap;margin-top:2.1rem}

.hero__scroll{
  position:absolute;left:50%;bottom:1.7rem;z-index:2;
  translate:-50% 0;
  width:1px;height:52px;background:rgba(246,241,232,.22);overflow:hidden;
}
.hero__scroll span{
  position:absolute;inset:0;display:block;background:var(--gold);
  animation:trickle 2.4s var(--ease) infinite;
}
@keyframes trickle{
  0%{transform:translateY(-100%)}
  60%,100%{transform:translateY(100%)}
}

/* staggered hero entrance */
.r{opacity:0;transform:translateY(20px);animation:rin .95s var(--ease) forwards}
.hero__title .r:nth-child(1){animation-delay:.15s}
.hero__title .r:nth-child(2){animation-delay:.24s}
.hero__title .r:nth-child(3){animation-delay:.33s}
.hero__title .r:nth-child(4){animation-delay:.42s}
.hero__sub{animation-delay:.6s}
.hero__cta{animation-delay:.74s}
.hero__title .r{display:inline-block}
@keyframes rin{to{opacity:1;transform:none}}

/* ---------- features: the pinned MacBook sequence ---------- */
.feat{position:relative;z-index:2}
/* the machine now assembles in the first stretch rather than the third, so the
   track can lose a screen without hurrying any of the four shots */
.feat__track{position:relative;height:560vh}
.feat__stage{
  position:sticky;top:0;height:100svh;height:100vh;
  width:100%;max-width:var(--max-wide);margin-inline:auto;padding-inline:var(--gut);
  display:grid;align-content:center;
  grid-template-columns:minmax(0,1fr);
  row-gap:clamp(1.6rem,4vw,2.6rem);
}

/* text slot — every slide stacks in one cell and cross-fades */
.feat__text{display:grid;align-content:center}
.slide{grid-area:1/1;max-width:32rem}
.slide p:not(.eyebrow){color:rgba(246,241,232,.78)}
.slide__lede{margin-top:1rem}
.js .slide{opacity:0;transform:translateY(18px);pointer-events:none}
.js .slide.is-on{opacity:1;transform:none;pointer-events:auto}
.slide{transition:opacity .5s var(--ease),transform .5s var(--ease)}

/* ---- the machine ----
   Three supplied drawings texture one 3D scene: the bezel (with its display
   knocked out) on the front of the lid, the aluminium shell on its back, and
   the keyboard deck laid flat from the hinge. Geometry follows the artwork. */
.mac{
  /* Negative tilt puts the camera ABOVE the machine; the lid folds forward
     over the deck to close, so at rest we look down onto the aluminium shell
     and the face only swings into view as it opens. */
  --tilt:-24deg;     /* -24 = looking down on it, -8 = near eye level */
  --open:-89.3deg;   /* -89.3 = shut on the deck, -2 = open */
  --power:0;         /* display wake */
  --u:0px;                        /* 1/100 of the lid's width, set by script */
  --wall:calc(var(--u) * 3.835);  /* base thickness, per the lip drawing */
  width:100%;
  /* the deck is positioned out of flow, so reserve its projected height here
     or the grid centres the lid alone and the base hangs off the fold */
  padding-bottom:20%;
  perspective:1900px;
  perspective-origin:50% 38%;
  /* shut, the lid lies forward and projects low; lift it back to centre */
  translate:0 calc(var(--lift,0) * -19%);
}
.mac__tilt{position:relative;transform-style:preserve-3d;transform:rotateX(var(--tilt))}

.mac__lid{
  position:relative;width:100%;
  aspect-ratio:878.6/594.6;           /* the bezel drawing */
  transform-origin:50% 100%;
  transform-style:preserve-3d;
  transform:rotateX(var(--open));
}
/* Which side of the lid we can see is decided by script, not by
   backface-visibility: WebKit gets that wrong inside preserve-3d and would let
   the display show through a shut lid. --face is 1 once the lid has turned
   past the camera, 0 while its aluminium back is toward us. The two mechanisms
   must not both be on — their thresholds differ slightly and the lid blinks
   out in the frames where they disagree. */
.mac__face,.mac__shell{position:absolute;inset:0}
.mac__face{opacity:var(--face,0)}
.mac__shell{opacity:calc(1 - var(--face,0))}

/* front of the lid: the display sits in the bezel's window and the bezel
   paints back over its edges, so the notch lands on top of the screenshot */
.mac__face::after{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:url(../img/v2/mac-face.svg) 50% 50%/100% 100% no-repeat;
}
.mac__screen{
  position:absolute;left:1.252%;top:1.85%;width:97.496%;height:93.004%;
  overflow:hidden;background:#07070A;
}
.mac__img{
  position:absolute;inset:0;display:block;
  opacity:0;transition:opacity .55s var(--ease);
}
.mac__img.is-on{opacity:var(--power)}
.mac__img img{
  width:100%;height:100%;object-fit:cover;
  /* Crop past the black canvas baked into each source capture. Scaling both
     axes together keeps the screenshot's original proportions intact. */
  transform:scale(1.14);
  transform-origin:42% 28%;
}
/* Shift the zoom's focal origin without exposing the capture's black edges. */
.mac__img[data-i="0"] img{object-position:left top;transform-origin:42% 28%}
.mac__img[data-i="1"] img{object-position:right top;transform-origin:58% 28%}
.mac__img[data-i="2"] img{object-position:left top;transform-origin:42% 28%}
.mac__img[data-i="3"] img{object-position:left top;transform-origin:42% 28%}
/* the display itself waking up */
.mac__screen::after{
  content:"";position:absolute;inset:0;background:#07070A;
  opacity:calc(1 - var(--power));transition:opacity .4s linear;
}
.mac__glare{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(104deg,rgba(255,255,255,.10) 0 14%,transparent 38%);
  opacity:calc(var(--power) * .55);
}

/* back of the lid: what you see while it is shut */
/* the lid is deliberately paper-thin — no rim, the screen reads as a sheet */
.mac__shell{
  transform:rotateY(180deg);
  background:url(../img/v2/mac-shell.svg) 50% 50%/100% 100% no-repeat;
}
/* seat the bare aluminium into the night rather than letting it glare */
.mac__shell::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(158deg,rgba(255,201,110,.09) 0%,rgba(21,14,30,.26) 58%,rgba(21,14,30,.40) 100%);
}

/* ---- thickness ----
   Only the base carries any. The lid stays a single sheet, and the base is
   extruded at the front alone. --u is one hundredth of the lid's laid-out
   width, set by script, so --wall stays proportional at any viewport (3.835
   units, taken from the lip drawing, whose height is 3.835% of its width). */

/* keyboard deck, hinged flat and running toward the viewer */
/* aspect-ratio, not a percentage height: a % height would resolve against the
   lid's height and letterbox the drawing inside an over-wide box */
.mac__deck{
  position:absolute;top:100%;left:0;width:100%;
  /* the lid's footprint, not the deck drawing's own 271.8/179.5 — the two
     drawings disagree by 1.6% and the overhang opens a seam you can see
     through when it is shut */
  aspect-ratio:878.6/594.6;
  /* nudged just below the lid's plane: with no rim the two are coplanar when
     shut, and the deck's hinge edge fights through the sheet */
  transform-origin:50% 0;
  transform:rotateX(90deg) translateZ(calc(var(--u) * -0.55));
  transform-style:preserve-3d;
  /* metal behind the drawing: its rounded front corners stop short of the box
     and the seam would otherwise show the night sky through the machine */
  background:url(../img/v2/mac-deck.svg) 50% 0/100% 100% no-repeat,
             linear-gradient(180deg,#e9eaec,#dcdde0);
  border-radius:0 0 3% 3%;
}
/* front elevation lifted straight from the drawing — scallop, ends and feet */
.mac__wall--front{
  position:absolute;
  top:100%;left:0;width:100%;height:var(--wall);
  transform-origin:0 0;transform:rotateX(-90deg);
  background:url(../img/v2/mac-lip.svg) 50% 0/100% 100% no-repeat;
}
/* progress rail */
.feat__rail{display:flex;gap:9px;justify-self:start;opacity:var(--rail,0);transition:opacity .4s var(--ease)}
.feat__rail b{
  width:26px;height:2px;border-radius:2px;background:rgba(246,241,232,.22);
  transition:background-color .45s var(--ease),width .45s var(--ease);
}
.feat__rail b.is-on{background:var(--gold);width:40px;box-shadow:0 0 12px rgba(255,201,110,.7)}

/* tablet and up: copy beside the machine */
@media (min-width:900px){
  .feat__stage{
    grid-template-columns:14px minmax(0,.82fr) minmax(0,1.32fr);
    column-gap:clamp(1.6rem,3.6vw,3.4rem);
    align-items:center;row-gap:0;
  }
  .feat__text{grid-column:2;grid-row:1}
  .mac{grid-column:3;grid-row:1}
  .feat__rail{
    grid-column:1;grid-row:1;align-self:center;
    flex-direction:column;gap:10px;
  }
  .feat__rail b{width:2px;height:26px}
  .feat__rail b.is-on{width:2px;height:46px}
}

/* phones: flatten the perspective so the near edge doesn't flare past the
   gutter, and shorten the deck so the whole machine clears the fold */
@media (max-width:760px){
  .mac{perspective:2600px}
  .slide{max-width:none}
}

/* ---------- whatsapp assistant ---------- */
.chat{position:relative;z-index:2}
/* sized against the thread, not by feel: ~718px of transcript needs a little
   over a screen and a half of page scroll to read at a comfortable pace. The
   last two thirds of a screen hold the phone still while the code is scanned. */
.chat__track{position:relative;height:300vh}
.chat__stage{
  position:sticky;top:0;height:100svh;height:100vh;
  display:grid;align-content:center;
  gap:clamp(1.4rem,5vw,4rem);
  width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
.chat__lede{max-width:37rem}
.chat__note{margin-top:1.1rem;color:rgba(246,241,232,.74);max-width:29rem}
@media (max-width:899px){
  .chat__note{font-size:.92rem}
  .chat__stage{padding-top:3.5rem}
}

.phone{
  width:100%;max-width:384px;justify-self:center;
  border-radius:26px;overflow:hidden;
  background:#EFE7DD;
  box-shadow:0 50px 100px -30px rgba(0,0,0,.8),0 0 150px -40px rgba(255,201,110,.5);
  border:1px solid rgba(246,241,232,.16);
}
.phone__top{
  display:flex;align-items:center;gap:.7rem;
  background:var(--wine);padding:.85rem 1rem;
}
.phone__avatar{
  width:34px;height:34px;border-radius:50%;flex:0 0 auto;
  background:var(--cream);
  display:grid;place-items:center;overflow:hidden;
}
.phone__avatar img{width:76%;height:76%;object-fit:contain}
.phone__who{display:flex;flex-direction:column;line-height:1.25}
.phone__who b{
  display:flex;align-items:center;gap:.3rem;
  font-size:.92rem;font-weight:600;color:var(--cream);
}
.phone__tick{width:15px;height:15px;flex:0 0 auto}

/* Fixed height window, top-anchored: the thread is taller than the frame and
   the script translates the feed through it, so a long invitation is *read*
   rather than dumped. It also guarantees the sticky stage never outgrows the
   viewport. Without JS the window opens up and the whole thread just prints. */
.phone__log{
  position:relative;
  height:clamp(286px,46svh,468px);
  overflow:hidden;
  background-image:radial-gradient(rgba(77,15,23,.05) 1px,transparent 1px);
  background-size:16px 16px;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 26px);
  mask-image:linear-gradient(180deg,transparent 0,#000 26px);
}
.phone__feed{
  position:relative;
  display:flex;flex-direction:column;gap:.45rem;
  /* clears the 26px top mask, so the invitation plate starts un-dimmed */
  padding:1.9rem .9rem 1.1rem;
  will-change:transform;
}
.phone__feed>*{flex:0 0 auto}
.bub{
  max-width:82%;padding:.55rem .8rem;border-radius:12px;
  font-size:.875rem;line-height:1.45;color:#20161A;
  box-shadow:0 1px 1px rgba(0,0,0,.07);
}

/* the invitation itself: image plate on top, message body under it */
.bub--card{max-width:89%;padding:4px 4px 0}
.bub__img{
  width:100%;height:auto;display:block;
  aspect-ratio:880/587;object-fit:cover;
  border-radius:9px;background:#E6DED6;
}
.bub__t{padding:.6rem .45rem .65rem}
.bub__t p+p{margin-top:.66em}
.bub__names{
  font-family:var(--display);
  font-optical-sizing:auto;
  font-variation-settings:"SOFT" 40,"WONK" 1;
  font-size:1.06rem;font-weight:600;line-height:1.14;
  letter-spacing:-.012em;color:var(--wine);
}

/* the receipt at the end of the thread */
.bub--rsvp{display:flex;flex-direction:column;gap:.12rem;max-width:89%}
.bub__ok{
  display:flex;align-items:baseline;gap:.35rem;
  margin-bottom:.3rem;font-weight:600;color:#1E7A45;
}
.bub__ok::before{content:"✓";font-size:.95em}

/* Eventory's follow-up media message: the code itself, cropped to the plate,
   with the caption inside the same WhatsApp-style bubble. */
/* narrower than the other media bubbles on purpose: the whole plate, caption
   and all, has to sit inside the phone's window while it is being scanned */
.bub--qr{max-width:74%;padding:4px}
.bub__qr-img{
  width:100%;height:auto;display:block;
  aspect-ratio:1;object-fit:contain;
  border-radius:9px;background:#F7F2E9;
}
.bub__caption{padding:.55rem .5rem .45rem}

/* ---------- the scan ---------- */
/* Everything below paints *over* the plate. The image is never transformed,
   so the code stays square and legible while the reticle works across it. */
.qr-wrapper{
  --scan:#1F9D72;
  position:relative;border-radius:9px;overflow:hidden;
  background:#F7F2E9;
}

.qr-corner{
  position:absolute;width:20px;height:20px;
  border:2px solid var(--scan);
  opacity:0;transition:opacity .28s var(--ease);
}
.qr-corner--tl{top:7px;left:7px;border-right:0;border-bottom:0;border-radius:4px 0 0 0}
.qr-corner--tr{top:7px;right:7px;border-left:0;border-bottom:0;border-radius:0 4px 0 0}
.qr-corner--bl{bottom:7px;left:7px;border-right:0;border-top:0;border-radius:0 0 0 4px}
.qr-corner--br{bottom:7px;right:7px;border-left:0;border-top:0;border-radius:0 0 4px 0}
.qr-wrapper.is-scanning .qr-corner{opacity:1}

.scan-line{
  position:absolute;left:8px;right:8px;height:2px;top:8px;
  border-radius:2px;
  background:linear-gradient(90deg,transparent,var(--scan) 18%,#5BE3AE 50%,var(--scan) 82%,transparent);
  box-shadow:0 0 10px 2px rgba(31,157,114,.55),0 0 26px 6px rgba(31,157,114,.28);
  opacity:0;
}
.qr-wrapper.is-scanning .scan-line{
  opacity:1;
  animation:scan-qr 1.2s ease-in-out 2;
}
@keyframes scan-qr{
  0%{top:8px}
  50%{top:calc(100% - 10px)}
  100%{top:8px}
}

.success-overlay{
  position:absolute;inset:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.7rem;padding:1rem;text-align:center;
  background:rgba(31,157,114,.84);
  opacity:0;transform:scale(1.08);
  transition:opacity .34s var(--ease),transform .34s var(--ease);
}
.qr-wrapper.is-success .success-overlay{opacity:1;transform:scale(1)}

.success-overlay__badge{
  display:grid;place-items:center;
  width:64px;height:64px;border-radius:50%;
  background:#fff;
  box-shadow:0 10px 26px -10px rgba(0,0,0,.5);
  transform:scale(.6);
  transition:transform .38s cubic-bezier(.2,1.4,.4,1) .08s;
}
.qr-wrapper.is-success .success-overlay__badge{transform:scale(1)}
.success-overlay__badge svg{
  width:38px;height:38px;
  fill:none;stroke:#127A57;
  stroke-width:3.6;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:34;stroke-dashoffset:34;
}
.qr-wrapper.is-success .success-overlay__badge svg{
  animation:tick-draw .34s var(--ease) .3s forwards;
}
@keyframes tick-draw{to{stroke-dashoffset:0}}

.success-overlay__toast{
  font-size:.8rem;font-weight:600;line-height:1.35;color:#fff;
  background:rgba(11,58,42,.5);
  border:1px solid rgba(255,255,255,.28);
  border-radius:999px;padding:.32rem .78rem;
  opacity:0;transform:translateY(6px);
  transition:opacity .3s var(--ease) .45s,transform .3s var(--ease) .45s;
}
.qr-wrapper.is-success .success-overlay__toast{opacity:1;transform:none}

@media (prefers-reduced-motion:reduce){
  .qr-wrapper.is-scanning .scan-line{animation:none}
  .success-overlay__badge,.success-overlay__toast{transition-duration:.01ms}
  .qr-wrapper.is-success .success-overlay__badge svg{animation-duration:.01ms}
}

.js .bub{
  opacity:0;transform:translateY(9px) scale(.97);
  transition:opacity .42s var(--ease),transform .42s var(--ease);
}
.bub b{font-weight:600}
.bub.in{background:#fff;align-self:flex-start;border-top-left-radius:3px}
.bub.out{background:#DEF0CE;align-self:flex-end;border-top-right-radius:3px}
.js .bub.is-in{opacity:1;transform:none}

.phone__bar{padding:.7rem .9rem 1rem;background:#EFE7DD}
.phone__bar span{
  display:block;background:#fff;border-radius:999px;
  padding:.55rem 1rem;font-size:.8rem;color:#A69A92;
  box-shadow:0 1px 1px rgba(0,0,0,.06);
}

@media (min-width:900px){
  .chat__stage{
    grid-template-columns:minmax(0,1fr) 384px;
    align-items:center;column-gap:clamp(3rem,7vw,6rem);
  }
  .phone{justify-self:end}
}

/* ---------- event day: scan → transfer → print ---------- */
.door{
  position:relative;z-index:2;
  background:linear-gradient(180deg,rgba(21,14,30,0),rgba(21,14,30,.16) 46%,rgba(21,14,30,.10));
}
.door__track{position:relative;height:200vh}
.door__stage{
  position:sticky;top:0;height:100svh;height:100vh;
  display:grid;align-content:center;
  gap:clamp(2rem,5vw,3.4rem);
  width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);
}
.door__lede{max-width:37rem}
.door__note{margin-top:1.1rem;color:rgba(246,241,232,.74);max-width:31rem}

/* phone → beam → printer, on one bench. The printed label overhangs the
   printer's layout box, so the bench is padded to keep it inside the stage. */
.door__rig{
  display:flex;align-items:center;justify-content:center;
  gap:clamp(.9rem,2.4vw,2rem);
  width:100%;padding-bottom:clamp(84px,14vh,150px);
}

/* the guest's phone, held up at the door */
.scanner{
  flex:0 0 auto;width:clamp(126px,17vw,178px);
  padding:9px;border-radius:22px;
  background:linear-gradient(180deg,#33222B,#170F14);
  border:1px solid rgba(246,241,232,.16);
  box-shadow:0 34px 60px -28px rgba(0,0,0,.9),0 0 100px -34px rgba(255,201,110,.45);
}
.scanner__bar{
  display:block;width:30%;height:4px;margin:1px auto 8px;
  border-radius:999px;background:rgba(246,241,232,.22);
}
.scanner__screen{border-radius:14px;overflow:hidden;background:#F7F2E9}
.scanner__qr{width:100%;height:auto;display:block;aspect-ratio:1}
.scanner .qr-wrapper{border-radius:14px}
.scanner .success-overlay__badge{width:46px;height:46px}
.scanner .success-overlay__badge svg{width:27px;height:27px}

/* the wire between them. Hidden until the code has actually been read. */
.data-transfer{
  position:relative;flex:1 1 auto;min-width:56px;max-width:230px;height:2px;
  border-radius:2px;overflow:hidden;
  background:linear-gradient(90deg,rgba(246,241,232,.04),rgba(246,241,232,.2),rgba(246,241,232,.04));
  opacity:0;transition:opacity .28s var(--ease);
}
.data-transfer.is-live{opacity:1}
.data-transfer::after{
  content:"";position:absolute;top:0;left:-60px;
  width:60px;height:100%;
  background:linear-gradient(90deg,transparent,#1F9D72,#5BE3AE,#1F9D72,transparent);
  box-shadow:0 0 12px 2px rgba(31,157,114,.7);
}
/* one pass, not a stream: the guest's record leaves the phone once */
.data-transfer.is-sending::after{animation:transfer-data .55s linear 1}
@keyframes transfer-data{
  from{left:-60px}
  to{left:100%}
}

/* the thermal label printer on the registration desk */
.printer{
  position:relative;flex:0 0 auto;
  width:clamp(158px,21vw,232px);
}
.printer__body{
  position:relative;height:116px;
  border-radius:16px 16px 11px 11px;
  background:linear-gradient(180deg,#43303A 0%,#2A1C24 46%,#1A1116 100%);
  border:1px solid rgba(246,241,232,.14);
  box-shadow:0 30px 50px -24px rgba(0,0,0,.9),inset 0 1px 0 rgba(246,241,232,.16);
}
.printer__cover{
  position:absolute;left:9%;right:9%;top:-10px;height:24px;
  border-radius:12px 12px 4px 4px;
  background:linear-gradient(180deg,#543C48,#33232B);
  border:1px solid rgba(246,241,232,.13);
  box-shadow:inset 0 1px 0 rgba(246,241,232,.2);
}
.printer__vent{
  position:absolute;left:14%;right:14%;top:20px;height:11px;border-radius:3px;
  background:repeating-linear-gradient(90deg,rgba(0,0,0,.42) 0 2px,transparent 2px 6px);
  opacity:.7;
}
.printer__slot{
  position:absolute;left:8%;right:8%;top:87px;height:9px;border-radius:3px;
  background:#080506;
  box-shadow:inset 0 3px 5px rgba(0,0,0,.95),0 1px 0 rgba(246,241,232,.2);
}
/* status light and wordmark sit above the slot: the label covers everything
   below it the moment the machine starts feeding paper */
.printer__led{
  position:absolute;left:11%;top:54px;width:7px;height:7px;border-radius:50%;
  background:#1F9D72;box-shadow:0 0 9px 1px rgba(31,157,114,.9);
}
.printer.is-printing .printer__led{animation:led-blink .32s steps(1,end) infinite}
@keyframes led-blink{50%{opacity:.35;box-shadow:none}}
.printer__mark{
  position:absolute;right:11%;top:50px;
  font-size:.54rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:rgba(246,241,232,.42);
}
.printer__feet{
  position:absolute;left:8%;right:8%;top:116px;height:7px;
  border-radius:0 0 7px 7px;
  background:#120C10;
  box-shadow:0 12px 24px -10px rgba(0,0,0,.9);
}
.printer.is-printing{animation:printer-vibration .12s linear infinite}
@keyframes printer-vibration{
  0%,100%{transform:translateX(0)}
  50%{transform:translateX(1px)}
}

/* Top of this box sits on the slot, so the label is inside the machine until
   the platen has fed it past the lip. */
.printer__out{
  position:absolute;left:0;right:0;top:87px;height:220px;
  overflow:hidden;pointer-events:none;z-index:3;
}
.printed-label{
  position:absolute;top:0;left:50%;width:76%;
  transform:translate(-50%,-100%);
  padding:.62rem .7rem .72rem;
  border-radius:1px 1px 3px 3px;
  background:#FBF8F1;color:#171012;text-align:left;
  background-image:repeating-linear-gradient(180deg,rgba(23,16,18,.045) 0 1px,transparent 1px 5px);
  box-shadow:0 16px 26px -14px rgba(0,0,0,.8);
}
.printed-label.is-printing{animation:print-label 1.5s linear forwards}
.printed-label.is-done{transform:translate(-50%,10px)}
/* stepped rather than smooth: a thermal head advances the paper a strip at a
   time, and the pauses are what make it read as printing */
@keyframes print-label{
  0%{transform:translate(-50%,-100%)}
  10%{transform:translate(-50%,-100%)}
  22%{transform:translate(-50%,-78%)}
  30%{transform:translate(-50%,-78%)}
  42%{transform:translate(-50%,-56%)}
  50%{transform:translate(-50%,-56%)}
  62%{transform:translate(-50%,-34%)}
  70%{transform:translate(-50%,-34%)}
  82%{transform:translate(-50%,-12%)}
  90%{transform:translate(-50%,-12%)}
  100%{transform:translate(-50%,10px)}
}

.printed-label__head{
  font-size:.52rem;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;line-height:1.3;
  padding-bottom:.34rem;border-bottom:1.5px solid #171012;
}
.printed-label__name{
  font-size:.88rem;font-weight:700;line-height:1.16;
  letter-spacing:-.012em;margin-top:.52rem;
}
.printed-label__meta{
  font-size:.68rem;line-height:1.3;margin-top:.2rem;color:#544348;
}
.printed-label__table{
  font-size:1.12rem;font-weight:700;letter-spacing:.03em;
  line-height:1.1;margin-top:.42rem;
}

/* phones: stack the bench, and send the data downward instead of across */
@media (max-width:719px){
  .door__stage{padding-top:3rem}
  .door__note{font-size:.92rem}
  .door__rig{flex-direction:column;gap:.7rem;padding-bottom:clamp(66px,11vh,110px)}
  .data-transfer{
    width:2px;min-width:0;max-width:none;height:46px;flex:0 0 auto;
    background:linear-gradient(180deg,rgba(246,241,232,.04),rgba(246,241,232,.2),rgba(246,241,232,.04));
  }
  .data-transfer::after{
    left:0;top:-46px;width:100%;height:46px;
    background:linear-gradient(180deg,transparent,#1F9D72,#5BE3AE,#1F9D72,transparent);
  }
  .data-transfer.is-sending::after{animation:transfer-data-v .55s linear 1}
  @keyframes transfer-data-v{
    from{top:-46px}
    to{top:100%}
  }
  /* the label has to hold a full name on one line, so the machine gets wider
     rather than the type getting smaller */
  .printer{width:196px}
  .printed-label{width:80%}
}

@media (prefers-reduced-motion:reduce){
  .printer.is-printing{animation:none}
  .printer.is-printing .printer__led{animation:none}
  .data-transfer.is-sending::after{animation:none;left:0;width:100%;opacity:.6}
}

/* desktop only: the scanner, printer and beam between them get more room to
   breathe. Tablet keeps the base clamp values, phones keep the stacked layout
   above. */
@media (min-width:900px){
  .door__rig{gap:clamp(1.6rem,3vw,3.2rem)}
  .scanner{width:clamp(180px,15vw,238px)}
  .printer{width:clamp(215px,19vw,310px)}
  .data-transfer{max-width:300px}
}

/* ---------- advantage ---------- */
/* A soft scrim keeps body copy legible once the sky has warmed to clay. */
.edge{
  position:relative;z-index:2;padding-block:var(--pad);
  background:linear-gradient(180deg,rgba(21,14,30,.10),rgba(21,14,30,.32) 40%,rgba(21,14,30,.22));
}
.edge .h2{max-width:20ch;margin-bottom:clamp(2.6rem,6vw,4.2rem)}
.edge__list{display:grid;gap:clamp(1.6rem,3.4vw,2.6rem)}
@media (min-width:760px){.edge__list{grid-template-columns:1fr 1fr}}

.edge__list li{
  padding-top:1.4rem;
  border-top:1px solid rgba(246,241,232,.2);
}
.edge__was{
  font-size:.88rem;color:rgba(246,241,232,.74);
  text-decoration:line-through;text-decoration-color:rgba(255,190,120,.9);
  text-decoration-thickness:1.5px;margin-bottom:.45rem;
}
.edge__is{
  font-family:var(--display);
  font-optical-sizing:auto;
  font-variation-settings:"SOFT" 40,"WONK" 1;
  font-size:clamp(1.25rem,2vw,1.6rem);font-weight:600;line-height:1.15;
  letter-spacing:-.015em;margin-bottom:.6rem;
}
.edge__d{color:rgba(246,241,232,.82);font-size:.97rem;max-width:34rem}

/* ---------- pricing ---------- */
.price{
  position:relative;z-index:2;
  padding-block:var(--pad);
  background:linear-gradient(180deg,rgba(250,237,227,0) 0%,var(--dawn) 13%,var(--dawn) 100%);
  color:var(--ink);
}
.price .eyebrow{color:var(--crimson)}
.price__head{max-width:44rem;margin-bottom:clamp(2.4rem,5vw,3.6rem)}

.price__card{
  display:grid;gap:clamp(1.8rem,4vw,3.4rem);
  background:#fff;
  border:1px solid rgba(77,15,23,.1);
  border-radius:22px;
  padding:clamp(1.7rem,4vw,3.2rem);
  box-shadow:0 40px 80px -40px rgba(77,15,23,.35);
}
@media (min-width:840px){.price__card{grid-template-columns:1fr 1fr;gap:clamp(2.5rem,5vw,4.5rem)}}

.price__tag{
  font-size:.7rem;font-weight:600;letter-spacing:.19em;text-transform:uppercase;
  color:var(--ink-soft);margin-bottom:.7rem;
}
.price__num{
  font-family:var(--display);
  font-optical-sizing:auto;
  font-variation-settings:"SOFT" 44,"WONK" 1;
  font-size:clamp(2.5rem,5.4vw,3.9rem);font-weight:600;line-height:1;
  letter-spacing:-.03em;color:var(--wine);
}
.price__num span{font-size:.42em;font-weight:500;margin-right:.32em;vertical-align:.42em;color:var(--ink-soft)}
.price__sub{margin:1rem 0 1.8rem;color:var(--ink-soft);font-size:.97rem;max-width:26rem}
.price__free{
  margin-top:1.6rem;padding:1rem 1.15rem;
  background:var(--dawn);border-radius:12px;
  font-size:.9rem;color:var(--ink-soft);line-height:1.55;
}
.price__free b{color:var(--wine);font-weight:600}

.price__list{display:grid;gap:.8rem;align-content:start}
.price__list li{
  position:relative;padding-left:1.7rem;
  font-size:.97rem;color:var(--ink);
}
.price__list li::before{
  content:"";position:absolute;left:0;top:.62em;
  width:9px;height:9px;border-radius:50%;
  background:radial-gradient(circle at 38% 34%,var(--gold),var(--ember) 62%,rgba(199,21,45,.85));
  box-shadow:0 0 9px rgba(255,158,74,.6);
}

/* ---------- footer ---------- */
.foot{
  position:relative;z-index:2;
  background:var(--dawn-2);color:var(--ink);
  padding-block:clamp(3rem,7vw,5rem) 2rem;
}
.foot__grid{
  display:grid;gap:clamp(1.9rem,4vw,3rem);
  grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
}
.foot__brand img{width:auto;height:30px;margin-bottom:.9rem}
.foot__brand p{color:var(--ink-soft);font-size:.92rem;max-width:19rem}
.foot__col h3{
  font-family:var(--body);font-size:.7rem;font-weight:600;
  letter-spacing:.19em;text-transform:uppercase;color:var(--ink-soft);
  margin-bottom:.9rem;
}
.foot__col a,.foot__col address{
  display:block;font-style:normal;font-size:.93rem;
  color:var(--ink);text-decoration:none;margin-bottom:.45rem;
  transition:color .2s var(--ease);
}
.foot__col a:hover{color:var(--crimson)}
.foot__base{
  display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  margin-top:clamp(2.4rem,5vw,3.6rem);padding-top:1.4rem;
  border-top:1px solid rgba(77,15,23,.14);
  font-size:.84rem;color:var(--ink-soft);
}

/* ---------- no JS: unpin everything, let it read as a plain document ----------
   The machine has nothing driving it, so it stops being a machine: the four
   screens become a plain stack of figures and every slide is spelled out. */
html:not(.js) .lanterns{display:none}
html:not(.js) .phone__log{height:auto;-webkit-mask-image:none;mask-image:none}
html:not(.js) .phone__feed{padding-top:1.1rem}
html:not(.js) .hero__scroll{display:none}
html:not(.js) .feat__track,
html:not(.js) .chat__track{height:auto}
html:not(.js) .feat__stage,
html:not(.js) .chat__stage{
  position:static;height:auto;
  display:block;padding-block:var(--pad);
}
html:not(.js) .feat__rail{display:none}
html:not(.js) .feat__text{display:block}
html:not(.js) .slide{max-width:none;margin-bottom:clamp(1.6rem,4vw,2.4rem)}
html:not(.js) .mac{perspective:none;padding-bottom:0;translate:none;width:100%}
html:not(.js) .mac__tilt,
html:not(.js) .mac__lid{transform:none;aspect-ratio:auto}
html:not(.js) .mac__shell,
html:not(.js) .mac__deck,
html:not(.js) .mac__glare,
html:not(.js) .mac__face::after,
html:not(.js) .mac__screen::after{display:none}
/* nothing sets --face without script, so bring the display back explicitly or
   the four captures never paint at all */
html:not(.js) .mac__face{position:static;background:none;opacity:1}
html:not(.js) .mac__screen{
  position:static;width:auto;height:auto;background:none;overflow:visible;
  display:grid;gap:clamp(1.4rem,4vw,2.2rem);
}
html:not(.js) .mac__img{position:static;opacity:1}
html:not(.js) .mac__img img{
  height:auto;object-fit:contain;border-radius:10px;transform:none
}

/* ---------- motion off ----------
   The sequence stays (it is scroll-position driven, not autoplay) but the
   machine is handed over already open, so nothing swings or parallaxes. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .r,.rise{opacity:1 !important;transform:none !important}
  .bub{opacity:1 !important;transform:none !important}
  /* nothing is driving the feed, so open the window and print the thread */
  .phone__log{height:auto;-webkit-mask-image:none;mask-image:none}
  .phone__feed{transform:none !important;padding-top:1.1rem}
  .lanterns{display:none}
  .mac{--tilt:-6deg !important;--open:-2deg !important;--power:1 !important}
  .chat__track{height:auto}
  .chat__stage{position:static;height:auto;min-height:0}
  .hero__scroll{display:none}
}
