/* ============================================================
   KEEPSAKES — cinematic scroll-jacked scrapbook
   Pull-up-a-chair memory book · horizontal reels · journey thread
   Builds on styles.css tokens (--clay, --parch, --espresso, fonts)
   ============================================================ */

.ks{
  --paper:        oklch(0.962 0.010 86);
  --paper-deep:   oklch(0.930 0.014 82);
  --thread:       var(--clay);
  --ink:          var(--espresso-dk);
  background:var(--paper);
  color:var(--espresso);
  overflow-x:hidden;
}
.ks *{ box-sizing:border-box; }

/* paper grain over everything */
.ks::before{
  content:""; position:fixed; inset:0; z-index:1; pointer-events:none; opacity:.5;
  mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
}

/* hide the decor symbol library */
.ks-defs{ position:absolute; width:0; height:0; overflow:hidden; }

/* ---------- shared decor primitives ---------- */
.decor{ position:absolute; pointer-events:none; z-index:6; color:var(--thread); }
.decor svg, svg.decor{ width:100%; height:100%; display:block; overflow:visible; }

/* washi / masking tape */
.tape{ position:absolute; z-index:8; width:92px; height:30px; pointer-events:none;
  background:
    linear-gradient(115deg, rgba(255,255,255,.18), rgba(255,255,255,0) 40%),
    repeating-linear-gradient(90deg, rgba(0,0,0,.04) 0 7px, rgba(0,0,0,0) 7px 14px),
    var(--tape-c, oklch(0.86 0.04 78 / .8));
  box-shadow:0 2px 6px rgba(20,17,15,.12);
  -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
  mask-image:linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%); }
.tape--paper{ --tape-c:oklch(0.93 0.012 84 / .9); }
.tape--sage{  --tape-c:oklch(0.84 0.03 140 / .78); }
.tape--blue{  --tape-c:oklch(0.82 0.03 250 / .72); }
.tape--clay{  --tape-c:oklch(0.78 0.06 44 / .68); }

/* paperclip wrapper (clips over the top edge) */
.clip{ position:absolute; top:-16px; left:22px; width:26px; height:58px; z-index:9; color:var(--taupe);
  filter:drop-shadow(0 2px 2px rgba(20,17,15,.28)); }

/* wax seal / round stamp */
.ks-seal{ display:inline-flex; flex-direction:column; align-items:center; justify-content:center; gap:.12em;
  width:88px; height:88px; border-radius:50%; border:1px dashed rgba(166,96,60,.6);
  background:radial-gradient(circle at 50% 36%, rgba(202,140,80,.16), transparent 70%);
  color:var(--clay); text-align:center; }
.ks-seal i{ font-family:var(--serif); font-style:normal; font-size:1.25rem; letter-spacing:.05em; line-height:1; }
.ks-seal b{ font-family:var(--mono); font-weight:400; font-size:.46rem; letter-spacing:.2em; text-transform:uppercase; color:var(--taupe); }

/* handwritten + typed caption styles */
.hand{ font-family:var(--hand); line-height:1.15; color:var(--clay); }
.typed{ font-family:var(--mono); font-size:.62rem; letter-spacing:.18em; text-transform:uppercase; color:var(--taupe); }
.script{ font-family:var(--script); }

/* =========================================================
   PHOTO OBJECTS
   ========================================================= */
.photo{ position:relative; background:#fdfaf3; padding:10px 10px 0; box-shadow:0 18px 36px -16px rgba(20,17,15,.5), 0 3px 10px rgba(20,17,15,.12);
  border:1px solid rgba(20,17,15,.05); }
.photo img{ width:100%; height:100%; object-fit:cover; display:block; filter:saturate(.96) contrast(1.02); }
.photo figcaption{ font-family:var(--hand); font-size:1.15rem; color:var(--ink); text-align:center; padding:.5rem .2rem .7rem; line-height:1; }
.photo--polaroid{ padding-bottom:0; }
.photo--polaroid figcaption{ padding:.7rem .2rem .9rem; }

/* torn-edge print (no white border, ragged top+bottom) */
.print{ position:relative; box-shadow:0 18px 40px -18px rgba(20,17,15,.55); }
.print img{ width:100%; height:100%; object-fit:cover; display:block;
  -webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='500' preserveAspectRatio='none'%3E%3Cpath fill='%23000' d='M0 14 Q40 6 80 12 T160 9 T250 13 T330 8 T400 14 L400 486 Q350 494 300 488 T210 491 T120 487 T40 492 T0 486 Z'/%3E%3C/svg%3E");
  mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='500' preserveAspectRatio='none'%3E%3Cpath fill='%23000' d='M0 14 Q40 6 80 12 T160 9 T250 13 T330 8 T400 14 L400 486 Q350 494 300 488 T210 491 T120 487 T40 492 T0 486 Z'/%3E%3C/svg%3E");
  -webkit-mask-size:100% 100%; mask-size:100% 100%; }

/* film frame (sprocket holes) */
.filmframe{ position:relative; background:#1c1815; padding:26px 10px; box-shadow:0 18px 40px -16px rgba(20,17,15,.6); }
.filmframe::before, .filmframe::after{ content:""; position:absolute; left:0; right:0; height:14px;
  background-image:repeating-linear-gradient(90deg, #1c1815 0 8px, #d8cfbf 8px 17px); background-size:auto 100%;
  -webkit-mask:repeating-linear-gradient(90deg, transparent 0 4px, #000 4px 13px); mask:repeating-linear-gradient(90deg, transparent 0 4px, #000 4px 13px); }
.filmframe::before{ top:6px; } .filmframe::after{ bottom:6px; }
.filmframe img{ width:100%; height:100%; object-fit:cover; }

/* angles */
.rot-1{ transform:rotate(-3deg); } .rot-2{ transform:rotate(2.4deg); }
.rot-3{ transform:rotate(-1.6deg); } .rot-4{ transform:rotate(3.2deg); }
.rot-5{ transform:rotate(-4.4deg); } .rot-6{ transform:rotate(1.2deg); }

/* =========================================================
   NAV offset + COVER
   ========================================================= */
.ks-cover{ position:relative; z-index:2; min-height:100svh; display:grid; place-items:center; text-align:center;
  padding:7rem 1.4rem 3rem; overflow:hidden; }
.ks-cover__deco{ position:absolute; inset:0; z-index:0; pointer-events:none; }
.ks-cover__inner{ position:relative; z-index:3; max-width:46rem; }
.ks-cover__kicker{ font-family:var(--mono); font-size:.66rem; letter-spacing:.42em; text-transform:uppercase; color:var(--taupe); }
.ks-cover__title{ font-family:var(--serif); font-weight:400; line-height:.86; color:var(--ink);
  font-size:clamp(4.2rem,17vw,15rem); letter-spacing:-.01em; margin:.1em 0 .15em; }
.ks-cover__title em{ font-style:italic; color:var(--clay); }
.ks-cover__sub{ font-family:var(--serif); font-style:italic; font-size:clamp(1.1rem,2.4vw,1.7rem); color:var(--taupe); max-width:34ch; margin:0 auto; }
.ks-cover__hand{ font-family:var(--hand); font-size:clamp(1.6rem,3vw,2.3rem); color:var(--clay); transform:rotate(-4deg); display:inline-block; margin-bottom:.4rem; }

.ks-cover__cluster{ position:absolute; inset:0; z-index:1; pointer-events:none; }
.ks-cover__ph{ position:absolute; width:clamp(110px,13vw,200px); }
.cph-1{ top:11%; left:7%; }   .cph-2{ bottom:10%; left:13%; }
.cph-3{ top:13%; right:8%; }  .cph-4{ bottom:9%; right:10%; }

.ks-scrollcue{ position:absolute; left:50%; bottom:2rem; transform:translateX(-50%); z-index:4; display:flex; flex-direction:column; align-items:center; gap:.5rem; }
.ks-scrollcue span{ font-family:var(--mono); font-size:.56rem; letter-spacing:.3em; text-transform:uppercase; color:var(--taupe); }
.ks-scrollcue i{ width:1px; height:42px; background:linear-gradient(var(--taupe), transparent); position:relative; overflow:hidden; }
.ks-scrollcue i::after{ content:""; position:absolute; top:-50%; left:0; width:100%; height:50%; background:var(--clay); animation:kscue 1.8s var(--ease) infinite; }
@keyframes kscue{ 0%{ transform:translateY(0); } 100%{ transform:translateY(300%); } }

/* =========================================================
   JOURNEY THREAD — wavy map trail rail
   ========================================================= */
.ks-rail{ position:fixed; left:max(1.1rem,2.2vw); top:50%; transform:translateY(-50%); z-index:40;
  display:flex; flex-direction:column; align-items:center; gap:0; pointer-events:none; }

/* the SVG trail */
.ks-trail{ display:block; overflow:visible; }
.ks-trail__bg{ fill:none; stroke:var(--sand); stroke-width:2; stroke-dasharray:4 7; stroke-linecap:round; }
.ks-trail__fill{ fill:none; stroke:var(--clay); stroke-width:2.5; stroke-linecap:round;
  stroke-dasharray:1; stroke-dashoffset:1;
  transition:stroke-dashoffset 0.25s ease; }

/* station dots */
.ks-trail .ks-bead{ fill:var(--paper); stroke:var(--sand); stroke-width:1.5;
  transition:fill .4s var(--ease), stroke .4s var(--ease); }
.ks-trail .ks-bead.on{ fill:var(--clay); stroke:var(--clay); transform:scale(1.3); transform-box:fill-box; transform-origin:center; }
.ks-trail .ks-bead.past{ fill:var(--sand); stroke:var(--sand); }
.ks-trail .ks-bead.on + .ks-bead-ring { opacity: 1; } /* fallback, real toggle done in JS */

/* station ring pulse — appears only when bead is active */
.ks-trail .ks-bead-ring{ fill:none; stroke:var(--clay); stroke-width:1.2; opacity:0; transition:opacity .4s var(--ease); }
.ks-trail .ks-bead-ring.on{ opacity:1; animation:ksRingPulse 2.2s ease-out infinite; }
@keyframes ksRingPulse{
  0%  { transform:scale(1);   opacity:.7; transform-box:fill-box; transform-origin:center; }
  100%{ transform:scale(2.6); opacity:0;  transform-box:fill-box; transform-origin:center; }
}

/* station label */
.ks-rail__label{ writing-mode:vertical-rl; margin-top:1rem; font-family:var(--mono); font-size:.54rem; letter-spacing:.34em; text-transform:uppercase; color:var(--taupe); }
@media (max-width:900px){ .ks-rail{ display:none; } }

/* mobile top progress */
.ks-topbar{ position:fixed; top:0; left:0; height:3px; width:100%; z-index:40; background:transparent; display:none; }
.ks-topbar i{ display:block; height:100%; width:var(--rail,0%); background:var(--clay); transition:width .15s linear; }
@media (max-width:900px){ .ks-topbar{ display:block; } }

/* =========================================================
   PAGE-TURN INTERSTITIAL (the vertical beats between reels)
   ========================================================= */
.ks-turn{ position:relative; z-index:2; min-height:62svh; display:grid; place-items:center; text-align:center; padding:4rem 1.4rem; overflow:hidden; }
.ks-turn__no{ font-family:var(--serif); font-style:italic; font-size:clamp(5rem,16vw,13rem); line-height:.8; color:var(--accent,var(--clay)); opacity:.22; }
.ks-turn__inner{ position:relative; z-index:3; max-width:40rem; margin-top:-2.5rem; }
.ks-turn__couple{ font-family:var(--serif); font-size:clamp(2.4rem,6vw,5rem); line-height:1; color:var(--ink); }
.ks-turn__couple em{ font-style:italic; color:var(--accent,var(--clay)); }
.ks-turn__meta{ font-family:var(--mono); font-size:.66rem; letter-spacing:.26em; text-transform:uppercase; color:var(--taupe); margin-top:1.1rem; }
.ks-turn__hand{ font-family:var(--hand); font-size:clamp(1.4rem,2.6vw,2rem); color:var(--accent,var(--clay)); transform:rotate(-2.5deg); display:inline-block; margin-top:1.4rem; }
.ks-turn__cue{ font-family:var(--mono); font-size:.58rem; letter-spacing:.28em; text-transform:uppercase; color:var(--taupe); margin-top:1.8rem; display:inline-flex; gap:.6rem; align-items:center; }
.ks-turn__cue::after{ content:"→"; font-size:1.1rem; color:var(--accent,var(--clay)); animation:ksnudge 1.6s var(--ease) infinite; }
@keyframes ksnudge{ 0%,100%{ transform:translateX(0); } 50%{ transform:translateX(6px); } }

/* =========================================================
   REEL — horizontal scroll-jacked spread
   ========================================================= */
.ks-reel{ position:relative; z-index:2; }
.ks-reel__sticky{ position:sticky; top:0; height:100svh; overflow:hidden; display:flex; align-items:center;
  background:var(--bg-tint, transparent); }
.ks-reel__track{ display:flex; align-items:center; gap:clamp(2.5rem,6vw,7rem); height:100%; padding:0 12vw;
  will-change:transform; }
.ks-reel__hint{ position:absolute; right:1.4rem; bottom:1.2rem; z-index:12; font-family:var(--mono); font-size:.54rem; letter-spacing:.22em; text-transform:uppercase; color:var(--taupe); opacity:.7; }

/* a panel = one beat inside the reel */
.ks-panel{ position:relative; flex:0 0 auto; display:flex; align-items:center; justify-content:center; }
.ks-panel--intro{ flex-basis:min(78vw,640px); }
.ks-panel--cluster{ flex-basis:min(92vw,860px); }
.ks-panel--single{ flex-basis:min(60vw,460px); }
.ks-panel--video{ flex-basis:min(60vw,420px); }
.ks-panel--quote{ flex-basis:min(80vw,560px); }
.ks-panel--end{ flex-basis:min(50vw,360px); }

/* chapter intro card */
.ks-intro{ position:relative; padding:2rem; }
.ks-intro__name{ font-family:var(--serif); font-size:clamp(2.6rem,6vw,4.6rem); line-height:.96; color:var(--ink); }
.ks-intro__name em{ font-style:italic; color:var(--accent,var(--clay)); }
.ks-intro__rule{ width:64px; height:1px; background:var(--accent,var(--clay)); margin:1.3rem 0; }
.ks-intro__meta{ font-family:var(--mono); font-size:.66rem; letter-spacing:.22em; text-transform:uppercase; color:var(--taupe); line-height:2; }
.ks-intro__note{ font-family:var(--hand); font-size:1.5rem; color:var(--accent,var(--clay)); transform:rotate(-2deg); margin-top:1.4rem; max-width:26ch; }
.ks-intro__seal{ position:absolute; right:-1rem; bottom:-1rem; }

/* photo clusters — overlapping arrangement */
.ks-cluster{ position:relative; width:100%; height:min(74vh,640px); }
.ks-cluster .obj{ position:absolute; }
/* a few reusable placements (override per-instance with inline if needed) */
.pos-a{ top:2%;  left:2%;   width:40%; }
.pos-b{ top:14%; left:36%;  width:46%; z-index:3; }
.pos-c{ top:40%; left:6%;   width:34%; z-index:4; }
.pos-d{ bottom:2%; right:3%; width:30%; z-index:5; }
.pos-e{ top:6%;  right:1%;  width:26%; }

/* single hero photo */
.ks-single{ width:100%; max-width:440px; }

/* vertical video reel */
.ks-vreel{ position:relative; width:min(58vw,360px); aspect-ratio:9/16; background:#15110e;
  padding:12px; box-shadow:0 26px 60px -22px rgba(20,17,15,.7); border:1px solid rgba(20,17,15,.06); }
.ks-vreel video{ width:100%; height:100%; object-fit:cover; display:block; background:#0c0a08; }
.ks-vreel__label{ position:absolute; left:50%; bottom:-1.7rem; transform:translateX(-50%); white-space:nowrap;
  font-family:var(--mono); font-size:.56rem; letter-spacing:.2em; text-transform:uppercase; color:var(--taupe); }
.ks-vreel__live{ position:absolute; top:1.3rem; left:1.3rem; z-index:4; display:inline-flex; align-items:center; gap:.4rem;
  font-family:var(--mono); font-size:.5rem; letter-spacing:.2em; text-transform:uppercase; color:#fff; opacity:.9; }
.ks-vreel__live::before{ content:""; width:7px; height:7px; border-radius:50%; background:#e0654a; box-shadow:0 0 0 0 rgba(224,101,74,.7); animation:kslive 1.6s infinite; }
@keyframes kslive{ 0%{ box-shadow:0 0 0 0 rgba(224,101,74,.6); } 100%{ box-shadow:0 0 0 9px rgba(224,101,74,0); } }
.ks-vreel__btn{ position:absolute; inset:0; z-index:5; display:grid; place-items:center; cursor:pointer; }
.ks-vreel__btn span{ width:60px; height:60px; border-radius:50%; background:rgba(253,250,243,.9); color:var(--ink); display:grid; place-items:center; font-size:1.1rem; padding-left:4px; box-shadow:0 8px 24px rgba(20,17,15,.4); transition:.4s var(--ease); }
.ks-vreel.playing .ks-vreel__btn{ opacity:0; pointer-events:none; }

/* big handwritten quote / torn note */
.ks-quote{ position:relative; }
.ks-quote__note{ position:relative; background:#f6efe1; padding:2.4rem 2.6rem; box-shadow:0 18px 40px -18px rgba(20,17,15,.45);
  transform:rotate(-1.4deg); }
.ks-quote__note::after{ content:""; position:absolute; inset:0; background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E"); pointer-events:none; }
.ks-quote__text{ font-family:var(--serif); font-style:italic; font-size:clamp(1.5rem,3vw,2.4rem); line-height:1.22; color:var(--ink); }
.ks-quote__by{ font-family:var(--hand); font-size:1.4rem; color:var(--accent,var(--clay)); margin-top:1rem; }

/* chapter end card */
.ks-end{ text-align:center; }
.ks-end__line{ font-family:var(--serif); font-style:italic; font-size:clamp(1.4rem,3vw,2.2rem); color:var(--taupe); }
.ks-end__arrow{ font-family:var(--mono); font-size:.6rem; letter-spacing:.26em; text-transform:uppercase; color:var(--clay); margin-top:1rem; }

/* =========================================================
   CLOSING — guestbook CTA
   ========================================================= */
.ks-close{ position:relative; z-index:2; min-height:100svh; display:grid; place-items:center; text-align:center; padding:7rem 1.4rem; overflow:hidden;
  background:var(--espresso-dk); color:var(--parch); }
.ks-close .ks-grain{ position:absolute; inset:0; z-index:0; opacity:.5; mix-blend-mode:overlay; pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E"); }
.ks-close__inner{ position:relative; z-index:3; max-width:42rem; }
.ks-close__hand{ font-family:var(--hand); font-size:clamp(1.7rem,3.4vw,2.6rem); color:var(--clay); transform:rotate(-3deg); display:inline-block; }
.ks-close__title{ font-family:var(--serif); font-weight:400; line-height:.92; color:var(--parch); font-size:clamp(2.6rem,7vw,6rem); margin:.6rem 0; }
.ks-close__title em{ font-style:italic; color:#e9c9a0; }
.ks-close__sub{ font-family:var(--serif); font-style:italic; color:rgba(244,239,230,.72); font-size:clamp(1.1rem,2.2vw,1.5rem); max-width:34ch; margin:0 auto 2.4rem; }
.ks-btn{ display:inline-flex; align-items:center; gap:.7rem; font-family:var(--mono); font-size:.66rem; letter-spacing:.24em; text-transform:uppercase;
  background:var(--parch); color:var(--espresso-dk); padding:1.1em 2em; border-radius:40px; transition:.4s var(--ease); }
.ks-btn:hover{ background:#e9c9a0; transform:translateY(-2px); }
.ks-close__seal{ margin-top:2.6rem; border-color:rgba(244,239,230,.4); color:var(--parch); }
.ks-close__seal b{ color:rgba(244,239,230,.6); }

/* reveal helper (used outside reels) */
.ks-rv{ opacity:0; transform:translateY(26px); transition:opacity 1s var(--ease), transform 1s var(--ease); }
.ks-rv.in{ opacity:1; transform:none; }
.ks-rv[data-d="1"]{ transition-delay:.12s; } .ks-rv[data-d="2"]{ transition-delay:.24s; } .ks-rv[data-d="3"]{ transition-delay:.36s; }

/* in-reel objects get a soft settle as the reel enters */
.ks-reel.in .obj, .ks-reel.in .ks-intro, .ks-reel.in .ks-vreel, .ks-reel.in .ks-quote, .ks-reel.in .ks-end, .ks-reel.in .ks-single{
  animation:kssettle .9s var(--ease) both; }
.ks-reel.in .obj:nth-child(2){ animation-delay:.06s; }
.ks-reel.in .obj:nth-child(3){ animation-delay:.12s; }
.ks-reel.in .obj:nth-child(4){ animation-delay:.18s; }
@keyframes kssettle{ from{ opacity:0; transform:translateY(22px) var(--rot,rotate(0)); } }

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width:760px){
  .ks-reel__track{ padding:0 8vw; gap:2.2rem; }
  .ks-panel--cluster{ flex-basis:88vw; }
  .ks-panel--intro{ flex-basis:82vw; }
  .ks-panel--single{ flex-basis:74vw; }
  .ks-panel--video{ flex-basis:76vw; }
  .ks-panel--quote{ flex-basis:84vw; }
  .ks-cluster{ height:64vh; }
  .ks-cover__cluster{ opacity:.5; }
  .ks-cover__ph{ width:clamp(86px,26vw,120px); }
}

/* =========================================================
   REDUCED MOTION / NO-JS FALLBACK
   reels become vertical stacks; no scroll-jack
   ========================================================= */
.ks-static .ks-reel__sticky{ position:static; height:auto; display:block; padding:3rem 0; }
.ks-static .ks-reel__track{ flex-direction:column; height:auto; padding:0 6vw; gap:3rem; transform:none !important; }
.ks-static .ks-panel{ flex-basis:auto !important; width:100%; max-width:560px; margin-inline:auto; }
.ks-static .ks-cluster{ height:auto; min-height:340px; }
.ks-static .ks-rail, .ks-static .ks-topbar{ display:none; }
@media (prefers-reduced-motion:reduce){
  .ks-reel__sticky{ position:static; height:auto; display:block; padding:3rem 0; }
  .ks-reel__track{ flex-direction:column; height:auto; padding:0 6vw; gap:3rem; transform:none !important; }
  .ks-panel{ flex-basis:auto !important; width:100%; max-width:560px; margin-inline:auto; }
  .ks-cluster{ height:auto; min-height:340px; }
  .ks-reel.in .obj, .ks-reel.in *{ animation:none !important; }
}

/* =========================================================
   MICRO-ANIMATIONS
   ========================================================= */

/* --- 1. Photo float (uses standalone 'translate' — composes with transform:rotate) --- */
@keyframes ksFloat{ from{ translate:0 0; } to{ translate:0 -5px; } }
.ks-reel .obj{ animation:ksFloat 5s ease-in-out infinite alternate; }
.ks-reel .obj:nth-child(2){ animation-duration:6.8s; animation-delay:-2.1s; }
.ks-reel .obj:nth-child(3){ animation-duration:4.3s; animation-delay:-3.5s; }
.ks-reel .obj:nth-child(4){ animation-duration:7.2s; animation-delay:-1s; }
.ks-reel .obj:nth-child(5){ animation-duration:5.6s; animation-delay:-4.2s; }

/* --- 2. SVG decor sway (uses standalone 'rotate' — composes with transform) --- */
@keyframes ksSway{ from{ rotate:-3.5deg; } to{ rotate:4deg; } }
.ks-reel .decor{ transform-origin:center bottom; animation:ksSway 8s ease-in-out infinite alternate; }
.ks-reel .decor:nth-of-type(even){ animation-duration:11s; animation-delay:-4s; }

/* --- 3. Chapter turn — stamp / wipe-in entrance --- */
.ks-turn__no{ opacity:.22; }
@keyframes ksStamp{
  0%  { opacity:0; transform:scale(1.6) rotate(5deg); filter:blur(4px); }
  55% { opacity:.28; transform:scale(.96) rotate(-1.5deg); filter:blur(0); }
  100%{ opacity:.22; transform:scale(1) rotate(0); filter:blur(0); }
}
@keyframes ksWipe{ from{ clip-path:inset(0 100% 0 0); } to{ clip-path:inset(0 0% 0 0); } }

.ks-turn.in .ks-turn__no{     animation:ksStamp .85s var(--ease) forwards; }
.ks-turn.in .ks-turn__couple{ animation:ksWipe .9s var(--ease) .18s both; }
.ks-turn.in .ks-turn__meta{   animation:ksWipe .6s var(--ease) .38s both; }
.ks-turn.in .ks-turn__hand{   animation:ksWipe .7s var(--ease) .5s both; }
.ks-turn.in .ks-turn__cue{    animation:ksWipe .5s var(--ease) .66s both; }

/* clip-path needs baseline hidden state */
.ks-turn__couple,.ks-turn__meta,.ks-turn__hand,.ks-turn__cue{
  clip-path:inset(0 100% 0 0);
}
.ks-turn.in .ks-turn__couple,.ks-turn.in .ks-turn__meta,
.ks-turn.in .ks-turn__hand,.ks-turn.in .ks-turn__cue{
  clip-path:inset(0 0% 0 0);
}

/* --- 4. Wax seal slow wobble --- */
@keyframes ksSealWobble{ from{ rotate:-3deg; } to{ rotate:3deg; } }
.ks-seal{ animation:ksSealWobble 6s ease-in-out infinite alternate; transform-origin:center; }

/* --- 5. Cover scroll cue already has kscue (defined above) --- */

/* --- 6. Panel 3D perspective — set on track, JS drives rotateY per panel --- */
.ks-reel__track{ perspective:1000px; }
.ks-panel{ transform-style:preserve-3d; will-change:transform; }

/* --- 7. Photo hover lift --- */
.ks-reel .photo,.ks-reel .print,.ks-reel .filmframe{ transition:box-shadow .4s var(--ease), filter .4s var(--ease); }
.ks-reel .photo:hover,.ks-reel .print:hover{
  box-shadow:0 28px 56px -20px rgba(20,17,15,.6), 0 6px 16px rgba(20,17,15,.18);
  filter:saturate(1.04) contrast(1.03);
  z-index:9;
}

/* --- 8. Closing CTA background shimmer --- */
@keyframes ksShimmer{ 0%,100%{ opacity:.5; } 50%{ opacity:.7; } }
.ks-close .ks-grain{ animation:ksShimmer 7s ease-in-out infinite; }

/* --- 9. Reduced motion: kill everything --- */
@media (prefers-reduced-motion:reduce){
  .ks-reel .obj, .ks-reel .decor, .ks-seal, .ks-turn__no,
  .ks-trail .ks-bead-ring.on, .ks-close .ks-grain,
  .ks-turn.in .ks-turn__no{ animation:none !important; }
  .ks-turn__couple,.ks-turn__meta,.ks-turn__hand,.ks-turn__cue{ clip-path:none !important; }
}

/* ============================================================
   v2 ADDITIONS — canvas trail · scatter · front-pop · 3D tilt
   ============================================================ */

/* #ks-maptrail removed — trail is the side SVG rail */
#ks-maptrail{ display:none; }

/* ─── PANEL 3D TILT (slight rotateY as panel drifts off-center) ─── */
.ks-panel{
  transform:perspective(1400px) rotateY(calc(var(--ptilt,0) * 7deg));
  transition:transform 0.35s ease;
}

/* ─── PHOTO SCATTER ───
   Uses standalone CSS translate + scale properties — compose cleanly
   with the transform:rotate() on .rot-N classes.
   Photos start collapsed (stacked) and scatter to their target positions.
*/
.ks-cluster .obj{
  cursor:pointer;
  transition:
    translate 0.9s cubic-bezier(0.34,1.56,0.64,1),
    scale     0.85s cubic-bezier(0.34,1.56,0.64,1),
    opacity   0.5s ease,
    box-shadow 0.4s ease;
}

/* Initial "stacked pile" state (before scatter fires) */
.ks-cluster .obj:not(.scatter-in){
  opacity:0;
  scale:0.65;
  translate:var(--scx,28px) var(--scy,22px);
  transition:none !important;
}
/* Per-child start offsets — creates the scattered pile effect */
.ks-cluster .obj:nth-child(1):not(.scatter-in){ --scx:22px;  --scy:36px; }
.ks-cluster .obj:nth-child(2):not(.scatter-in){ --scx:-32px; --scy:18px; }
.ks-cluster .obj:nth-child(3):not(.scatter-in){ --scx:14px;  --scy:-24px; }
.ks-cluster .obj:nth-child(4):not(.scatter-in){ --scx:-18px; --scy:30px; }
.ks-cluster .obj:nth-child(5):not(.scatter-in){ --scx:26px;  --scy:-16px; }

/* Scattered (landed) — spring to natural position */
.ks-cluster .obj.scatter-in{
  opacity:1;
  scale:1;
  translate:0px 0px;
}

/* ─── HOVER: subtle lift when already scattered, not front ─── */
.ks-cluster .obj.scatter-in:not(.ks-front):hover{
  scale:1.04 !important;
  translate:0px -6px !important;
  z-index:10;
  box-shadow:0 28px 56px -18px rgba(20,17,15,.58),0 6px 16px rgba(20,17,15,.16) !important;
  transition:
    scale 0.28s cubic-bezier(0.34,1.56,0.64,1),
    translate 0.28s cubic-bezier(0.34,1.56,0.64,1),
    box-shadow 0.28s ease !important;
}

/* ─── FRONT-POP: click brings a back photo to front with spring bounce ─── */
.ks-cluster .obj.ks-front{
  z-index:20 !important;
  scale:1.10 !important;
  translate:0px -12px !important;
  box-shadow:0 48px 88px -22px rgba(20,17,15,.75),
             0 12px 30px rgba(20,17,15,.26) !important;
  filter:saturate(1.06) contrast(1.03) !important;
  transition:
    scale     0.55s cubic-bezier(0.34,1.56,0.64,1),
    translate 0.55s cubic-bezier(0.34,1.56,0.64,1),
    box-shadow 0.45s ease !important;
}

/* ─── Override old settle animation on .obj — scatter handles it now ─── */
.ks-reel.in .obj{ animation:none !important; }
/* Keep settle on non-cluster panel elements */
.ks-reel.in .ks-intro,
.ks-reel.in .ks-vreel,
.ks-reel.in .ks-quote__note,
.ks-reel.in .ks-end,
.ks-reel.in .ks-single{
  animation:kssettle .9s var(--ease) both;
}

/* ─── COVER CLUSTER: polaroids settle in on page load ─── */
.ks-cover__cluster .ks-cover__ph{
  animation:ks-cover-in 1.3s cubic-bezier(0.22,1,0.36,1) both;
}
.cph-1{ animation-delay:.08s !important; } .cph-2{ animation-delay:.18s !important; }
.cph-3{ animation-delay:.28s !important; } .cph-4{ animation-delay:.38s !important; }
@keyframes ks-cover-in{
  from{ opacity:0; scale:.72; translate:0px 28px; }
  to  { opacity:1; scale:1;   translate:0px 0px;  }
}

/* ─── REEL EDGE VIGNETTES — light fades at left/right edges ─── */
.ks-reel__sticky::before,
.ks-reel__sticky::after{
  content:""; position:absolute; top:0; bottom:0; width:min(11vw,100px); z-index:11; pointer-events:none;
}
.ks-reel__sticky::before{
  left:0;
  background:linear-gradient(90deg,var(--bg-tint,rgba(248,243,236,.95)) 30%,transparent);
}
.ks-reel__sticky::after{
  right:0;
  background:linear-gradient(270deg,var(--bg-tint,rgba(248,243,236,.95)) 30%,transparent);
}

/* ─── REDUCED MOTION: flatten everything ─── */
@media (prefers-reduced-motion:reduce){
  .ks-cluster .obj:not(.scatter-in){ opacity:1; scale:1; translate:0 0; transition:none !important; }
  .ks-cluster .obj{ transition:none; }
  .ks-cluster .obj.ks-front{ transition:none !important; }
  .ks-panel{ transform:none; transition:none; }
  #ks-maptrail{ display:none; }
  .ks-cover__cluster .ks-cover__ph{ animation:none; }
  .ks-reel__sticky::before,.ks-reel__sticky::after{ display:none; }
}

/* ============================================================
   v3 — real printed decor · adaptive video · scroll zoom · layouts
   ============================================================ */

/* ---- printed botanical decor (rasterised hand-stamped PNGs) ---- */
img.ks-leaf{
  position:absolute; z-index:6; pointer-events:none; display:block;
  width:auto; height:auto; user-select:none;
  filter:drop-shadow(0 8px 12px rgba(20,17,15,.10));
  transform-origin:center bottom;
  animation:ksLeafSway 9s ease-in-out infinite alternate;
}
img.ks-leaf.no-sway{ animation:none; }
@keyframes ksLeafSway{ from{ rotate:var(--lr0,-3deg); } to{ rotate:var(--lr1,3deg); } }
img.ks-leaf:nth-of-type(even){ animation-duration:12s; animation-delay:-3s; }
.ks-cover__cluster img.ks-leaf{ z-index:1; }

/* parallax drift: leaves ride the panel offset for depth */
img.ks-leaf{ translate:calc(var(--poff,0) * 12px) calc(var(--poff,0) * -5px); }
.ks-cover__cluster img.ks-leaf{ translate:none; }

/* ---- adaptive film reel: orientation decided in JS ---- */
.ks-panel--video{ flex-basis:auto; }
.ks-vreel{ width:min(56vw,340px); aspect-ratio:9/16; }   /* default until metadata */
.ks-vreel.is-tall{ width:min(56vw,346px); aspect-ratio:9/16; }
.ks-vreel.is-wide{ width:min(84vw,780px); aspect-ratio:16/9; }
.ks-vreel.is-wide{ padding:14px; }
.ks-vreel.is-wide .ks-vreel__label{ bottom:-1.7rem; }

/* ---- proximity ZOOM: content swells as its panel hits centre ---- */
.ks-panel{ --pprox:.55; --poff:0; }
.ks-panel--single .ks-single,
.ks-panel--video  .ks-vreel,
.ks-panel--quote  .ks-quote,
.ks-panel--intro  .ks-intro,
.ks-panel--cluster .ks-cluster{
  scale:calc(.9 + .12 * var(--pprox));
  transition:scale .45s var(--ease);
}
@media (prefers-reduced-motion:reduce){
  .ks-panel--single .ks-single,.ks-panel--video .ks-vreel,.ks-panel--quote .ks-quote,
  .ks-panel--intro .ks-intro,.ks-panel--cluster .ks-cluster{ scale:1 !important; }
}

/* ---- slow ken-burns on hero singles while the reel is live ---- */
@keyframes ksKen{ from{ scale:1.001; } to{ scale:1.07; } }
.ks-reel.in .ks-single img{ animation:ksKen 16s ease-in-out infinite alternate; }
@media (prefers-reduced-motion:reduce){ .ks-reel.in .ks-single img{ animation:none; } }

/* =========================================================
   CLUSTER LAYOUT VARIANTS — each engineered with gaps so
   photos kiss at the corners but never bury faces.
   Children are plain `.obj` figures; position set by nth-child.
   ========================================================= */
.ks-cluster .obj{ overflow:visible; }
.ks-cluster .obj img{ width:100%; height:100%; object-fit:cover; }

/* shared: drop pos-* dependence inside variant clusters */
.ks-cluster--gallery .obj,.ks-cluster--cascade .obj,.ks-cluster--filmstrip .obj,
.ks-cluster--triptych .obj,.ks-cluster--mosaic .obj{ position:absolute; }

/* A · GALLERY WALL — neat 2×2, tiny tilts, clear gutters */
.ks-cluster--gallery{ height:min(76vh,650px); }
.ks-cluster--gallery .obj:nth-child(1){ left:1%;  top:3%;  width:45%; height:47%; rotate:-2.4deg; z-index:2; }
.ks-cluster--gallery .obj:nth-child(2){ left:53%; top:0;   width:45%; height:43%; rotate:1.8deg;  z-index:3; }
.ks-cluster--gallery .obj:nth-child(3){ left:3%;  top:54%; width:43%; height:43%; rotate:1.6deg;  z-index:4; }
.ks-cluster--gallery .obj:nth-child(4){ left:54%; top:49%; width:44%; height:48%; rotate:-2deg;   z-index:5; }

/* B · CASCADE — diagonal staircase, corner overlaps only */
.ks-cluster--cascade{ height:min(78vh,660px); }
.ks-cluster--cascade .obj:nth-child(1){ left:0;   top:1%;  width:42%; height:54%; rotate:-3deg;  z-index:2; }
.ks-cluster--cascade .obj:nth-child(2){ left:31%; top:23%; width:41%; height:55%; rotate:2.2deg; z-index:3; }
.ks-cluster--cascade .obj:nth-child(3){ left:61%; top:45%; width:39%; height:53%; rotate:-1.8deg;z-index:4; }

/* C · FILMSTRIP — taped horizontal row of equal frames */
.ks-cluster--filmstrip{ height:min(64vh,520px); }
.ks-cluster--filmstrip .obj{ top:14%; height:72%; width:25.5%; }
.ks-cluster--filmstrip .obj:nth-child(1){ left:0;     rotate:-1.6deg; z-index:2; }
.ks-cluster--filmstrip .obj:nth-child(2){ left:25%;   rotate:1.4deg;  z-index:3; }
.ks-cluster--filmstrip .obj:nth-child(3){ left:50%;   rotate:-1.2deg; z-index:2; }
.ks-cluster--filmstrip .obj:nth-child(4){ left:75%;   rotate:1.6deg;  z-index:3; }

/* D · TRIPTYCH — three talls, generous gutters */
.ks-cluster--triptych{ height:min(80vh,680px); }
.ks-cluster--triptych .obj{ top:6%; height:86%; width:30%; }
.ks-cluster--triptych .obj:nth-child(1){ left:1%;  rotate:-2.2deg; top:9%; z-index:2; }
.ks-cluster--triptych .obj:nth-child(2){ left:35%; rotate:1.4deg;  top:0;  height:92%; z-index:4; }
.ks-cluster--triptych .obj:nth-child(3){ left:69%; rotate:-1.6deg; top:9%; z-index:3; }

/* E · MOSAIC — one hero + two stacked, finale spread */
.ks-cluster--mosaic{ height:min(80vh,680px); }
.ks-cluster--mosaic .obj:nth-child(1){ left:0;   top:4%;  width:54%; height:90%; rotate:-2deg;  z-index:2; }
.ks-cluster--mosaic .obj:nth-child(2){ left:58%; top:2%;  width:41%; height:44%; rotate:1.8deg; z-index:3; }
.ks-cluster--mosaic .obj:nth-child(3){ left:58%; top:52%; width:41%; height:45%; rotate:-1.6deg;z-index:4; }

@media (max-width:760px){
  .ks-cluster--gallery,.ks-cluster--cascade,.ks-cluster--triptych,.ks-cluster--mosaic,.ks-cluster--filmstrip{ height:62vh; }
}
