/* ==========================================================================
   A birthday letter book — black, oxblood, aged paper.
   Sections:  0 tokens · 1 reset · 2 ambient · 3 ornaments · 4 gate
              5 hero · 6 prologue · 7 notes · 8 paper · 9 photos
              10 bands · 11 closing · 12 motion · 13 responsive
   ========================================================================== */

/* ---------- 0. tokens ---------------------------------------------------- */
:root {
  /* ink & void */
  --void:         #080607;
  --void-2:       #050304;
  --raised:       #120c0e;

  /* light on dark */
  --ink:          #efe4dd;
  --ink-soft:     rgba(239, 228, 221, .62);
  --ink-faint:    rgba(239, 228, 221, .34);
  --ink-ghost:    rgba(239, 228, 221, .13);

  /* the red */
  --red-deep:     #5e0d18;
  --red:          #8e1526;
  --red-bright:   #b4212f;
  --red-wash:     rgba(142, 21, 38, .30);
  --red-mist:     rgba(142, 21, 38, .12);

  /* brass hairlines */
  --gold:         #c6a86c;
  --gold-soft:    rgba(198, 168, 108, .40);
  --gold-faint:   rgba(198, 168, 108, .17);

  /* paper */
  --paper:        #e9dcb2;
  --paper-warm:   #e3d3a2;
  --paper-shade:  #d3c08c;
  --paper-edge:   #b9a473;
  --paper-ink:    #33291d;
  --paper-ink-2:  #574733;
  --paper-ink-3:  rgba(51, 41, 29, .48);
  --paper-rule:   rgba(120, 96, 60, .18);

  /* type */
  --serif:  "Cormorant Garamond", "EB Garamond", Georgia, "Times New Roman", serif;
  --roman:  "Cinzel", "Cormorant Garamond", Georgia, serif;
  --hand:   "Caveat", "Segoe Script", "Bradley Hand", cursive;

  /* rhythm */
  --gutter: clamp(1.25rem, 5vw, 3rem);
  --measure: 40rem;
  --section-y: clamp(5rem, 13vh, 10rem);

  /* motion */
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-soft: cubic-bezier(.4, 0, .2, 1);
  --dur: .7s;
}

/* ---------- 1. reset ----------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scrollbar-color: var(--red-deep) var(--void-2);
}

body {
  margin: 0;
  min-height: 100svh;
  background: var(--void);
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(1.0625rem, .55vw + .93rem, 1.1875rem);
  line-height: 1.75;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  text-rendering: optimizeLegibility;
}

body.is-locked { overflow: hidden; height: 100svh; }

/* the viewer locks the page without losing her place on it */
html.is-viewing { overflow: hidden; }

img { max-width: 100%; display: block; }
h1, h2, h3, p, figure, blockquote { margin: 0; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
input { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--red); color: #fff; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

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

/* ---------- 2. ambient layers -------------------------------------------- */
.grain {
  position: fixed; inset: -120px;
  z-index: 200;
  pointer-events: none;
  opacity: .05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='260' height='260' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grainShift 6s steps(6) infinite;
  will-change: transform;
}

@keyframes grainShift {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-24px, 12px); }
  40%  { transform: translate(18px, -20px); }
  60%  { transform: translate(-14px, -14px); }
  80%  { transform: translate(22px, 16px); }
  100% { transform: translate(0, 0); }
}

.vignette {
  position: fixed; inset: 0;
  z-index: 190;
  pointer-events: none;
  /* Kept light at the top: a section heading scrolled to the top of the
     viewport was being dimmed into the background by the old .55 falloff. */
  background:
    radial-gradient(130% 100% at 50% 0%,   transparent 58%, rgba(0,0,0,.34) 100%),
    radial-gradient(120% 90%  at 50% 100%, transparent 52%, rgba(0,0,0,.48) 100%);
}

.pointer-glow {
  position: fixed;
  top: 0; left: 0;
  width: 44rem; height: 44rem;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(-50%, -50%, 0);
  background: radial-gradient(circle, var(--red-mist) 0%, transparent 62%);
  transition: opacity 1.2s var(--ease-soft);
}

body.has-pointer .pointer-glow { opacity: 1; }

/* ---------- 3. ornaments ------------------------------------------------- */
.ornament {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  width: min(20rem, 68%);
  margin: 1.75rem auto;
  color: var(--gold-soft);
}

.ornament--sm { width: min(13rem, 52%); margin: 1.5rem auto; gap: .75rem; }

.ornament__rule {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-faint) 22%, var(--gold-soft) 50%, var(--gold-faint) 78%, transparent);
}

.ornament__mark {
  font-size: .8rem;
  line-height: 1;
  color: var(--red-bright);
  opacity: .85;
  transform: translateY(-1px);
}

/* ---------- 4. the gate -------------------------------------------------- */
.gate {
  position: fixed; inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  padding: var(--gutter);
  background:
    radial-gradient(80% 60% at 50% 46%, rgba(142,21,38,.13) 0%, transparent 70%),
    var(--void-2);
  transition: opacity 1s var(--ease-soft), transform 1.1s var(--ease-out), visibility 0s linear 1.1s;
}

.gate.is-open {
  opacity: 0;
  visibility: hidden;
  transform: scale(1.06);
  pointer-events: none;
}

.gate__inner {
  width: min(34rem, 100%);
  text-align: center;
  animation: riseIn 1.1s var(--ease-out) both .15s;
}

.gate__eyebrow {
  font-family: var(--roman);
  font-size: .72rem;
  letter-spacing: .42em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: .25rem;
  padding-left: .42em;
}

.gate__question {
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(1.5rem, 3.4vw, 2.1rem);
  line-height: 1.35;
  color: var(--ink);
  margin: 0 0 2.25rem;
  text-wrap: balance;
}

.gate__form {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.75rem;
}

.gate__input {
  width: min(24rem, 100%);
  padding: .55rem .25rem;
  text-align: center;
  font-family: var(--hand);
  font-size: 1.6rem;
  line-height: 1.4;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ink-ghost);
  transition: border-color .45s var(--ease-soft);
  caret-color: var(--red-bright);
}

.gate__input::placeholder { color: var(--ink-ghost); font-size: 1.25rem; }
.gate__input:focus { outline: none; border-bottom-color: var(--red-bright); }

.gate.is-wrong .gate__input {
  border-bottom-color: var(--red-bright);
  animation: shake .5s var(--ease-soft);
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  15% { transform: translateX(-9px); }
  35% { transform: translateX(8px); }
  55% { transform: translateX(-5px); }
  75% { transform: translateX(4px); }
}

.gate__submit {
  position: relative;
  font-family: var(--roman);
  font-size: .72rem;
  letter-spacing: .34em;
  text-transform: uppercase;
  padding: .85rem 2.4rem .85rem 2.74rem;
  color: var(--ink);
  border: 1px solid var(--gold-faint);
  background: linear-gradient(180deg, rgba(142,21,38,.14), rgba(142,21,38,.04));
  transition: border-color .4s, background .4s, color .4s, transform .4s var(--ease-out);
}

.gate__submit:hover,
.gate__submit:focus-visible {
  border-color: var(--gold-soft);
  background: linear-gradient(180deg, rgba(142,21,38,.34), rgba(142,21,38,.14));
  transform: translateY(-2px);
}

.gate__feedback {
  min-height: 1.6em;
  margin-top: 1.5rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: .95rem;
  color: var(--ink-faint);
  transition: color .4s;
}

.gate__feedback.is-error { color: var(--red-bright); }

/* ---------- 5. hero ------------------------------------------------------ */
.site {
  position: relative;
  z-index: 1;
  opacity: 0;
  transition: opacity 1.2s var(--ease-soft);
}

.site.is-revealed { opacity: 1; }

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  grid-template-rows: 1fr auto;
  place-items: center;
  padding: clamp(4rem, 12vh, 8rem) var(--gutter) clamp(2.5rem, 6vh, 4rem);
  overflow: hidden;
  isolation: isolate;
}

.hero__glow {
  position: absolute;
  left: 50%; bottom: -34%;
  width: min(120rem, 175vw);
  aspect-ratio: 1;
  transform: translateX(-50%);
  z-index: -1;
  background: radial-gradient(circle, rgba(142,21,38,.30) 0%, rgba(94,13,24,.11) 34%, transparent 66%);
  animation: breathe 11s ease-in-out infinite;
}

@keyframes breathe {
  0%, 100% { opacity: .75; transform: translateX(-50%) scale(1); }
  50%      { opacity: 1;   transform: translateX(-50%) scale(1.07); }
}

.hero__inner {
  text-align: center;
  max-width: 46rem;
  align-self: center;
}

.hero__eyebrow {
  font-family: var(--roman);
  font-size: clamp(.66rem, 1.1vw, .78rem);
  letter-spacing: .5em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding-left: .5em;
}

.hero__greeting {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.35rem, 3.2vw, 2rem);
  color: var(--ink-soft);
  letter-spacing: .01em;
}

.hero__name {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(3rem, 12vw, 8.5rem);
  line-height: .96;
  letter-spacing: .04em;
  margin: .15em 0 .35em;
  color: #f6ece3;
  text-wrap: balance;
  text-shadow:
    0 0 60px rgba(142, 21, 38, .38),
    0 1px 0 rgba(0, 0, 0, .5);
  padding-bottom: .06em;
}

.hero__subtitle {
  font-family: var(--roman);
  font-size: clamp(.64rem, 1.15vw, .76rem);
  letter-spacing: .38em;
  text-transform: uppercase;
  color: var(--red-bright);
  opacity: .8;
  padding-left: .38em;
}

.hero__scroll {
  display: grid;
  justify-items: center;
  gap: .9rem;
  color: var(--ink-faint);
  transition: color .5s;
}

.hero__scroll:hover { color: var(--ink-soft); }

.hero__scrollLine {
  width: 1px;
  height: 3.5rem;
  background: linear-gradient(180deg, transparent, var(--gold-soft));
  transform-origin: top;
  animation: scrollPulse 2.6s var(--ease-soft) infinite;
}

@keyframes scrollPulse {
  0%, 100% { transform: scaleY(.42); opacity: .35; }
  50%      { transform: scaleY(1);   opacity: 1; }
}

.hero__scrollWord {
  font-family: var(--roman);
  font-size: .6rem;
  letter-spacing: .38em;
  text-transform: uppercase;
  padding-left: .38em;
}

/* staggered entrance once the gate opens */
.site.is-revealed .hero__eyebrow  { animation: riseIn 1.1s var(--ease-out) both .10s; }
.site.is-revealed .hero .ornament { animation: riseIn 1.1s var(--ease-out) both .24s; }
.site.is-revealed .hero__greeting { animation: riseIn 1.1s var(--ease-out) both .38s; }
.site.is-revealed .hero__name     { animation: riseIn 1.3s var(--ease-out) both .50s; }
.site.is-revealed .hero__subtitle { animation: riseIn 1.1s var(--ease-out) both .78s; }
.site.is-revealed .hero__scroll   { animation: riseIn 1.1s var(--ease-out) both 1.05s; }

@keyframes riseIn {
  from { opacity: 0; transform: translateY(26px); filter: blur(6px); }
  to   { opacity: 1; transform: none;             filter: blur(0); }
}

/* ---------- 6. prologue -------------------------------------------------- */
.prologue {
  position: relative;
  padding: var(--section-y) var(--gutter) calc(var(--section-y) * .7);
  display: grid;
  place-items: center;
  align-content: center;
}

.prologue__text {
  max-width: 34rem;
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.2rem, 2.2vw, 1.5rem);
  line-height: 1.85;
  color: var(--ink-soft);
  text-wrap: pretty;
}

/* ---------- 7. notes ----------------------------------------------------- */
.notes {
  position: relative;
  padding: calc(var(--section-y) * .9) var(--gutter) var(--section-y);
}

.notes__head {
  max-width: var(--measure);
  margin: 0 auto clamp(2.5rem, 6vw, 4rem);
}

.notes__headRow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.notes__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.1rem, 5.6vw, 3.4rem);
  line-height: 1;
  letter-spacing: .01em;
}

.notes__count {
  font-family: var(--roman);
  font-size: .68rem;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--red-bright);
  opacity: .8;
  white-space: nowrap;
}

.notes__subtitle {
  margin-top: .5rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.02rem;
  color: var(--ink-faint);
}

.notes__rule {
  display: block;
  height: 1px;
  margin-top: 1.5rem;
  background: linear-gradient(90deg, var(--gold-soft), var(--red-wash) 40%, transparent 92%);
}

.notes__stage { position: relative; }

/* Held to the readable measure. It must NOT run full width: an invisible
   full-width box here sits over the margin photographs and swallows their
   clicks. */
.notes__list {
  position: relative;
  z-index: 2;
  max-width: var(--measure);
  margin-inline: auto;
  display: grid;
  gap: clamp(2rem, 4.5vw, 3.25rem);
}

.polaroid { will-change: transform; }

/* ---------- 8. the paper ------------------------------------------------- */
.note {
  position: relative;
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  transform: rotate(var(--tilt, 0deg));
  transition: transform .8s var(--ease-out);
}

/* the two sheets stacked behind each letter */
.note::before,
.note::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 3px;
  background: var(--paper-shade);
  box-shadow: 0 12px 34px rgba(0, 0, 0, .55);
  transition: opacity .6s var(--ease-soft), transform .8s var(--ease-out);
}

.note::before { transform: rotate(-1.1deg) translate(-6px, 5px); opacity: .40; }
.note::after  { transform: rotate(1.4deg)  translate(7px, 9px);  opacity: .24; }

.note.is-open { transform: rotate(0deg); }
.note.is-open::before,
.note.is-open::after { opacity: 0; transform: none; }

.note__sheet {
  position: relative;
  z-index: 1;
  border-radius: 3px;
  overflow: hidden;
  color: var(--paper-ink);
  background-color: var(--paper);
  /* Aging is measured in px, not %, so a six-paragraph letter is not darker
     than a one-paragraph one — only its top and bottom edges age. */
  background-image:
    /* foxing stains */
    radial-gradient(22rem 16rem at 8% 0,     rgba(160,120,60,.15) 0%, transparent 70%),
    radial-gradient(18rem 14rem at 96% 9rem, rgba(140,96,48,.13)  0%, transparent 72%),
    radial-gradient(26rem 18rem at 88% 100%, rgba(120,82,40,.14)  0%, transparent 72%),
    radial-gradient(14rem 10rem at 22% 100%, rgba(150,110,54,.10) 0%, transparent 68%),
    /* aged edges */
    linear-gradient(180deg, rgba(255,251,236,.55) 0, rgba(255,251,236,0) 7rem),
    linear-gradient(0deg,   rgba(122,90,42,.20)   0, rgba(122,90,42,0)   9rem);
  background-repeat: no-repeat;
  box-shadow:
    0 1px 0 rgba(255, 250, 235, .55) inset,
    0 -14px 28px -18px rgba(90, 62, 26, .55) inset,
    0 22px 48px rgba(0, 0, 0, .58),
    0 2px 0 rgba(0, 0, 0, .35);
  transition: box-shadow .6s var(--ease-soft), transform .6s var(--ease-out);
}

/* paper fibre */
.note__sheet::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .32;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23p)' opacity='.42'/%3E%3C/svg%3E");
}

/* left margin rule, like a real sheet */
.note__sheet::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: clamp(1.1rem, 4.5vw, 2.2rem);
  width: 1px;
  background: linear-gradient(180deg, transparent, rgba(142,21,38,.30) 12%, rgba(142,21,38,.30) 88%, transparent);
  pointer-events: none;
}

.note:hover .note__sheet { transform: translateY(-3px); }
.note.is-open:hover .note__sheet { transform: none; }

/* --- the tappable head --- */
.note__head {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: clamp(1rem, 3vw, 1.75rem);
  width: 100%;
  text-align: left;
  padding: clamp(1.4rem, 3.6vw, 2rem) clamp(1.35rem, 4vw, 2.25rem)
           clamp(1.4rem, 3.6vw, 2rem) clamp(2.4rem, 7.5vw, 3.6rem);
  min-height: 3rem;
}

.note__headings { display: grid; gap: .35rem; min-width: 0; }

.note__title {
  font-family: var(--hand);
  font-weight: 700;
  font-size: clamp(1.5rem, 3.6vw, 1.95rem);
  line-height: 1.25;
  color: var(--paper-ink);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
}

.note__meta {
  display: flex;
  align-items: baseline;
  gap: .7rem;
  min-width: 0;
  font-family: var(--hand);
  font-size: clamp(1.1rem, 2.4vw, 1.28rem);
  line-height: 1.4;
}

.note__date {
  flex: none;
  color: var(--paper-ink-2);
  font-weight: 600;
  position: relative;
  padding-right: .7rem;
}

.note__date::after {
  content: "";
  position: absolute;
  right: 0; top: 50%;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--red);
  opacity: .55;
  transform: translateY(-50%);
  transition: opacity .35s var(--ease-soft);
}

/* the separator dot has nothing to separate once the preview is gone */
.note.is-open .note__date::after { opacity: 0; }

.note__preview {
  color: var(--paper-ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.note.is-open .note__preview { opacity: 0; }
.note__preview { transition: opacity .35s var(--ease-soft); }

/* wax-seal button on the right */
.note__seal {
  position: relative;
  flex: none;
  width: clamp(2.4rem, 6vw, 2.9rem);
  aspect-ratio: 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background:
    radial-gradient(60% 60% at 34% 28%, #c03040 0%, var(--red) 42%, var(--red-deep) 100%);
  box-shadow:
    0 1px 1px rgba(255,255,255,.28) inset,
    0 -3px 6px rgba(0,0,0,.45) inset,
    0 5px 12px rgba(60, 8, 14, .5);
  transition: transform .6s var(--ease-out), box-shadow .6s var(--ease-soft);
}

.note__seal::before {
  content: "";
  width: 56%; height: 56%;
  border: 1px solid rgba(255, 228, 214, .34);
  border-radius: 50%;
}

.note__chev {
  position: absolute;
  top: 50%; left: 50%;
  width: 8px; height: 8px;
  border-right: 1.5px solid rgba(255, 232, 220, .85);
  border-bottom: 1.5px solid rgba(255, 232, 220, .85);
  transform: translate(-50%, -62%) rotate(45deg);
  transition: transform .6s var(--ease-out);
}

.note__head:hover .note__seal { transform: scale(1.07) rotate(-6deg); }
.note.is-open .note__seal { transform: rotate(-14deg); }
.note.is-open .note__chev { transform: translate(-50%, -38%) rotate(225deg); }

/* --- the expanding panel --- */
.note__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .85s var(--ease-out);
}

.note.is-open .note__panel { grid-template-rows: 1fr; }

.note__panelInner {
  overflow: hidden;
  min-height: 0;
}

.note__panelPad {
  padding: 0 clamp(1.35rem, 4vw, 2.25rem) clamp(1.75rem, 4.5vw, 2.75rem)
             clamp(2.4rem, 7.5vw, 3.6rem);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .5s var(--ease-soft) .12s, transform .7s var(--ease-out) .12s;
}

.note.is-open .note__panelPad { opacity: 1; transform: none; }

.note__divider {
  height: 1px;
  margin-bottom: clamp(1.4rem, 3.5vw, 2rem);
  background: linear-gradient(90deg, rgba(142,21,38,.35), rgba(120,96,60,.22) 45%, transparent 90%);
}

.note__body {
  font-family: var(--hand);
  font-size: clamp(1.25rem, 2.9vw, 1.42rem);
  line-height: 2rem;
  color: var(--paper-ink);
  /* faint ruled lines behind the handwriting */
  background-image: repeating-linear-gradient(
    180deg,
    transparent 0,
    transparent calc(2rem - 1px),
    var(--paper-rule) calc(2rem - 1px),
    var(--paper-rule) 2rem
  );
  background-position: 0 .35rem;
}

.note__body p { margin: 0 0 2rem; text-wrap: pretty; }
.note__body p:last-child { margin-bottom: 0; }

.note__signoff {
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  display: flex;
  align-items: center;
  gap: 1rem;
  font-family: var(--hand);
  font-size: clamp(1.3rem, 3vw, 1.55rem);
  color: var(--paper-ink-2);
}

.note__signoffRule {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(120,96,60,.28), transparent);
}

/* ---------- 9. photographs ----------------------------------------------- */
.polaroid {
  position: relative;
  width: var(--w, 13rem);
  padding: .7rem .7rem 2.6rem;
  background: linear-gradient(170deg, #f4ece0 0%, #e9dfd0 62%, #ddd1bf 100%);
  border-radius: 2px;
  box-shadow:
    0 1px 0 rgba(255,255,255,.7) inset,
    0 18px 38px rgba(0, 0, 0, .62),
    0 3px 8px rgba(0, 0, 0, .4);
  transform: translate3d(0, var(--py, 0px), 0) translateY(var(--anchor, 0px)) rotate(var(--rot, 0deg));
  transition: transform .8s var(--ease-out), box-shadow .8s var(--ease-soft);
}

.polaroid::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  border-radius: 2px;
  opacity: .3;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='q'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23q)' opacity='.4'/%3E%3C/svg%3E");
}

.polaroid__tape {
  position: absolute;
  top: -.85rem; left: 50%;
  width: 4.6rem; height: 1.7rem;
  transform: translateX(-50%) rotate(var(--taperot, -3deg));
  background: linear-gradient(105deg, rgba(238, 226, 196, .5), rgba(214, 198, 158, .32));
  box-shadow: 0 2px 6px rgba(0,0,0,.28);
  opacity: .85;
}

.polaroid__tape::before,
.polaroid__tape::after {
  content: "";
  position: absolute; top: 0; bottom: 0; width: 4px;
  background: repeating-linear-gradient(180deg, rgba(255,255,255,.28) 0 3px, transparent 3px 6px);
}
.polaroid__tape::before { left: 0; }
.polaroid__tape::after  { right: 0; }

/* The photograph sets its own height, so it can never be cropped — tall phone
   shots stay tall, wide ones stay wide. The declared w/h only reserves the
   space beforehand, so nothing on the page jumps as the photos arrive. */
.polaroid__media {
  display: block;
  position: relative;
  width: 100%;
  overflow: hidden;
  background: #171012;
}

.polaroid__media:not(.has-image) { aspect-ratio: var(--ar, 4 / 5); }

.polaroid__media img {
  width: 100%;
  height: auto;
  filter: saturate(.82) contrast(1.04) sepia(.12);
  transition: filter .8s var(--ease-soft), transform 1.2s var(--ease-out);
}

.polaroid:hover {
  transform: translate3d(0, var(--py, 0px), 0) translateY(var(--anchor, 0px))
             translateY(-10px) rotate(0deg) scale(1.035);
  box-shadow: 0 30px 60px rgba(0, 0, 0, .7);
  z-index: 3;
}
.polaroid:hover .polaroid__media img { filter: saturate(1) contrast(1.02) sepia(0); transform: scale(1.05); }

/* a photograph that actually loaded hides its placeholder */
.has-image .frame__empty { display: none; }

.polaroid__caption {
  position: absolute;
  left: 0; right: 0; bottom: .55rem;
  text-align: center;
  font-family: var(--hand);
  font-size: 1.15rem;
  color: #5b4b38;
  opacity: .8;
}

/* empty-slot state, shown when the file is not there yet */
.frame__empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  gap: .5rem;
  padding: 1rem;
  text-align: center;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.022) 0 8px, transparent 8px 16px),
    linear-gradient(160deg, #1b1214 0%, #100a0c 100%);
  color: rgba(239, 228, 221, .44);
  font-family: var(--roman);
  font-size: .58rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  line-height: 1.7;
  box-shadow: 0 0 0 1px rgba(198,168,108,.14) inset;
}

.frame__empty > span {
  display: grid;
  justify-items: center;
  gap: .1rem;
}

.frame__empty b {
  display: block;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.6rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--red-bright);
  opacity: .55;
  margin-bottom: .15rem;
}

.frame__empty i {
  display: block;
  font-family: var(--serif);
  font-style: normal;
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: none;
  color: rgba(239, 228, 221, .34);
  word-break: break-all;
}

/* hero polaroids */
.hero__photos {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.hero__photos .polaroid {
  position: absolute;
  top: var(--top);
  opacity: .9;
  pointer-events: auto;
  will-change: transform;
}

.hero__photos .polaroid[data-side="left"]  { left: var(--x); }
.hero__photos .polaroid[data-side="right"] { right: var(--x); }

/* ---------- 10. wide photo bands ----------------------------------------- */
.band {
  position: relative;
  margin: var(--section-y) 0;
  isolation: isolate;
}

/* The floor is generous: on a short window (or at browser zoom) a 56vh band
   collapses and crops away most of the photograph. */
.band__media {
  position: relative;
  width: 100%;
  height: clamp(24rem, 56vh, 34rem);
  overflow: hidden;
}

/* Less overscan than before — the band has to crop to be a band, and the extra
   room the parallax needed was eating heads off the top of the photograph. */
.frame--band {
  position: absolute;
  inset: -9% 0;
  transform: translate3d(0, var(--py, 0px), 0);
  will-change: transform;
}

.frame--band img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* `pos` in content.js aims the crop window. Lower the second number to keep
     heads in frame, raise it to keep more of the bottom. */
  object-position: var(--pos, 50% 50%);
  filter: saturate(.72) contrast(1.06) brightness(.82) sepia(.14);
}

.frame--band .frame__empty { inset: 9% 0; }

.band__media::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, var(--void) 0%, transparent 26%, transparent 68%, var(--void) 100%),
    linear-gradient(90deg, var(--void) 0%, transparent 18%, transparent 82%, var(--void) 100%),
    radial-gradient(70% 60% at 50% 50%, transparent 30%, rgba(94,13,24,.22) 100%);
  transition: opacity .6s var(--ease-soft);
}

/* no file yet — let the empty slot read as a deliberate space */
.band__media.is-empty::after { opacity: .34; }

.frame--band .frame__empty {
  font-size: .68rem;
  letter-spacing: .3em;
  gap: .75rem;
}

.frame--band .frame__empty b { font-size: 2.4rem; }
.frame--band .frame__empty i { font-size: .8rem; }

.band__caption {
  position: absolute;
  left: 50%; bottom: clamp(1.5rem, 5vw, 3rem);
  transform: translateX(-50%);
  width: min(30rem, 84%);
  text-align: center;
  font-family: var(--hand);
  font-size: clamp(1.3rem, 3.4vw, 1.75rem);
  line-height: 1.5;
  color: var(--ink);
  text-shadow: 0 2px 22px rgba(0,0,0,.9);
  z-index: 2;
}

/* ---------- 11. closing --------------------------------------------------- */
.closing {
  position: relative;
  display: grid;
  gap: clamp(2.5rem, 6vw, 4rem);
  justify-items: center;
  align-content: center;
  padding: var(--section-y) var(--gutter) calc(var(--section-y) * .6);
  text-align: center;
}

.polaroid--closing { --w: clamp(14rem, 40vw, 19rem); --rot: -2.2deg; }

.closing__text { max-width: 34rem; }

.closing__eyebrow {
  font-family: var(--roman);
  font-size: .66rem;
  letter-spacing: .42em;
  text-transform: uppercase;
  color: var(--red-bright);
  opacity: .78;
  padding-left: .42em;
  margin-bottom: .9rem;
}

.closing__heading {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(2rem, 6vw, 3.2rem);
  line-height: 1.12;
  letter-spacing: .01em;
  text-wrap: balance;
  margin-bottom: 1.4rem;
}

.closing__body {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.1rem, 2.2vw, 1.3rem);
  line-height: 1.85;
  color: var(--ink-soft);
  text-wrap: pretty;
}

.closing__signature {
  font-family: var(--hand);
  font-size: clamp(1.6rem, 4vw, 2.1rem);
  color: var(--ink);
  opacity: .9;
}

.footer {
  padding: 0 var(--gutter) clamp(3rem, 8vh, 5rem);
  text-align: center;
  font-family: var(--roman);
  font-size: .58rem;
  letter-spacing: .32em;
  text-transform: uppercase;
  color: var(--ink-ghost);
  padding-left: calc(var(--gutter) + .32em);
}

/* ---------- 11b. photographs down the margins ---------------------------
   Each section carries its own layer of photographs, pinned out in the left
   and right margins. They are out of the flow entirely, so the four letters
   stay in one unbroken stack with nothing between them.
   ------------------------------------------------------------------------ */
.sideScatter {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.sideScatter .polaroid {
  position: absolute;
  top: var(--top);
  --anchor: -50%;                 /* the given top is the photograph's middle */
  --w: clamp(8rem, 10.5vw, 11.5rem);
  pointer-events: auto;
}

.sideScatter .polaroid[data-side="left"]  { left: var(--x, 2%); }
.sideScatter .polaroid[data-side="right"] { right: var(--x, 2%); }

/* Each section's own text sits above its photographs. Only elements that are
   held to a narrow measure may go in this list — a full-width one would cover
   the margins and block the photographs underneath from being clicked. */
.prologue__text,
.notes__head,
.note,
.closing__photo,
.closing__text { position: relative; z-index: 2; }

/* the wrapper is full width, so it must never intercept a click */
.notes__stage { pointer-events: none; }
.notes__stage .note { pointer-events: auto; }

/* the invisible hit area that opens the full-width band */
.band__open {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%; height: 100%;
  background: transparent;
}

.band__open:focus-visible { outline-offset: -6px; }

/* ---------- 11c. full-screen photograph ---------------------------------- */
.viewer {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
}

.viewer[hidden] { display: none; }

.viewer__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(4, 3, 3, .95);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  opacity: 0;
  transition: opacity .45s var(--ease-soft);
}

.viewer.is-open .viewer__backdrop { opacity: 1; }

.viewer__figure {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 1.1rem;
  justify-items: center;
  /* claim horizontal movement for swiping, leave pinch-zoom to the browser */
  touch-action: pan-y pinch-zoom;
  opacity: 0;
  transform: scale(.97);
  transition: opacity .5s var(--ease-soft), transform .6s var(--ease-out);
}

.viewer.is-open .viewer__figure { opacity: 1; transform: none; }

.viewer__stage {
  padding: .55rem;
  border-radius: 2px;
  background: linear-gradient(168deg, #f5ede1 0%, #e6dbc8 60%, #d9cdb9 100%);
  box-shadow: 0 40px 90px rgba(0, 0, 0, .8), 0 2px 8px rgba(0, 0, 0, .5);
  line-height: 0;
}

.viewer__stage img {
  display: block;
  -webkit-user-drag: none;
  user-select: none;
  width: auto; height: auto;
  max-width: min(90vw, 66rem);
  max-height: 72svh;
  background: #171012;
}

.viewer__caption {
  font-family: var(--hand);
  font-size: clamp(1.1rem, 2.6vw, 1.4rem);
  color: var(--ink-soft);
  text-align: center;
}

.viewer__close,
.viewer__nav {
  position: absolute;
  z-index: 3;
  display: grid;
  place-items: center;
  color: var(--ink-faint);
  transition: color .4s var(--ease-soft), transform .4s var(--ease-out);
}

.viewer__close {
  top: clamp(.5rem, 2vw, 1.5rem);
  right: clamp(.5rem, 2vw, 1.5rem);
  width: 2.9rem; aspect-ratio: 1;
}

.viewer__close span { position: relative; width: 17px; height: 17px; }

.viewer__close span::before,
.viewer__close span::after {
  content: "";
  position: absolute;
  top: 50%; left: 0;
  width: 100%; height: 1.5px;
  background: currentColor;
}

.viewer__close span::before { transform: rotate(45deg); }
.viewer__close span::after  { transform: rotate(-45deg); }

.viewer__nav {
  top: 50%;
  width: clamp(2.9rem, 7vw, 4.5rem);
  aspect-ratio: 1;
  transform: translateY(-50%);
  color: var(--gold-soft);
}

.viewer__nav--prev { left: clamp(.15rem, 2vw, 2rem); }
.viewer__nav--next { right: clamp(.15rem, 2vw, 2rem); }

.viewer__nav span {
  width: 14px; height: 14px;
  border-top: 1.5px solid currentColor;
  border-right: 1.5px solid currentColor;
}

.viewer__nav--prev span { transform: rotate(-135deg) translate(-2px, -2px); }
.viewer__nav--next span { transform: rotate(45deg) translate(-2px, -2px); }

.viewer__close:hover, .viewer__close:focus-visible { color: var(--ink); }
.viewer__nav:hover,   .viewer__nav:focus-visible   { color: var(--ink); }

.viewer__counter {
  position: absolute;
  z-index: 3;
  bottom: clamp(.6rem, 2.5vw, 1.75rem);
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--roman);
  font-size: .6rem;
  letter-spacing: .32em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-left: .32em;
}

/* ---------- 12. scroll reveal -------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(34px);
  transition: opacity 1s var(--ease-soft), transform 1.1s var(--ease-out);
}

.reveal.is-visible { opacity: 1; transform: none; }

.reveal[data-delay="1"] { transition-delay: .10s; }
.reveal[data-delay="2"] { transition-delay: .20s; }
.reveal[data-delay="3"] { transition-delay: .30s; }
.reveal[data-delay="4"] { transition-delay: .40s; }

/* ---------- 13. responsive ------------------------------------------------ */

/* laptop and up — photographs lift out into the margins beside the letters.
   Width + gap stay inside the available margin at every width from 1180px up,
   so nothing ever collides with the column or runs off the side. */
@media (min-width: 1180px) {
  .hero__photos .polaroid { --w: 11rem; }

  /* these two sections are given room so their margin photographs have
     somewhere to sit without stacking on top of one another */
  .prologue { min-height: 50rem; }
  .closing  { min-height: 72rem; }
}

/* Below laptop there are no margins to speak of, so each section's photographs
   drop into the flow underneath it — still never between the letters. */
@media (max-width: 1179px) {
  .hero__photos { display: none; }

  .sideScatter {
    position: static;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-start;
    /* generous, because a rotated frame needs room for its corners */
    gap: clamp(1.5rem, 5vw, 3rem);
    margin-top: clamp(2rem, 6vw, 3.5rem);
  }

  .sideScatter .polaroid {
    position: static;
    --anchor: 0px;
    --py: 0px;
    --w: clamp(8rem, 38vw, 12rem) !important;
  }
}

/* phone */
@media (max-width: 640px) {
  :root { --section-y: clamp(3.5rem, 11vh, 6rem); }

  .hero { min-height: 100svh; }

  .note__head {
    grid-template-columns: 1fr auto;
    padding-left: 1.9rem;
  }

  .note__meta {
    flex-direction: column;
    align-items: flex-start;
    gap: .1rem;
  }

  .note__date { padding-right: 0; }
  .note__date::after { display: none; }

  .note__preview {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
  }

  .note__sheet::after { left: .9rem; }
  .note__panelPad { padding-left: 1.9rem; }

  .note::before { transform: rotate(-.9deg) translate(-4px, 4px); }
  .note::after  { transform: rotate(1.1deg) translate(5px, 7px); }

  .band__media { height: clamp(16rem, 44vh, 22rem); }
}

/* very small phones */
@media (max-width: 380px) {
  .note__title { font-size: 1.38rem; }
  .note__seal { width: 2.2rem; }
}

/* ---------- respect the setting ------------------------------------------ */
@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; }
  .site { opacity: 1; }
  .grain { animation: none; }
  .polaroid:hover {
    transform: translateY(var(--anchor, 0px)) rotate(var(--rot, 0deg));
  }
  /* the viewer must still appear — it just appears instantly */
  .viewer__backdrop { opacity: 1; }
  .viewer__figure { opacity: 1; transform: none; }

  /* the accordion still needs to open — keep it, just instant */
  .note__panel { transition: none; }
}
