/* ==========================================================================
   NOBATE TOE — design tokens
   ========================================================================== */
@font-face{
  font-family:"DigiSarve";
  src:url("assets/fonts/DigiSarve.ttf") format("truetype");
  font-display:swap;
  font-weight:400 800;
}
/* Used ONLY for the dynamic name overlay on the page-1 letter image,
   matching the exact font the original Photoshop salutation used
   before that text was removed from the PNG. */
@font-face{
  font-family:"DigiDerakhshandeh";
  src:url("assets/fonts/DigiDerakhshandeh.ttf") format("truetype");
  font-display:swap;
  font-weight:400 800;
}

:root{
  --bg-1:#0a1226;          /* deep midnight blue */
  --bg-2:#16224a;          /* mid night blue, cleaner/more saturated than before */
  --text:#f0eee6;          /* warm off-white */
  --muted:#a7b0c9;         /* cool muted, for secondary text on navy */
  --accent:#8fc19a;        /* soft, slightly luminous natural green — "the light" */
  --accent-bright:#aee0b4; /* hover state, a touch brighter */
  --accent-ink:#0f2015;    /* text on top of the green */
  --star:#fdf6e3;          /* star color */
  --paper:#e7dcc2;         /* reference tone of the paper asset */
  --ink:#3c3628;           /* dark warm text on paper */

  --radius-lg:22px;
  --ease-soft:cubic-bezier(.22,.8,.2,1);

  --font-display:"DigiSarve",Tahoma,Arial,sans-serif;
  --font-body:"DigiSarve",Tahoma,Arial,sans-serif;

  /* ---- Admin-panel-controlled values (config.js / admin-panel.js) ----
     Defaults here reproduce the shipped design exactly; the panel only
     overrides them (via documentElement.style.setProperty) once someone
     actually moves a control. Keep these in sync with config.js's
     DEFAULT_CONFIG if either ever changes. */
  --nur-intro-x:0px;
  --nur-intro-y:0px;
  --nur-intro-font-size:20px;
  --nur-intro-line-height:1.7;
  --nur-intro-gap:10px;
  --nur-intro-greeting-font-size:36px;
  --nur-intro-greeting-gap:22px;
  --nur-intro-word-spacing:0px;

  --nur-envelope-y:0px;
  --nur-envelope-line-gap:9px;
  --nur-envelope-gap-to-envelope:10px;
  --nur-envelope-font-size:20px;
  --nur-envelope-word-spacing:0px;

  /* The letter card renders as one scaling image (.letter-stage-inner's
     width below); every px-sized thing overlaid on it needs to shrink at
     the same rate or it stays full-size on a card that's shrunk around
     it. 653px is note-page*.png's natural width - the size these numbers
     were tuned at. See --nur-letter-name-font-size/--nur-letter1-font-size
     etc. below for how this gets used. */
  --nur-card-scale:min(840px,92vw);
  --nur-card-reference-width:653px;

  --nur-letter-name-x:6%;
  --nur-letter-name-y:16%;
  --nur-letter-name-font-size:48px;
  --nur-letter-name-rotation:0deg;
  --nur-letter-name-gap:8px;
  --nur-letter-name-word-spacing:0px;

  --nur-final-y:0px;
  --nur-final-font-size:34px;
  --nur-final-word-spacing:0px;
  --nur-final-sig-y:96px;
  --nur-final-sig-font-size:15px;
  --nur-final-sig-word-spacing:0px;

  /* Letter pages 1-3 - real HTML text laid over the now-blank paper
     artwork (assets/note-page1/2/3.png). x/y/width are % (same reasoning
     as --nur-letter-name-x/y: the whole card scales as one image, so a
     fixed px position/width would overflow it on narrow screens) -
     positioned the same way as --nur-letter-name-* (right/top), just
     wrapping instead of nowrap since this is a paragraph block. */
  --nur-letter1-x:6%;
  --nur-letter1-y:21%;
  --nur-letter1-width:80%;
  --nur-letter1-font-size:17px;
  --nur-letter1-line-height:1.55;
  --nur-letter1-gap:8px;
  --nur-letter1-word-spacing:0px;

  --nur-letter2-x:6%;
  --nur-letter2-y:13%;
  --nur-letter2-width:80%;
  --nur-letter2-font-size:17px;
  --nur-letter2-line-height:1.55;
  --nur-letter2-gap:8px;
  --nur-letter2-word-spacing:0px;

  --nur-letter3-x:6%;
  --nur-letter3-y:13%;
  --nur-letter3-width:80%;
  --nur-letter3-font-size:17px;
  --nur-letter3-line-height:1.55;
  --nur-letter3-gap:8px;
  --nur-letter3-word-spacing:0px;

  /* Each page's own nav button - x/y are the button's CENTER point in %
     (so drag-to-position and width/height changes both stay anchored to
     the same point); width/height/font-size/border-radius are px, scaled
     by --nur-card-scale in .note-next-btn below exactly like the letter
     text above. */
  --nur-btn1-x:50%;
  --nur-btn1-y:87%;
  --nur-btn1-width:96px;
  --nur-btn1-height:47px;
  --nur-btn1-font-size:14px;
  --nur-btn1-radius:999px;
  --nur-btn1-scale:1;

  --nur-btn2-x:50%;
  --nur-btn2-y:88%;
  --nur-btn2-width:96px;
  --nur-btn2-height:47px;
  --nur-btn2-font-size:14px;
  --nur-btn2-radius:999px;
  --nur-btn2-scale:1;

  --nur-btn3-x:50%;
  --nur-btn3-y:82%;
  --nur-btn3-width:88px;
  --nur-btn3-height:47px;
  --nur-btn3-font-size:14px;
  --nur-btn3-radius:999px;
  --nur-btn3-scale:1;
}

*{box-sizing:border-box}

html{-webkit-tap-highlight-color:transparent}

/* The document's own scrollbar - thin and muted instead of the browser's
   bright default gray/white bar, since it sits directly against this dark
   night-sky theme. Purely cosmetic (color/width of the scrollbar chrome),
   so it doesn't change what scrolls or when - the letter pages' genuine
   need to scroll (their content is taller than one screen) is untouched,
   and this is independent of dir="rtl" on <html> (which side the bar sits
   on is a layout-direction effect; this only restyles its own colors).
   rgba(167,176,201,...) is --muted's RGB value at low opacity. */
html{
  scrollbar-width:thin;
  scrollbar-color:rgba(167,176,201,.35) transparent;
}
html::-webkit-scrollbar{width:6px}
html::-webkit-scrollbar-track{background:transparent}
html::-webkit-scrollbar-thumb{
  background-color:rgba(167,176,201,.35);
  border-radius:999px;
}
html::-webkit-scrollbar-thumb:hover{background-color:rgba(167,176,201,.55)}

body{
  margin:0;
  min-height:100vh;
  color:var(--text);
  font-family:var(--font-display);
  font-weight:400;
  background:
    radial-gradient(ellipse 70% 50% at 50% -6%, rgba(120,150,220,.10), transparent 62%),
    linear-gradient(180deg,var(--bg-1),var(--bg-2) 55%,var(--bg-1));
  overflow-x:hidden;
}

/* Hidden admin-panel toggle dot (admin-panel.js). Styled here, in the
   always-loaded stylesheet, rather than in the panel's own lazily-built
   markup - the button itself is created and appended to <body> right away
   on page load, but the panel markup (and its styles) used to only get
   built the first time it's opened. Until then this button rendered with
   default button layout (static position, in normal flow), adding stray
   height to the document on every page load - which is what was showing
   up as a persistent scrollbar and a sliver of the Wix page's own
   background at the bottom of the embed, on every screen, from the start. */
#nurAdminToggle{
  position:fixed; bottom:10px; left:10px; width:14px; height:14px; border-radius:50%;
  background:rgba(255,255,255,.06); border:0; cursor:pointer; z-index:99998;
  opacity:0; transition:opacity .2s ease;
}
#nurAdminToggle:hover, #nurAdminToggle:focus-visible{opacity:1}

/* a very slow, almost imperceptible drift behind everything, so the sky
   reads as a soft painted scene rather than a flat, static gradient.
   inset:0 (not a negative inset) deliberately - a fixed-position box sized
   past the viewport still enlarges the *document's* scrollable area even
   though nothing is visually cut off (nothing renders past the window
   edges either way), which was the real source of the stray scrollbar and
   the sliver of the Wix page's own background showing at the bottom of the
   embed on screens that otherwise fit in one viewport. The blur below
   already softens this box's own edges, so the visual difference from the
   old -10% bleed is imperceptible. */
body::before{
  content:"";
  position:fixed;
  inset:0;
  z-index:0;
  pointer-events:none;
  background:radial-gradient(ellipse 45% 35% at 30% 20%, rgba(143,193,154,.06), transparent 60%),
             radial-gradient(ellipse 40% 30% at 75% 70%, rgba(120,150,220,.07), transparent 60%);
  filter:blur(40px);
  animation:skyDrift 70s ease-in-out infinite alternate;
}
@keyframes skyDrift{
  0%{transform:translate(0,0) scale(1)}
  100%{transform:translate(-2%,2%) scale(1.04)}
}
@media (prefers-reduced-motion: reduce){
  body::before{animation:none}
}

/* ==========================================================================
   Night sky — a few soft, scattered, gently twinkling stars. Never a busy
   field: generated once at load, low density, staggered timing, lots of
   empty space between them.
   ========================================================================== */
.stars{
  position:fixed;
  inset:0;
  z-index:0;
  pointer-events:none;
  overflow:hidden;
}
.star{
  position:absolute;
  border-radius:50%;
  background:var(--star);
  box-shadow:0 0 5px 1px rgba(253,246,227,.45);
  animation:twinkle var(--dur,6s) ease-in-out infinite;
  animation-delay:var(--delay,0s);
  opacity:.3;
}
@keyframes twinkle{
  0%,100%{opacity:.15;transform:scale(.8)}
  50%{opacity:.75;transform:scale(1.1)}
}
@media (prefers-reduced-motion: reduce){
  .star{animation:none;opacity:.4}
}

/* A Latin handle inside RTL Persian copy must never reflow or pick up the
   Persian glyph shapes for its Latin letters — isolate direction and force
   the fallback (non-Persian) face explicitly. */
.handle{
  unicode-bidi:isolate;
  direction:ltr;
}
/* Extra breathing room where a Latin name sits right next to a Persian
   word in a greeting sentence (e.g. "درود  ArioPlay") - without this
   the two scripts visually crowd each other once the "@" that used to
   separate them is removed. */
.greeting .handle{
  margin-inline:0.3em;
}

.wrap{
  position:relative;
  z-index:1;
  width:min(1100px,92vw);
  margin:0 auto;
  min-height:100vh;
}

/* ==========================================================================
   Stage / scene switching — one persistent shell, one scene visible at a
   time. Transitions are slow, soft, and slightly blurry rather than a hard
   cut: the outgoing scene fades and blurs away (pulled out of flow so it
   can't jump the page height) while the incoming one fades and sharpens in.
   ========================================================================== */
.stage{
  display:none;
}
.stage.active{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  min-height:100vh;
  padding:60px 0;
  animation:sceneIn 1.1s var(--ease-soft) both;
}
.stage.leaving{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  /* fixed, not absolute: `.stage.active` sizes itself with
     min-height:100vh (viewport-relative). `position:absolute;inset:0`
     instead sizes against `.wrap`'s own height, which can grow the
     instant the incoming stage activates - the outgoing stage would
     then re-center inside a taller box than the one it was centered in
     a moment ago, visibly jumping. `position:fixed` stays
     viewport-relative like `.active` was, so the box never changes
     size mid-exit. */
  position:fixed;
  inset:0;
  pointer-events:none;
  animation:sceneOut .85s ease forwards;
}

@keyframes sceneIn{
  from{opacity:0;filter:blur(18px)}
  to{opacity:1;filter:blur(0)}
}
@keyframes sceneOut{
  from{opacity:1;filter:blur(0)}
  to{opacity:0;filter:blur(18px)}
}
@media (prefers-reduced-motion: reduce){
  .stage.active{animation:none}
  .stage.leaving{animation:none;opacity:0}
}

/* ==========================================================================
   Full-screen text scenes (intro / leaving / before-open)
   ========================================================================== */
.scene-text{
  max-width:560px;
  width:92vw;
  text-align:center;
  margin:0 auto 26px;
}
.scene-text p{
  font-size:clamp(18px,2.4vw,24px);
  line-height:1.7;
  margin:0 0 10px;
  color:var(--text);
}
.scene-text p:last-child{margin-bottom:0}
.scene-text p.greeting{
  font-size:clamp(30px,4.4vw,42px);
  font-weight:700;
  margin-bottom:22px;
}
.scene-text.small{margin-bottom:10px}
.scene-text.small p{
  font-size:clamp(18px,2.2vw,22px);
  line-height:1.65;
  margin-bottom:9px;
}
.scene-text.small p.greeting{
  font-size:clamp(26px,3.8vw,34px);
  font-weight:700;
  margin-bottom:9px;
}

/* ---- Admin-panel position/text hooks -------------------------------- */
/* Intro: the body copy is rendered as one paragraph per manual line
   break in config.intro.body - every line break the admin typed becomes
   a real paragraph boundary, so the "gap" control always has something
   real to space out. */
#stage-intro .scene-text{
  transform:translate(var(--nur-intro-x),var(--nur-intro-y));
}
#stage-intro .scene-text p.greeting{
  font-size:var(--nur-intro-greeting-font-size);
  margin-bottom:var(--nur-intro-greeting-gap);
  word-spacing:var(--nur-intro-word-spacing);
}
#stage-intro .scene-body p{
  white-space:pre-wrap;
  font-size:var(--nur-intro-font-size);
  line-height:var(--nur-intro-line-height);
  margin:0 0 var(--nur-intro-gap);
  color:var(--text);
  word-spacing:var(--nur-intro-word-spacing);
}
#stage-intro .scene-body p:last-child{margin-bottom:0}

/* Envelope (before-open): greeting + instruction, plus the gap to the
   envelope image below them. */
#stage-before-open .scene-text.small{
  margin-bottom:var(--nur-envelope-gap-to-envelope);
  transform:translateY(var(--nur-envelope-y));
}
#stage-before-open .scene-text.small p.greeting{
  margin-bottom:var(--nur-envelope-line-gap);
  word-spacing:var(--nur-envelope-word-spacing);
}
#stage-before-open .scene-text.small p:not(.greeting){
  white-space:pre-line;
  font-size:var(--nur-envelope-font-size);
  word-spacing:var(--nur-envelope-word-spacing);
}

.scene-actions{
  display:flex;
  justify-content:center;
  gap:14px;
  flex-wrap:wrap;
}

.btn{
  border:0;
  border-radius:999px;
  padding:15px 34px;
  cursor:pointer;
  font-family:var(--font-display);
  font-size:18px;
  font-weight:600;
  text-shadow:0 1px 1px rgba(0,0,0,.18);
  text-decoration:none;
  display:inline-block;
  transition:transform .15s ease, box-shadow .25s ease, background-color .25s ease;
}
.btn:active{transform:scale(.97)}
.btn-primary{
  background:var(--accent);
  color:var(--accent-ink);
  box-shadow:0 0 22px rgba(143,193,154,.35);
}
.btn-primary:hover{
  background:var(--accent-bright);
  box-shadow:0 0 28px rgba(174,224,180,.55);
}
.btn-ghost{
  background:transparent;
  color:var(--muted);
  border:1px solid rgba(169,176,200,.35);
}
.btn-ghost:hover{color:var(--text);border-color:rgba(169,176,200,.6)}

/* ==========================================================================
   Envelope
   ========================================================================== */
.floating-scene{
  position:relative;
  width:min(500px,82vw);
  margin:0 auto;
  cursor:pointer;
  outline:none;
}
.floating-scene:focus-visible{
  outline:2px solid rgba(143,193,154,.9);
  outline-offset:12px;
  border-radius:18px;
}
.envelope-img{
  display:block;
  width:100%;
  height:auto;
  filter:drop-shadow(0 30px 55px rgba(0,0,0,.55));
  user-select:none;
  -webkit-user-drag:none;
  animation:envelopeNudge 3.4s ease-in-out infinite;
}
.floating-scene:hover .envelope-img{
  animation-play-state:paused;
  transform:translateY(-3px);
}
@keyframes envelopeNudge{
  0%,72%,100%{transform:translateY(0) rotate(0)}
  77%{transform:translateY(-2px) rotate(-.65deg)}
  82%{transform:translateY(0) rotate(.55deg)}
  87%{transform:translateY(-1px) rotate(-.25deg)}
  92%{transform:translateY(0) rotate(0)}
}
@media (prefers-reduced-motion: reduce){
  .envelope-img{animation:none}
}

/* ==========================================================================
   The letter — a physical card that turns to reveal its other side.
   ========================================================================== */
/* the letter is often taller than the viewport by design (a real long
   letter, not a scrollbox) - align it to the top of its stage so opening
   the envelope reveals the salutation first, not the middle of the page */
#stage-letter.active{
  justify-content:flex-start;
  padding-top:56px;
}

.letter-stage-inner{
  /* --nur-card-scale drives every px-based size overlaid on the letter
     card (name overlay, letter-body text) so they scale down WITH the
     card on narrow screens instead of staying fixed while the card
     shrinks - keep this in sync with any change here, they must match. */
  width:var(--nur-card-scale);
  margin:0 auto 32px;
  filter:drop-shadow(0 22px 50px rgba(0,0,0,.45));
}
/* the letter "turning" is a soft blur/fade crossfade between the two
   faces (the same transition language used for every other scene in the
   app) rather than a literal CSS 3D flip - reliable everywhere. Both
   faces share one grid cell so the container sizes to the taller one
   and no position-juggling is needed for two very differently-sized
   faces (a full letter vs a short note). */
.letter-flipper{
  position:relative;
  width:100%;
  display:grid;
  align-items:start;
}
.letter-face{
  position:relative;
  grid-area:1/1;
  width:100%;
  opacity:0;
  filter:blur(14px);
  pointer-events:none;
  transition:opacity .8s ease, filter .8s ease;
}
.letter-flipper[data-active="1"] .letter-face.page1,
.letter-flipper[data-active="2"] .letter-face.page2,
.letter-flipper[data-active="3"] .letter-face.page3{
  opacity:1;
  filter:blur(0);
  pointer-events:auto;
}
@media (prefers-reduced-motion: reduce){
  .letter-face{transition:none}
}

.note-img{
  display:block;
  width:100%;
  height:auto;
  border-radius:6px;
}

.note-field{
  position:absolute;
  z-index:3;
  color:var(--ink);
  /* a hairline lift off the paper grain — never a box, just enough for
     legibility over the photo's own texture */
  text-shadow:0 1px 1px rgba(255,252,242,.7);
}

/* The streamer name, drawn dynamically where the Photoshop salutation
   used to be baked into note-page1.png before that area was left
   blank. Font/weight/color match the original Photoshop text as
   closely as possible (Digi Derakhshandeh, Bold, ~38.3pt, dark ink);
   size is expressed relatively so it scales with the image exactly
   like the rest of the note-field overlays. */
.field-name-overlay{
  right:var(--nur-letter-name-x);
  top:var(--nur-letter-name-y);
  font-family:"DigiDerakhshandeh",Tahoma,Arial,sans-serif;
  font-weight:700;
  /* scaled by --nur-card-scale - see the comment on that var - so the
     name stays proportional to the card instead of a fixed size that
     looks huge once the card shrinks on a narrow screen. */
  font-size:calc(var(--nur-letter-name-font-size) * var(--nur-card-scale) / var(--nur-card-reference-width));
  word-spacing:calc(var(--nur-letter-name-word-spacing) * var(--nur-card-scale) / var(--nur-card-reference-width));
  color:#241f16;
  white-space:nowrap;
  transform:rotate(var(--nur-letter-name-rotation));
  transform-origin:right top;
}
/* the gap between the name and "عزیز" - physical (not logical) margin,
   since .handle forces direction:ltr for the Latin name regardless of
   the surrounding RTL flow, and we always want space on its visual left
   (toward "عزیز", which follows it in the markup). */
.field-name-overlay .handle{
  margin-left:calc(var(--nur-letter-name-gap) * var(--nur-card-scale) / var(--nur-card-reference-width));
}

/* The letter body text - real HTML now, replacing what used to be baked
   into the PNG. Unlike .field-name-overlay (a single nowrap label), this
   wraps normally within its own width, one <p> per manual line break
   (same renderParagraphs() used for the intro text). Each page gets its
   own position/size since the blank artwork's writable area/decorations
   differ slightly per page. */
.letter-body p{
  color:#241f16;
  /* preserves runs of multiple spaces exactly as typed (unlike pre-line,
     which still collapses them) - line breaks are already one <p> per
     line via renderParagraphs(), this is purely for mid-line spacing. */
  white-space:pre-wrap;
}
/* font-size/word-spacing/margin-bottom are all scaled by --nur-card-scale
   (same reasoning as .field-name-overlay above) - without this, a fixed
   px font-size stays full-size while the card shrinks on a narrow
   screen, wrapping into far more lines than fit and overflowing past
   the bottom of the card. line-height is already unitless (a multiplier
   of font-size) so it scales automatically and needs no calc(). */
.page1 .letter-body{
  right:var(--nur-letter1-x);
  top:var(--nur-letter1-y);
  width:var(--nur-letter1-width);
}
.page1 .letter-body p{
  font-size:calc(var(--nur-letter1-font-size) * var(--nur-card-scale) / var(--nur-card-reference-width));
  line-height:var(--nur-letter1-line-height);
  word-spacing:calc(var(--nur-letter1-word-spacing) * var(--nur-card-scale) / var(--nur-card-reference-width));
  margin:0 0 calc(var(--nur-letter1-gap) * var(--nur-card-scale) / var(--nur-card-reference-width));
}
.page2 .letter-body{
  right:var(--nur-letter2-x);
  top:var(--nur-letter2-y);
  width:var(--nur-letter2-width);
}
.page2 .letter-body p{
  font-size:calc(var(--nur-letter2-font-size) * var(--nur-card-scale) / var(--nur-card-reference-width));
  line-height:var(--nur-letter2-line-height);
  word-spacing:calc(var(--nur-letter2-word-spacing) * var(--nur-card-scale) / var(--nur-card-reference-width));
  margin:0 0 calc(var(--nur-letter2-gap) * var(--nur-card-scale) / var(--nur-card-reference-width));
}
.page3 .letter-body{
  right:var(--nur-letter3-x);
  top:var(--nur-letter3-y);
  width:var(--nur-letter3-width);
}
.page3 .letter-body p{
  font-size:calc(var(--nur-letter3-font-size) * var(--nur-card-scale) / var(--nur-card-reference-width));
  line-height:var(--nur-letter3-line-height);
  word-spacing:calc(var(--nur-letter3-word-spacing) * var(--nur-card-scale) / var(--nur-card-reference-width));
  margin:0 0 calc(var(--nur-letter3-gap) * var(--nur-card-scale) / var(--nur-card-reference-width));
}

/* small in-paper control, sitting right under a page's text rather than
   as a full-size pill below the whole card. x/y/width/height/font-size/
   border-radius all come from that page's config.letterPageN.button
   (set as --nur-btnN-* below) so position/size/label are fully editable
   from the admin panel, including drag-to-position; x/y are the
   button's CENTER (hence translate(-50%,-50%)) so resizing or dragging
   never shifts its anchor point. Everything px-sized is scaled by
   --nur-card-scale, same as the letter text, so the button stays
   proportional to the card instead of the old fixed-px mobile override
   this replaces. Colors/hover/shadow are untouched - only placement and
   size are configurable. */
.note-next-btn{
  position:absolute;
  z-index:4;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  border:0;
  padding:0;
  font-family:var(--font-display);
  font-weight:700;
  text-shadow:0 1px 1px rgba(0,0,0,.18);
  color:var(--accent-ink);
  background:var(--accent);
  box-shadow:0 0 14px rgba(143,193,154,.35);
  cursor:pointer;
  transition:transform .15s ease, box-shadow .25s ease, background-color .25s ease;
}
.note-next-btn:hover{
  background:var(--accent-bright);
  box-shadow:0 0 18px rgba(174,224,180,.5);
}

.letter-face.page1 .note-next-btn{
  left:var(--nur-btn1-x);
  top:var(--nur-btn1-y);
  width:calc(var(--nur-btn1-width) * var(--nur-card-scale) / var(--nur-card-reference-width));
  height:calc(var(--nur-btn1-height) * var(--nur-card-scale) / var(--nur-card-reference-width));
  font-size:calc(var(--nur-btn1-font-size) * var(--nur-card-scale) / var(--nur-card-reference-width));
  border-radius:calc(var(--nur-btn1-radius) * var(--nur-card-scale) / var(--nur-card-reference-width));
  transform:translate(-50%,-50%) scale(var(--nur-btn1-scale));
}
.letter-face.page1 .note-next-btn:active{transform:translate(-50%,-50%) scale(calc(var(--nur-btn1-scale) * .96))}

.letter-face.page2 .note-next-btn{
  left:var(--nur-btn2-x);
  top:var(--nur-btn2-y);
  width:calc(var(--nur-btn2-width) * var(--nur-card-scale) / var(--nur-card-reference-width));
  height:calc(var(--nur-btn2-height) * var(--nur-card-scale) / var(--nur-card-reference-width));
  font-size:calc(var(--nur-btn2-font-size) * var(--nur-card-scale) / var(--nur-card-reference-width));
  border-radius:calc(var(--nur-btn2-radius) * var(--nur-card-scale) / var(--nur-card-reference-width));
  transform:translate(-50%,-50%) scale(var(--nur-btn2-scale));
}
.letter-face.page2 .note-next-btn:active{transform:translate(-50%,-50%) scale(calc(var(--nur-btn2-scale) * .96))}

.letter-face.page3 .note-next-btn{
  left:var(--nur-btn3-x);
  top:var(--nur-btn3-y);
  width:calc(var(--nur-btn3-width) * var(--nur-card-scale) / var(--nur-card-reference-width));
  height:calc(var(--nur-btn3-height) * var(--nur-card-scale) / var(--nur-card-reference-width));
  font-size:calc(var(--nur-btn3-font-size) * var(--nur-card-scale) / var(--nur-card-reference-width));
  border-radius:calc(var(--nur-btn3-radius) * var(--nur-card-scale) / var(--nur-card-reference-width));
  transform:translate(-50%,-50%) scale(var(--nur-btn3-scale));
}
.letter-face.page3 .note-next-btn:active{transform:translate(-50%,-50%) scale(calc(var(--nur-btn3-scale) * .96))}

/* ==========================================================================
   Countdown — the light being sent. Kept deliberately bare: a number, a
   quiet line beneath it, one soft green glow. Nothing else.
   ========================================================================== */
#stage-countdown{
  position:relative;
}
/* BUGFIX: an ID selector always outranks a class selector, so the base
   `#stage-countdown{position:relative}` above was silently overriding
   `.stage.leaving{position:fixed}` (see .stage.leaving) - the countdown
   stage never actually left normal document flow while exiting, so it
   collided with the incoming final stage and the number visibly jumped.
   This re-asserts fixed positioning with a selector specific enough to
   win. */
#stage-countdown.leaving{
  position:fixed;
}
.countdown-glow{
  position:absolute;
  width:min(280px,60vw);
  aspect-ratio:1;
  border-radius:50%;
  background:radial-gradient(circle, rgba(143,193,154,.32), transparent 72%);
  filter:blur(18px);
  animation:glowPulse 4.5s ease-in-out infinite;
  z-index:0;
}
@keyframes glowPulse{
  0%,100%{opacity:.55;transform:scale(.94)}
  50%{opacity:.9;transform:scale(1.06)}
}
.countdown-number{
  position:relative;
  z-index:1;
  font-family:var(--font-body); /* clean, unambiguous digits over ornament */
  font-size:clamp(56px,12vw,104px);
  font-weight:600;
  color:var(--text);
  line-height:1;
}
.countdown-label{
  position:relative;
  z-index:1;
  margin-top:16px;
  font-size:clamp(16px,2vw,19px);
  font-weight:400;
  color:var(--muted);
}
@media (prefers-reduced-motion: reduce){
  .countdown-glow{animation:none;opacity:.7}
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width:760px){
  .stage.active{padding:40px 0}
  .scene-text p{font-size:18px;line-height:1.75;margin-bottom:12px}
  .scene-text.small p{font-size:16px;margin-bottom:8px}

  /* The letter card scales as a whole picture at every width, and the
     name overlay/letter-body text/nav buttons already scale with it via
     --nur-card-scale (see :root and the .letter-body/.field-name-overlay/
     .note-next-btn rules) - nothing extra needed here for them. */

  #stage-letter.active{padding-top:36px}
}
