/* Kingswell Publishing
   open-letter envelope: sticky pin + GSAP scrubbed timeline (public/js/site.js).
   This file is the look; the motion is all GSAP. Tokens live in tokens.css. */

/* ============================================================
   3. OPEN LETTER - a full-bleed envelope sits on the floor of the
   viewport, already open (flap up, seal gone); the letter rides up
   out of the pocket and rests there to be read.
   Pin = CSS sticky. Scrub = GSAP ScrollTrigger.
   ============================================================ */
.letter{
  height:200svh;                        /* 100svh pinned: the letter rises out (~65%), then holds to read */
}
.letter__stage{
  position:sticky;top:0;height:100svh;overflow:hidden;
  background:
    radial-gradient(120% 90% at 50% 118%, rgba(18,124,110,.10), transparent 60%),
    var(--paper);
  box-shadow:inset 0 0 240px rgba(7,33,31,.08);
}
.letter__aura{
  position:absolute;left:50%;top:56%;width:150vmax;height:150vmax;
  transform:translate(-50%,-50%);pointer-events:none;
  background:radial-gradient(circle, rgba(232,200,122,.16), rgba(232,200,122,0) 46%);
}

.letter__head{
  position:absolute;left:0;right:0;top:clamp(84px,12vh,146px);
  text-align:center;z-index:950;pointer-events:none;
}
.letter__head h2{
  font-size:clamp(32px,4.6vw,72px);max-width:15ch;margin-inline:auto;
  padding-inline:var(--gutter);
}

.env{
  /* one width drives every dimension, so the whole object scales as a unit.
     the sheet is short now (a note, not a page) so --sheetH is small and
     --sheetFS runs larger — a few generous lines read as considered, not empty. */
  --w: min(78vw, 90vh, 820px);
  --envH: .44;      /* real #10 envelope proportion */
  --sheetH: .5;
  --sheetFS: .020;
  --sheetPB: .10;
  position:absolute;left:50%;margin-left:calc(var(--w) / -2);
  bottom:calc(var(--w) * -0.075);          /* the envelope runs off the floor */
  width:var(--w);height:calc(var(--w) * var(--envH));
  perspective:2200px;
  /* rises above the fixed nav pill (z-index 900) as the letter passes it,
     rather than showing through its frosted blur */
  z-index:940;
}
/* the inside of the envelope (seen above the pocket and through its V):
   a shade darker than the outside, and shadowed from the fold down, so the
   pocket reads as having depth instead of one flat card */
.env__back{
  position:absolute;inset:0;border-radius:5px;
  /* one ivory paper throughout: inside is the darkest tone of it */
  background:linear-gradient(180deg,#E6D8BB 0%,#ECE0C7 45%,#F0E6D1 100%);
  box-shadow:0 40px 110px -50px rgba(7,33,31,.45), 0 -20px 80px -44px rgba(7,33,31,.28),
             inset 0 20px 30px -20px rgba(92,70,30,.22),    /* shade under the fold */
             inset 0 0 0 1px rgba(163,126,44,.16);          /* paper edge */
}
.env__back::after{                        /* paper grain, barely there */
  content:"";position:absolute;inset:0;border-radius:5px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  opacity:.05;mix-blend-mode:multiply;pointer-events:none;
}
/* the open flap, standing up behind the letter. Drawn upright (no 3D flip,
   which smeared its highlight into a haze at the fold). The element itself
   is the light paper edge; ::before is the inner face inset by a hair, so
   both slanted edges carry a crisp cut-paper line. */
.env__flap{
  position:absolute;left:0;right:0;bottom:100%;height:64%;
  background:#FBF7EE;
  clip-path:polygon(0 100%, 50% 0, 100% 100%);
  z-index:1;
}
.env__flap::before{                       /* inner face: lit toward the tip, shaded into the fold */
  content:"";position:absolute;inset:0;
  clip-path:polygon(1.3% 100%, 50% 2.4%, 98.7% 100%);
  background:linear-gradient(180deg,#F4ECDB 0%,#EDE2CA 55%,#E4D5B6 100%);
}
.env__flap::after{                        /* fold shadow + grain */
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(0deg,rgba(92,70,30,.14),rgba(92,70,30,0) 16%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  background-blend-mode:normal,multiply;
  opacity:.35;
}

/* the travel window: the letter is clipped to this while it is inside,
   and stays visible far above so it can leave the frame cleanly */
.env__clip{
  position:absolute;left:9%;right:9%;bottom:8%;top:-520%;
  overflow:hidden;z-index:2;pointer-events:none;
}
.env__sheet{
  position:absolute;left:0;right:0;bottom:0;
  height:auto;min-height:calc(var(--w) * var(--sheetH));   /* grows to fit the text (phones overflowed a fixed height) */
  background:linear-gradient(180deg,#FDFEFD,#F5F8F5);
  color:var(--ink);
  font-size:calc(var(--w) * var(--sheetFS));
  padding:calc(var(--w) * .045) calc(var(--w) * .05) calc(var(--w) * var(--sheetPB));
  box-shadow:0 -10px 24px -14px rgba(7,33,31,.3), 0 4px 0 rgba(255,255,255,.95),   /* tight: a wide one got cut into a box by .env__clip over the open flap */
             inset 0 1px 0 rgba(255,255,255,.9), inset 0 0 0 1px rgba(7,33,31,.05);
  transform:translateY(101%);will-change:transform;
}
.env__sheet::before{                      /* letterhead hairline */
  content:"";position:absolute;left:calc(var(--w) * .05);right:calc(var(--w) * .05);
  top:calc(var(--w) * .030);height:2px;background:var(--gold);opacity:.7;
}
.env__sheet::after{                       /* paper grain */
  content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  opacity:.09;mix-blend-mode:multiply;pointer-events:none;
}
.env__sheen{                              /* diagonal light sweep as the letter settles */
  position:absolute;inset:-20% -10%;pointer-events:none;z-index:2;
  background:linear-gradient(105deg, transparent 42%, rgba(255,255,255,.6) 50%, transparent 58%);
  transform:translateX(-130%);mix-blend-mode:overlay;
  display:none;                         /* retired: no blend-mode layer under the scrub */
}
.env__body{max-width:58ch;margin-inline:auto;display:flex;flex-direction:column;gap:.62em;position:relative;z-index:1;}
.env__sheet p{font-size:1em;line-height:1.62;letter-spacing:-0.006em;color:rgba(7,33,31,.82);}
.env__sheet .env__to{font-weight:500;color:var(--ink);}
.env__sheet .env__closing{font-weight:600;color:var(--ink);margin-top:.1em;}
.env__rule{height:1px;background:rgba(7,33,31,.14);margin:.5em 0 .2em;}
.env__sheet .env__sig{
  font-family:Unbounded,serif;font-style:italic;
  font-variation-settings:"SOFT" 40,"WONK" 1;
  font-size:1.32em;color:var(--ink);line-height:1.2;
}
.env__sheet .env__sig small{
  display:block;font-family:'Plus Jakarta Sans',sans-serif;font-style:normal;
  font-size:.62em;color:rgba(7,33,31,.55);margin-top:.5em;letter-spacing:0;
}

.env__front{
  position:absolute;left:0;right:0;bottom:0;top:30%;
  background:linear-gradient(178deg,#F6EFE0 0%,#F9F4EA 52%,#F3EBDA 100%);
  clip-path:polygon(0 0, 50% 30%, 100% 0, 100% 100%, 0 100%);
  border-radius:0 0 5px 5px;z-index:3;
  box-shadow:inset 0 -30px 60px -44px rgba(92,70,30,.22),
             inset 1px 0 0 rgba(163,126,44,.16), inset -1px 0 0 rgba(163,126,44,.16),
             inset 0 -1px 0 rgba(163,126,44,.2);
}
/* the folds of a real envelope front: two side flaps (a touch darker) tucked
   under a bottom flap (a touch lighter), with a pressed crease where they meet */
.env__front::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath d='M0 0L50 46L0 100Z' fill='rgba(92,70,30,.05)'/%3E%3Cpath d='M100 0L50 46L100 100Z' fill='rgba(92,70,30,.05)'/%3E%3Cpath d='M0 100L50 46L100 100Z' fill='rgba(255,255,255,.35)'/%3E%3Cpath d='M0 100L50 46L100 100' fill='none' stroke='rgba(163,126,44,.22)' stroke-width='1' vector-effect='non-scaling-stroke'/%3E%3Cpath d='M0 99L50 45L100 99' fill='none' stroke='rgba(255,255,255,.8)' stroke-width='1' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E") center/100% 100% no-repeat;
}
.env__front::after{                       /* grain */
  content:"";position:absolute;inset:0;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  opacity:.05;mix-blend-mode:multiply;
}
.env__cast{                               /* contact shadow the rising letter casts on the pocket */
  position:absolute;left:7%;right:7%;top:30%;height:26%;z-index:4;pointer-events:none;
  background:radial-gradient(ellipse 62% 100% at 50% 0%, rgba(7,33,31,.5), rgba(7,33,31,0) 74%);
  opacity:0;
  display:none;                         /* retired: the letter now runs deep into the pocket, and this read as a smudge on it */
}
.env__mark{
  position:absolute;left:6%;bottom:26%;z-index:4;
  font-family:Unbounded,serif;font-size:calc(var(--w) * .0125);
  letter-spacing:.24em;text-transform:uppercase;
  color:rgba(163,126,44,.55);
  text-shadow:0 1px 0 rgba(255,255,255,.7);
  pointer-events:none;
}
.env__lip{                                /* bright paper edge along the pocket */
  position:absolute;left:0;right:0;top:30%;height:34%;
  clip-path:polygon(0 0, 50% 30%, 100% 0, 100% 1.6%, 50% 31.6%, 0 1.6%);
  background:rgba(255,255,255,.85);z-index:4;pointer-events:none;
}
/* wax seal, still stuck to the tip of the open flap. Same layer as the flap
   (after it in the DOM, so on top of it) but under the letter, which slides
   in front of it like it would in the hand. Slightly irregular edge + an
   inner stamped ring so it reads as pressed wax, not a flat button. */
.env__seal{
  position:absolute;left:50%;top:-58%;width:6.4%;aspect-ratio:1;
  transform:translate(-50%,-50%);
  border-radius:52% 48% 51% 49% / 49% 52% 48% 51%;
  background:radial-gradient(circle at 36% 30%, #3AAA98 0%, #17806F 36%, #0B4640 72%, #072F2A 100%);
  box-shadow:0 7px 14px -5px rgba(7,33,31,.6), 0 2px 3px rgba(7,33,31,.35),
             inset 0 -3px 6px rgba(0,0,0,.38), inset 0 2px 3px rgba(255,255,255,.28);
  z-index:1;display:grid;place-items:center;
  font-family:Unbounded,serif;font-style:italic;font-size:calc(var(--w) * .021);color:var(--gold);
  text-shadow:0 1px 0 rgba(0,0,0,.35);
}
.env__seal::before{                       /* stamped inner ring */
  content:"";position:absolute;inset:15%;border-radius:50%;
  border:1px solid rgba(232,200,122,.55);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.3), 0 1px 0 rgba(255,255,255,.15);
}

/* ---- fallbacks: motion off, or the animation library failed to load ---- */
@media (prefers-reduced-motion:reduce){
  .letter{height:auto;}
  .letter__stage{position:static;height:auto;min-height:100svh;padding-bottom:34vh;}
  .env__sheet{transform:translateY(0);}
}
.no-gsap .letter{height:auto;}
.no-gsap .letter__stage{position:static;height:auto;min-height:100svh;padding-bottom:34vh;}
.no-gsap .env__sheet{transform:translateY(0);}

/* phones: the envelope has to fit the screen, so it stands taller; the
   note is short, so the sheet stays compact even at this proportion */
@media (max-width:820px){
  .env{
    --w: min(94vw, 62vh, 460px);
    --envH: .62;
    --sheetH: 1.05;
    --sheetFS: .050;
    --sheetPB: .16;
  }
  .env__body{max-width:none;}
  .env__mark{display:none;}
  .env__seal{width:9%;font-size:calc(var(--w) * .03);}
}
