/* ─────────────────────────────────────────────────────────────
   rahgoddess · rooms
   One block per room, in the order they appear.
   ───────────────────────────────────────────────────────────── */

/* ── I. Ouverture ─────────────────────────────────────────── */
#ouverture { display: grid; place-items: center; text-align: center; color: var(--champagne); }
.ouv-inner { padding: var(--gutter); }
.ouv-kicker { font-family: var(--mono); font-size: .7rem; letter-spacing: .35em; text-transform: uppercase; opacity: .7; }
/* The headline lives in a box as tall as its tallest word (measured in ouverture.js),
   so the lines above and below hold still while the word changes. It wraps only
   between "Elle est" and the word, never inside either. */
.ouv-line {
  font-variation-settings: var(--display-opsz); font-size: clamp(3.4rem, 12vw, 13rem); font-weight: var(--display-weight); line-height: .9; margin: .2em 0;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; align-content: center;
  column-gap: .26em; padding-block: .12em;
}
.ouv-word {
  display: inline-block; font-style: italic; color: var(--rose);
  transition: filter .6s var(--ease-silk), opacity .6s var(--ease-silk), transform .6s var(--ease-silk), letter-spacing .9s var(--ease-silk);
}
.ouv-word.out { filter: blur(18px); opacity: 0; transform: translateY(.15em) scale(1.08); letter-spacing: .2em; }
.ouv-sub { max-width: 30ch; margin: 1.5rem auto 0; font-size: 1.35em; font-style: italic; opacity: .85; }
.ouv-scroll {
  position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%);
  display: grid; justify-items: center; gap: .6rem;
  font-family: var(--mono); font-size: .6rem; letter-spacing: .4em; text-transform: uppercase; opacity: .6;
}
.ouv-scroll i { width: 1px; height: 60px; background: linear-gradient(currentColor, transparent); animation: drip 2.4s infinite var(--ease-silk); transform-origin: top; }
@media (max-height: 640px) { .ouv-scroll { display: none; } }   /* no room for it beneath the headline box */
@keyframes drip { 0% { transform: scaleY(0); } 60% { transform: scaleY(1); opacity: 1; } 100% { transform: scaleY(1); opacity: 0; } }

/* ── II. Le Manifeste ─────────────────────────────────────── */
#manifeste { height: 340vh; }
.manifeste-text { font-variation-settings: var(--display-opsz);
  max-width: 24ch; margin: 0; padding: 0 var(--gutter);
  font-family: var(--display); font-weight: var(--display-weight); font-size: clamp(1.6rem, min(4.6vw, 5.4vh), 4.6rem); line-height: 1.08; letter-spacing: -.01em;
}
.manifeste-text .w { opacity: .12; transition: opacity .35s, color .35s; }
.manifeste-text .w.lit { opacity: 1; }
.manifeste-text .w.hot { color: var(--crimson); font-style: italic; }

/* ── III. Paris ───────────────────────────────────────────── */
#paris { min-height: 140vh; color: var(--champagne); }
.paris-clock {
  position: absolute; top: var(--gutter); left: var(--gutter);
  font-family: var(--mono); font-size: .7rem; letter-spacing: .25em; text-transform: uppercase; color: var(--gold);
}
.knockout { position: relative; }
.knockout canvas { width: 100%; height: 100%; }
.paris-knock { height: 46vh; margin-top: 12vh; }
.knock-word { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.tour {
  position: absolute; right: 6vw; bottom: 0; height: 88vh; width: auto; color: var(--gold);
  filter: drop-shadow(0 0 14px rgba(212, 166, 74, .45));
}
.tour-lines path { stroke-dasharray: var(--len); stroke-dashoffset: calc(var(--len) * (1 - var(--draw, 0))); }
.tour-sparkles circle { fill: #fff; animation: twinkle .5s infinite alternate; }
@keyframes twinkle { from { opacity: 0; } to { opacity: 1; } }
.paris-copy { position: relative; padding: 0 var(--gutter) calc(var(--gutter) * 3); max-width: 34rem; }
.paris-copy h2 { font-size: clamp(3rem, 7vw, 6.5rem); }
.paris-copy h2 em { color: var(--gold); }
.paris-copy p { font-size: 1.2em; font-style: italic; opacity: .85; }
.paris-copy .pill:hover { background: var(--gold); }

/* ── IV. La Bibliothèque ──────────────────────────────────── */
#bibliotheque { padding-bottom: calc(var(--gutter) * 3); }
.shelf {
  display: flex; align-items: flex-end; gap: 6px;
  height: 340px; margin: 2rem var(--gutter) 0; padding: 0 12px;
  border-bottom: 14px solid #3a2016; box-shadow: 0 18px 30px -12px rgba(0,0,0,.4);
  overflow-x: auto; scrollbar-width: none;
}
.book {
  flex: 0 0 auto; width: clamp(34px, 3.3vw, 60px); height: var(--h);   /* nineteen spines and the bookend fit a desktop shelf */
  background:
    linear-gradient(90deg, rgba(0,0,0,.25), transparent 18%, rgba(255,255,255,.12) 50%, transparent 82%, rgba(0,0,0,.3)),
    var(--c);
  color: color-mix(in srgb, var(--c) 20%, #fff);
  writing-mode: vertical-rl; transform-origin: bottom center;
  font-family: var(--display); font-weight: var(--display-weight); font-size: 1.05rem; letter-spacing: .08em;
  border-radius: 3px 3px 0 0;
  transition: transform .6s var(--ease-silk), box-shadow .6s;
}
.book:nth-child(4n+1) { color: #fff; }
.book[style*="#e8d5b0"], .book[style*="#f2a7b5"], .book[style*="#d4a64a"], .book.light { color: #241418; }
.book:hover { transform: translateY(-14px) rotate(-2deg); }
.book.pulled { transform: translateY(-46px) rotate(-6deg); box-shadow: 0 30px 40px -20px rgba(0,0,0,.5); }

/* The bookend: a brass Cavalier holding up the end of the shelf */
.bookend { flex: 0 0 auto; align-self: flex-end; width: clamp(96px, 12.5vw, 150px); margin-left: 8px; transform-origin: bottom center; transition: transform .5s var(--ease-silk); }
.bookend svg { display: block; width: 100%; height: auto; overflow: visible; filter: drop-shadow(2px 6px 6px rgba(0,0,0,.25)); }
.bookend:hover { transform: rotate(-4deg); }
.bookend.wiggle { animation: wiggle .6s var(--ease-silk); }
@keyframes wiggle { 25% { transform: rotate(-9deg); } 55% { transform: rotate(6deg); } 80% { transform: rotate(-3deg); } }
.bookend .glint { animation: glint 7s 3s infinite; }      /* a passing gleam: the only hint she does anything */
@keyframes glint { 0%, 88% { opacity: 0; transform: skewX(-18deg) translateX(0); } 90% { opacity: .55; } 100% { opacity: 0; transform: skewX(-18deg) translateX(140px); } }

/* On phones the extra books wait behind the bookend until she's tapped */
@media (max-width: 700px) {
  .shelf:not(.revealed) .book.extra { display: none; }
  .shelf.revealed .book.extra { animation: bookIn .7s var(--ease-silk) both; }
}
.open-book {
  margin: 3rem var(--gutter) 0; max-width: 48rem;
  animation: bookIn 1s var(--ease-silk);
}
.open-book blockquote { font-variation-settings: var(--display-opsz); margin: 0; font-family: var(--display); font-weight: var(--display-weight); font-style: italic; font-size: clamp(1.8rem, 3.6vw, 3.2rem); line-height: 1.1; }
.open-book blockquote::before { content: "« "; color: var(--oxblood); }
.open-book blockquote::after { content: " »"; color: var(--oxblood); }
.open-book figcaption { font-family: var(--mono); font-size: .75rem; letter-spacing: .25em; text-transform: uppercase; margin-top: 1rem; color: var(--oxblood); display: flex; align-items: center; gap: .8rem; }
.ebook-link {
  display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
  color: var(--oxblood); border: 1px solid currentColor; transition: background .3s, color .3s, transform .3s var(--ease-silk);
}
.ebook-link[hidden] { display: none; }
.ebook-link:hover, .ebook-link:focus-visible { background: var(--oxblood); color: var(--champagne); transform: rotate(-8deg) scale(1.08); }
@keyframes bookIn { from { opacity: 0; transform: translateY(20px); filter: blur(8px); } }
.typewriter { position: relative; margin: 4rem var(--gutter) 0; max-width: 48rem; }
.typewriter label { font-family: var(--display); font-weight: var(--display-weight); font-size: 1.6rem; display: block; }
.typewriter label span { display: block; font-family: var(--serif); font-style: italic; font-size: 1rem; opacity: .7; }
.typewriter input {
  width: 100%; margin-top: 1rem; padding: .4em 0;
  font-family: var(--mono); font-size: clamp(1.1rem, 2.4vw, 1.8rem); color: inherit;
  background: none; border: 0; border-bottom: 1px solid currentColor; outline: none; caret-color: var(--crimson);
}
.tw-ghosts { position: absolute; left: 0; right: 0; bottom: 3rem; height: 0; pointer-events: none; }
.tw-ghosts span {
  position: absolute; bottom: 0; font-family: var(--mono); font-size: 1.4rem; white-space: nowrap;
  animation: inkRise 9s var(--ease-silk) forwards;
}
@keyframes inkRise {
  30% { transform: translateY(-50px) scale(1.05); filter: blur(0); opacity: 1; }
  to { transform: translateY(-240px) scale(1.4); filter: blur(16px); opacity: 0; }
}
/* the water: everything written lately keeps surfacing and sinking again */
.ink-pool { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.ink-pool span {
  position: absolute; white-space: nowrap; max-width: 90vw; overflow: hidden; text-overflow: ellipsis;
  font-family: var(--display); font-weight: var(--display-weight); font-style: italic; color: var(--oxblood);
  opacity: 0; animation: inkForm var(--dur, 14s) var(--ease-silk) forwards;
}
@keyframes inkForm {
  0%   { opacity: 0; filter: blur(18px); transform: translateY(14px) scale(1.12); letter-spacing: .25em; }
  25%  { opacity: var(--peak, .4); filter: blur(0); transform: none; letter-spacing: .02em; }
  70%  { opacity: var(--peak, .4); filter: blur(.5px); transform: translateY(-10px); }
  100% { opacity: 0; filter: blur(20px); transform: translateY(-40px) scale(.96); letter-spacing: .15em; }
}

/* ── V. Les Écrans ────────────────────────────────────────── */
#ecrans { color: #e9fff6; padding-bottom: calc(var(--gutter) * 3); }
#ecrans .room-num { color: #7cf2c8; }
.tv-wall {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: clamp(12px, 2vw, 28px);
  padding: 0 var(--gutter);
}
.tv {
  position: relative; aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: 22px / 26px; background: #111;
  box-shadow: inset 0 0 0 10px #1c1c1c, inset 0 0 40px 10px #000, 0 20px 50px -20px rgba(124, 242, 200, .25);
  transition: transform .5s var(--ease-silk), box-shadow .5s;
}
.tv canvas { position: absolute; inset: 10px; width: calc(100% - 20px); height: calc(100% - 20px); border-radius: 16px / 20px; filter: saturate(1.3) contrast(1.1); }
.tv::after {
  content: ""; position: absolute; inset: 10px; border-radius: 16px / 20px; pointer-events: none;
  background: repeating-linear-gradient(transparent 0 2px, rgba(0,0,0,.28) 2px 3px), radial-gradient(ellipse, transparent 55%, rgba(0,0,0,.65));
}
.tv::before {
  content: attr(data-label); position: absolute; left: 22px; bottom: 18px; z-index: 2;
  font-family: var(--mono); font-size: .75rem; letter-spacing: .3em; color: #7cf2c8; text-shadow: 0 0 8px #7cf2c8;
}
.tv:hover { transform: scale(1.03) rotate(-.6deg); box-shadow: inset 0 0 0 10px #222, inset 0 0 40px 10px #000, 0 30px 80px -20px rgba(124, 242, 200, .5); }
.tv.on-air { position: fixed; inset: 6vh 6vw; z-index: 85; aspect-ratio: auto; transform: none; }
@media (max-width: 700px) { .tv.on-air::before { display: none; } }   /* the card names it; the label would run under the buttons */
.tv-scrim { position: fixed; inset: 0; z-index: 84; background: rgba(0,0,0,.85); animation: fadeIn .4s; }
/* the séance: clips play over the on-air set's screen, under their own scanlines.
   They live outside the TV (a <button>): Safari won't reliably deliver taps to a frame inside one. */
.tv-media {
  position: fixed; inset: calc(6vh + 10px) calc(6vw + 10px); z-index: 86;
  border: 0; border-radius: 16px / 20px; overflow: hidden; background: #000; object-fit: contain; pointer-events: none;
}
div.tv-media::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(transparent 0 2px, rgba(0,0,0,.22) 2px 3px), radial-gradient(ellipse, transparent 60%, rgba(0,0,0,.5));
}
.tv-media iframe { width: 100%; height: 100%; border: 0; pointer-events: auto; }   /* YouTube may need a tap to start */
.tv-media.off { visibility: hidden; }   /* between clips the séance's player waits, hidden but alive */
.tv-media.off iframe { pointer-events: none; }
.tv-media::cue { font-family: var(--serif); font-size: 1.25em; background: rgba(0, 0, 0, .65); color: #f5e6c8; }
.tv-hint { position: fixed; right: calc(6vw + 18px); bottom: calc(6vh + 16px); z-index: 87; display: flex; gap: 8px; }   /* just inside the on-air set's corner */
.tv-hint button {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .15em; text-transform: uppercase;
  color: #7cf2c8; border: 1px solid currentColor; border-radius: 999px; padding: .45em 1em; background: rgba(0,0,0,.55);
}
.tv-hint button:hover { background: #7cf2c8; color: #000; }
@keyframes fadeIn { from { opacity: 0; } }

/* ── VI. La Table ─────────────────────────────────────────── */
#table { color: var(--champagne); display: grid; align-items: center; }
#table > canvas.seeds { z-index: 3; pointer-events: none; }
.table-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); align-items: center; gap: var(--gutter);
  padding: calc(var(--gutter) * 2) var(--gutter);
}
.menu-kicker { font-family: var(--mono); font-size: .7rem; letter-spacing: .3em; text-transform: uppercase; color: var(--gold); }
.menu h2 { font-size: clamp(3rem, 7vw, 6.5rem); }
.menu h2 em { color: var(--gold); }
.menu dl { margin: 2rem 0 0; display: grid; grid-template-columns: auto 1fr; gap: .7rem 1.4rem; }
.menu dt { font-family: var(--display); font-weight: var(--display-weight); font-style: italic; color: var(--gold); }
.menu dd { margin: 0; border-bottom: 1px dotted rgba(245, 230, 200, .3); padding-bottom: .3rem; }
.grenade-stage { display: grid; justify-items: center; }
.grenade { width: min(70vw, 380px); cursor: inherit; transition: transform .8s var(--ease-silk); filter: drop-shadow(0 30px 40px rgba(0,0,0,.5)); }
.grenade:hover { transform: rotate(-6deg) scale(1.04); animation: wobble 1.2s infinite; }
@keyframes wobble { 0%, 100% { transform: rotate(-6deg) scale(1.04); } 50% { transform: rotate(4deg) scale(1.06); } }
.grenade.burst { transform: scale(0); opacity: 0; transition: transform .25s var(--ease-snap), opacity .25s; animation: none; }
.grenade-hint { font-family: var(--mono); font-size: .65rem; letter-spacing: .3em; text-transform: uppercase; opacity: .6; }

/* ── VII. Les Forces ──────────────────────────────────────── */
#forces { height: 520vh; color: var(--champagne); transition: color 1.2s var(--ease-silk); }
#forces[data-el="2"] { color: #3a1410; }                       /* dark ink on the sunlit beach */
#forces[data-el="2"] .pulse-btn { color: #3a1410; border-color: #3a1410; }
#forces > canvas.forces-gl { position: sticky; top: 0; height: 100vh; height: 100svh; margin-bottom: -100vh; margin-bottom: -100svh; z-index: -1; }
.forces-sticky { align-content: center; justify-items: center; gap: 2rem; text-align: center; }
.elements { list-style: none; margin: 0; padding: 0; display: grid; gap: .1em; }
.elements li { font-variation-settings: var(--display-opsz);
  font-family: var(--display); font-weight: var(--display-weight); font-size: clamp(2.4rem, min(10vw, 10vh), 9rem); line-height: .95;
  opacity: .14; filter: blur(3px); transition: opacity .8s, filter .8s, letter-spacing 1.2s var(--ease-silk);
}
.elements li span { display: block; font-family: var(--serif); font-style: italic; font-size: 1.1rem; letter-spacing: .1em; height: 0; overflow: hidden; transition: height .6s; }
.elements li.on { opacity: 1; filter: none; letter-spacing: .06em; }
.elements li.on span { height: 1.6em; }
.moon-phase { font-family: var(--mono); font-size: .7rem; letter-spacing: .25em; text-transform: uppercase; opacity: .7; margin: 0; }
.pulse-btn {
  width: 120px; height: 120px; border-radius: 50%;
  border: 1px solid var(--crimson); color: var(--champagne);
  font-family: var(--display); font-weight: var(--display-weight); font-style: italic; font-size: 1.2rem;
  transition: transform .2s, background .4s;
  touch-action: none; user-select: none; -webkit-user-select: none;
}
.pulse-btn span { display: block; font-family: var(--mono); font-style: normal; font-size: .55rem; letter-spacing: .15em; text-transform: uppercase; opacity: .7; }
.pulse-btn.held { background: var(--crimson); transform: scale(1.15); }

/* ── VIII. La Musique ─────────────────────────────────────── */
#musique { color: var(--blush); touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.musique-copy { position: absolute; left: var(--gutter); bottom: calc(var(--gutter) + 80px); max-width: 30rem; pointer-events: none; }
.musique-copy h2 { font-size: clamp(3rem, 9vw, 8rem); font-style: italic; }
.musique-copy p { font-size: 1.15em; opacity: .85; }
.sonata-row { display: inline-flex; align-items: center; gap: .9rem; margin-top: .4rem; }
.sonata { pointer-events: auto; flex: none; border-radius: 50%; }
.sonata-label { font-family: var(--display); font-weight: var(--display-weight); font-style: italic; font-size: 1.05rem; }
.sonata svg { display: block; flex: none; width: 46px; height: 46px; padding: 12px; border-radius: 50%; border: 1px solid currentColor; transition: background .3s, color .3s, transform .4s var(--ease-silk); }
.sonata:hover svg { background: var(--rose); color: #12071c; transform: scale(1.08); }
.sonata-label small { display: block; font-family: var(--mono); font-style: normal; font-size: .58rem; letter-spacing: .2em; text-transform: uppercase; opacity: .65; }
.sonata .i-stop, .sonata.playing .i-play { display: none; }
.sonata.playing .i-stop { display: inline; }
.sonata.playing svg { background: var(--rose); color: #12071c; animation: rosepulse 1.6s infinite; }

/* ── IX. Les Chiens ───────────────────────────────────────── */
#chiens { min-height: 100vh; min-height: 100svh; --ground: 18%; }
.good-count { padding: 0 var(--gutter); font-family: var(--mono); font-size: .75rem; letter-spacing: .2em; text-transform: uppercase; }
.good-count span { font-family: var(--display); font-weight: var(--display-weight); font-size: 3rem; letter-spacing: 0; vertical-align: middle; margin-right: .3rem; }
.parade { position: absolute; left: 0; right: 0; bottom: 0; height: 50vh; height: 50svh; pointer-events: none; }
/* the ground: every dog's feet land on or above this line, never below */
.parade::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: var(--ground); border-top: 1px solid rgba(90, 15, 26, .35); background: linear-gradient(rgba(90, 15, 26, .12), rgba(90, 15, 26, .3)); z-index: 0; }
.dog { position: absolute; bottom: calc(var(--ground) + var(--row, 0) * 7%); pointer-events: auto; cursor: inherit; will-change: transform; z-index: calc(10 - var(--row, 0)); }
.dog svg { transform: scale(calc(1 - var(--row, 0) * .12)); transform-origin: bottom center; }
.dog svg { display: block; overflow: visible; }
.dog .leg { transform-box: fill-box; transform-origin: top center; animation: trot .36s infinite alternate ease-in-out; }
.dog .leg.b { animation-direction: alternate-reverse; }
.dog .tail { transform-box: view-box; animation: wag .25s infinite alternate ease-in-out; }   /* origin set per breed */
.dog .bob { animation: bob .36s infinite alternate ease-in-out; }
.dog.sit .leg, .dog.sit .bob { animation-play-state: paused; }
.dog.sit .tail { animation-duration: .1s; }
@keyframes trot { from { transform: rotate(18deg); } to { transform: rotate(-18deg); } }
@keyframes wag { from { transform: rotate(-20deg); } to { transform: rotate(25deg); } }
@keyframes bob { from { transform: translateY(0); } to { transform: translateY(-3px); } }
.heart { position: absolute; pointer-events: none; font-size: 1.6rem; color: var(--crimson); animation: heartUp 1.4s var(--ease-silk) forwards; }
@keyframes heartUp { to { transform: translate(var(--dx, 0), -120px) scale(1.6) rotate(var(--rot, 0deg)); opacity: 0; } }
.paws { position: absolute; inset: 0; pointer-events: none; z-index: -1; }
.paws span { position: absolute; font-size: 22px; color: var(--oxblood); opacity: .35; transform: translate(-50%, -50%) rotate(var(--r)); animation: pawFade 3s forwards; }
@keyframes pawFade { to { opacity: 0; } }

/* ── X. Finale ────────────────────────────────────────────── */
#finale { display: grid; place-items: center; text-align: center; color: var(--champagne); }
.finale-inner h2 { font-size: clamp(3.4rem, 11vw, 11rem); }
.finale-inner h2 em { color: var(--rose); }
.seal {
  margin: 3rem auto 0; display: grid; place-items: center;
  width: 130px; height: 130px;
  border-radius: 48% 52% 50% 46% / 50% 46% 54% 50%;
  background: radial-gradient(circle at 35% 30%, #e0465f, var(--crimson) 40%, #6d1020 85%);
  box-shadow: inset -6px -10px 18px rgba(0,0,0,.45), inset 6px 8px 14px rgba(255,255,255,.18), 0 14px 30px rgba(0,0,0,.5);
  transition: transform .3s var(--ease-snap);
}
.seal span {
  width: 84px; height: 84px; border-radius: 50%; display: grid; place-items: center;
  border: 2px solid rgba(0,0,0,.25); box-shadow: inset 0 0 0 4px rgba(255,255,255,.08);
  font-family: var(--display); font-weight: var(--display-weight); font-style: italic; font-size: 3rem; color: #5a0f1a; text-shadow: 1px 1px 0 rgba(255,255,255,.25);
}
.seal:hover { transform: rotate(-8deg) scale(1.05); }
.seal.stamp { transform: scale(.82) rotate(4deg); }
.seal-note { font-family: var(--mono); font-size: .65rem; letter-spacing: .3em; text-transform: uppercase; opacity: .6; margin-top: 1.2rem; }

/* ── Small screens ────────────────────────────────────────── */
@media (max-width: 700px) {
  .tour { height: 56vh; right: -4vw; opacity: .7; }
  .paris-knock { height: 28vh; }
  .shelf { height: 260px; }
  .musique-copy { bottom: calc(var(--gutter) + 90px); }
  .ouv-scroll { display: none; }
}
