/* ============================================================================
   BASE — reset, paper, typography, global atmosphere
   ========================================================================== */

*,*::before,*::after{ box-sizing:border-box; }
*{ margin:0; padding:0; }

html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:auto;              /* Lenis owns scrolling */
}

body{
  background:var(--ivory);
  color:var(--ink);
  font-family:var(--f-sans);
  font-size:var(--t-body);
  font-weight:300;
  line-height:1.72;
  letter-spacing:.005em;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
  overflow-x:clip;
}

img,svg,video,canvas{ display:block; max-width:100%; }
img{ height:auto; }
button,input{ font:inherit; color:inherit; background:none; border:none; }
button{ cursor:pointer; }
a{ color:inherit; text-decoration:none; }
ul,ol{ list-style:none; }
::selection{ background:var(--blush-deep); color:var(--ink); }

/* Scrollbar — thin, warm, unobtrusive */
::-webkit-scrollbar{ width:9px; }
::-webkit-scrollbar-track{ background:var(--ivory-warm); }
::-webkit-scrollbar-thumb{ background:var(--sand); border-radius:9px; border:2px solid var(--ivory-warm); }
::-webkit-scrollbar-thumb:hover{ background:var(--rose); }


/* ── PAPER ──────────────────────────────────────────────────────────────────
   A fibrous, warm sheet. Two turbulence layers: coarse fibre + fine tooth.
   Used as a background-image so it can sit under any colour.
   ------------------------------------------------------------------------ */
:root{
  --paper-fibre:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23f)' opacity='.42'/%3E%3C/svg%3E");
  /* Opacity is baked low here because .grain composites it with plain alpha
     rather than multiply — see the note on .grain below. */
  --paper-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='2.4' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)' opacity='.075'/%3E%3C/svg%3E");
  --paper-cloud:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='700' height='700'%3E%3Cfilter id='c'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.008' numOctaves='5'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='700' height='700' filter='url(%23c)' opacity='.6'/%3E%3C/svg%3E");
}

.paper{ position:relative; isolation:isolate; }
.paper::before{
  content:''; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background-image:var(--paper-fibre), var(--paper-cloud);
  background-size:300px 300px, 700px 700px;
  mix-blend-mode:multiply;
  opacity:.16;
}

/* Film grain and vignette, in ONE fixed layer instead of two.
   Every full-viewport fixed overlay has to be recomposited on every scroll
   frame, so each one is a permanent tax on scrolling. These two were the last
   pair; merging them halves that cost, and dropping the grain's multiply
   blend removes a whole blending pass over the entire viewport. On paper this
   warm the difference between multiply and plain alpha is not visible. */
.grain{
  position:fixed; inset:0; z-index:9000; pointer-events:none;
  background-image:
    var(--paper-grain),
    radial-gradient(130% 100% at 50% 42%, transparent 42%, rgba(122,91,75,.13) 100%);
  background-size:160px 160px, cover;
}
/* kept as a hook so markup and older CSS do not break */
.vignette{ display:none; }


/* ── TYPE ────────────────────────────────────────────────────────────────── */

.script{
  font-family:var(--f-script);
  font-weight:400;
  line-height:.98;
  letter-spacing:.005em;
  color:var(--ink);
}
.hand{
  font-family:var(--f-hand);
  font-weight:500;
  line-height:1.35;
  color:var(--brown);
}
.serif{
  font-family:var(--f-serif);
  font-weight:300;
  line-height:1.5;
  letter-spacing:.004em;
}

.eyebrow{
  font-family:var(--f-sans);
  font-size:var(--t-eyebrow);
  font-weight:500;
  letter-spacing:.34em;
  text-transform:uppercase;
  color:var(--rose-deep);
  display:inline-flex; align-items:center; gap:.85em;
}
.eyebrow::before{
  content:''; width:2.1rem; height:1px;
  background:linear-gradient(90deg,transparent,var(--rose));
}
.eyebrow.is-bare::before{ display:none; }

.t-display{ font-family:var(--f-script); font-size:var(--t-mega); line-height:.94; }
.t-1{ font-family:var(--f-script); font-size:var(--t-xl); line-height:1.0; }
.t-2{ font-family:var(--f-script); font-size:var(--t-lg); line-height:1.05; }
.t-3{ font-family:var(--f-serif); font-size:var(--t-md); font-weight:400; line-height:1.24; letter-spacing:.002em; }

.lede{
  font-family:var(--f-serif);
  font-size:clamp(1.05rem,1.35vw,1.35rem);
  font-weight:300; line-height:1.66; color:var(--ink-soft);
  max-width:46ch;
}
.copy{ color:var(--muted); max-width:52ch; font-weight:300; }
.tiny{ font-size:var(--t-small); letter-spacing:.13em; text-transform:uppercase; color:var(--ink-faint); font-weight:400; }

/* The little ♡ that punctuates every heading in the reference.
   Capped in absolute terms so it stays a grace note next to display type
   rather than growing into a second headline. */
.hrt{
  display:inline-block; color:var(--rose);
  font-size:min(.42em, 1.35rem);
  vertical-align:.4em; margin-left:.3em; font-family:var(--f-sans);
  line-height:1;
}
.hrt::before{ content:'♡'; }
.hrt.is-full::before{ content:'♥'; }


/* ── LAYOUT ──────────────────────────────────────────────────────────────── */

.shell{
  width:100%; max-width:var(--maxw);
  margin-inline:auto;
  padding-inline:var(--gut);
}

.section{
  position:relative;
  padding-block:var(--sect);
  isolation:isolate;
  scroll-margin-top:5.5rem;
}
.section--tight{ padding-block:calc(var(--sect) * .62); }

/* Section head — eyebrow / script title / lede, used everywhere. */
.shead{ display:flex; flex-direction:column; gap:1.1rem; max-width:34rem; }
.shead .t-1,.shead .t-2{ margin-top:-.15rem; }


/* ── HAIRLINES & ORNAMENT ────────────────────────────────────────────────── */

.rule{
  height:1px; border:0;
  background:linear-gradient(90deg,transparent,var(--rule) 12%,var(--rule) 88%,transparent);
}
.rule--dot{
  height:1px; border:0;
  background-image:radial-gradient(circle,var(--linen) 1px,transparent 1px);
  background-size:7px 1px; background-repeat:repeat-x;
  opacity:.75;
}

/* Hand-drawn arrow used as a nudge toward the next thing. */
.arrow-hand{ color:var(--rose); opacity:.72; }


/* ── UTILITY ─────────────────────────────────────────────────────────────── */

.sr-only{
  position:absolute!important; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap;
}
.nowrap{ white-space:nowrap; }
[hidden]{ display:none!important; }

/* Elements start invisible only when JS is alive to reveal them.
   No blanket will-change here: it promoted ~120 elements to their own layers
   for the whole session to serve one animation each. GSAP sets and clears it
   around the tween, which is what it is for. */
.js [data-reveal]{ opacity:0; }


/* ── MOTION SAFETY ───────────────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;
    animation-iteration-count:1!important;
    transition-duration:.001ms!important;
  }
  .grain{ animation:none; }
  .js [data-reveal]{ opacity:1!important; }
}
