/* justbible.app/welcome: a lamp, a path, and the night turning to day, driven by the scroll.
   The films' design (gold line art on a dark ground, Fraunces headlines, verses with a gold rule)
   on the app's own surfaces (legal.css: #f9f9f9 light, #0e1217 dark), with the same one-slide-
   over-a-scene layout as the kmklabs.app landing page. The stage is scene.js.

   Type: Fraunces (SIL Open Font License 1.1, fonts/OFL.txt), two static instances self-hosted in
   /fonts/ because the site's CSP allows no outside fonts. The headline cut is opsz 144 / SOFT 40,
   the verse cut opsz 48 / SOFT 60, the same settings the archived Sail page used. */

/* ── Tokens: light by default; dark when the app's choice ('bible:theme') or the device says so ── */
:root {
  --bg:#f9f9f9; --text:#0d0d0d; --dim:#5d5d5d; --ink:#c98a3c; --rule:rgba(201,138,60,.28);
  --btn-bg:#0d0d0d; --btn-fg:#f9f9f9; color-scheme:light;
}
@media (prefers-color-scheme:dark) {
  :root:not([data-theme="light"]) {
    --bg:#0e1217; --text:#ececec; --dim:#a8a8a8; --ink:#edb868; --rule:rgba(237,184,104,.22);
    --btn-bg:#edb868; --btn-fg:#0e1217; color-scheme:dark;
  }
}
:root[data-theme="dark"] {
  --bg:#0e1217; --text:#ececec; --dim:#a8a8a8; --ink:#edb868; --rule:rgba(237,184,104,.22);
  --btn-bg:#edb868; --btn-fg:#0e1217; color-scheme:dark;
}

@font-face { font-family:'Fraunces'; font-style:normal; font-weight:600; font-display:swap; src:url(/fonts/fraunces-600.woff2) format('woff2') }
@font-face { font-family:'Fraunces'; font-style:italic; font-weight:400; font-display:swap; src:url(/fonts/fraunces-italic-400.woff2) format('woff2') }
:root { --serif:'Fraunces','Iowan Old Style','Palatino Linotype',Palatino,Georgia,'Times New Roman',serif }

* { box-sizing:border-box }
html { background:var(--bg); scroll-behavior:smooth; -webkit-text-size-adjust:100% }
::selection { background:var(--ink); color:var(--bg) }
:focus-visible { outline:2px solid var(--ink); outline-offset:3px; border-radius:4px }
body { margin:0; background:var(--bg); color:var(--text); font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif; line-height:1.55; -webkit-font-smoothing:antialiased }
a { color:var(--ink) }

/* ── The scene: fixed behind everything, covering the viewport, drawn in the ink ── */
.scene { position:fixed; inset:0; z-index:0; color:var(--ink); pointer-events:none }
.stage { position:absolute; inset:0; width:100%; height:100%; display:block }

/* The continuous motion, on its own clock. */
.stars circle { animation:twinkle 5s ease-in-out infinite }
.stars circle:nth-child(2n) { animation-delay:1.7s } .stars circle:nth-child(3n) { animation-delay:3.1s } .stars circle:nth-child(5n) { animation-duration:7s }
@keyframes twinkle { 0%,100% { opacity:1 } 50% { opacity:.3 } }
/* The lamp draws itself in once as the page opens, post first, then the lantern. */
.lamp-lines path { stroke-dasharray:100; stroke-dashoffset:100; animation:drawon 1.3s cubic-bezier(.33,1,.68,1) both }
.lamp-lines .post { animation-delay:.25s } .lamp-lines .head { animation-delay:.85s }
@keyframes drawon { to { stroke-dashoffset:0 } }
.flame-flick { animation:flicker 1.7s ease-in-out infinite }
@keyframes flicker { 0%,100% { opacity:1; transform:translateY(0) } 35% { opacity:.85; transform:translateY(1px) } 70% { opacity:.95; transform:translateY(-1px) } }
.fly { animation:fly 4s ease-in-out infinite }
@keyframes fly { 0%,100% { opacity:.15; transform:translate(0,0) } 50% { opacity:1; transform:translate(6px,-8px) } }
/* One streak, then a long dark: the dash (18 of 100) runs the path's length in under a second. */
.meteor path { stroke-dasharray:18 82; animation:meteor 16s linear infinite }
@keyframes meteor { 0% { stroke-dashoffset:18; opacity:1 } 5% { stroke-dashoffset:-100; opacity:1 } 5.01%,100% { stroke-dashoffset:-100; opacity:0 } }
.birds-glide { animation:glide 40s ease-in-out infinite alternate }
@keyframes glide { from { transform:translateX(-40px) } to { transform:translateX(40px) } }

/* ── Header: the brand home, and light or dark, over a soft band of the page colour ── */
.top { position:fixed; top:0; left:0; right:0; z-index:3; display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:.7rem clamp(1rem, 4vw, 2.5rem); padding-top:max(.7rem, env(safe-area-inset-top));
  background:linear-gradient(to bottom, color-mix(in srgb, var(--bg) 88%, transparent), transparent) }
.top { transition:background .25s, box-shadow .25s }
.top.solid { background:var(--bg); box-shadow:0 1px 0 var(--rule) }
.brand { display:flex; align-items:center; gap:.6rem; color:var(--text); text-decoration:none; font-weight:700; letter-spacing:-.01em }
.brand img { display:block; width:28px; height:28px; border-radius:7px }
.theme { width:40px; height:40px; border-radius:999px; border:0; background:transparent; color:var(--dim); display:inline-flex; align-items:center; justify-content:center; cursor:pointer; transition:color .2s, background .2s, transform .15s }
.theme:hover { color:var(--text); background:color-mix(in srgb, var(--text) 8%, transparent) }
.theme:active { transform:scale(.95) }
.theme svg { width:18px; height:18px }
:root[data-theme="dark"] .ico-moon { display:none }
:root:not([data-theme="dark"]) .ico-sun { display:none }

/* ── The stops: one screen each, the words on the side the scene is not ── */
.walk { position:relative; z-index:1 }
/* The words sit a little above centre so the far line (two thirds down the stage) runs under them, not through them. */
.stop { min-height:100svh; display:grid; align-items:center; padding:5rem clamp(1.25rem, 6vw, 6rem) calc(4rem + 12vh) }
.stop.right { grid-template-columns:1fr minmax(0, 34rem) }
.stop.hero { grid-template-columns:1fr minmax(0, 44rem) }
.stop.right .words { grid-column:2 }
/* The left stops start past the lamp, which stands at the near left of the stage. */
.stop.left { grid-template-columns:clamp(8rem, 14vw, 16rem) minmax(0, 34rem) 1fr }
.stop.left .words { grid-column:2 }
.words { opacity:0; transform:translateY(14px); transition:opacity .9s ease, transform .9s cubic-bezier(.22,1,.36,1) }
.stop.in .words, .frozen .words { opacity:1; transform:none }
/* A soft pool of the page colour behind the words so the stars and the lines never fight the type. */
.words { position:relative; padding:1.5rem clamp(1rem, 2vw, 2rem); border-radius:20px;
  background:radial-gradient(ellipse at center, color-mix(in srgb, var(--bg) 82%, transparent) 0%, color-mix(in srgb, var(--bg) 60%, transparent) 60%, transparent 100%) }

h1, h2, h3 { overflow-wrap:break-word }
h2, h3 { text-wrap:balance }
p, blockquote p { text-wrap:pretty }
h1 { margin:0; font-family:var(--serif); font-weight:600; font-size:clamp(2.6rem, 4.6vw, 4.2rem); letter-spacing:-.02em; line-height:1.02 }
h1 span { display:block }
.gold { color:var(--ink) }
h2 { margin:0 0 1rem; font-family:var(--serif); font-weight:600; font-size:clamp(2rem, 4.2vw, 3.3rem); letter-spacing:-.015em; line-height:1.08 }
.eyebrow { margin:0 0 .6rem; color:var(--ink); letter-spacing:.16em; text-transform:uppercase; font-size:.78rem; font-weight:700 }
.lead { color:var(--text); font-size:clamp(1.1rem, 1.6vw, 1.4rem); margin:1.2rem 0 1.4rem; max-width:28em }
.words p { margin:0 0 .9rem; color:var(--dim); font-size:clamp(1.05rem, 1.25vw, 1.2rem) }
.words p.lead { color:var(--text); margin:1.2rem 0 1.5rem }  /* beats .words p's margin, which left it tight under the headline */
blockquote { margin:1.4rem 0; padding:0 0 0 1rem; border-left:2px solid var(--ink) }
blockquote p { margin:0; color:var(--text); hanging-punctuation:first; font-family:var(--serif); font-style:italic; font-weight:400; font-size:1.15rem }
blockquote cite { display:block; margin-top:.4rem; color:var(--dim); font-style:normal; font-size:.9rem }
.hint { color:var(--dim); font-size:.9rem; opacity:.8; display:inline-flex; align-items:center; gap:.45rem; text-decoration:none; margin-top:.4rem }
.cue { color:var(--ink); animation:cue 2.4s ease-in-out infinite }
@keyframes cue { 0%,100% { transform:translateY(0); opacity:.55 } 50% { transform:translateY(4px); opacity:1 } }

/* The one button: a pill, the ink on the dark ground and the text colour on the light one. */
.btn { display:inline-flex; align-items:center; gap:.5rem; padding:.85rem 1.5rem; border-radius:999px; background:var(--btn-bg); color:var(--btn-fg);
  font-weight:700; font-size:1rem; letter-spacing:.01em; text-decoration:none; transition:transform .15s, opacity .2s }
.btn:hover { opacity:.9 }
.btn:active { transform:scale(.97) }
/* The hero's call: one button, and the film as a quieter link beside it (a play mark and a word). */
.words p.cta { margin:.2rem 0 1rem; display:flex; flex-wrap:wrap; align-items:center; gap:.9rem 1.6rem }
.words p.cta .btn { padding:.75rem 1.35rem; font-size:.98rem }
.play { display:inline-flex; align-items:center; gap:.55rem; color:var(--text); font-weight:600; font-size:.98rem; text-decoration:none; padding:.35rem 0 }
.play svg { color:var(--ink); flex:none; transition:transform .2s }
.play:hover svg { transform:scale(1.08) }
.play:hover { color:var(--ink) }

/* ── Ashore: the app in full, on solid ground over the finished scene ── */
.ashore { position:relative; z-index:2; background:var(--bg); border-top:1px solid var(--rule) }
.about { max-width:74rem; margin:0 auto; scroll-margin-top:1rem; padding:clamp(3.5rem, 8vw, 7rem) clamp(1.25rem, 5vw, 3rem) }
.about + .about { border-top:1px solid var(--rule) }
.about h2 { margin:0 0 .8rem }
.about-lead { color:var(--text); font-size:clamp(1.1rem, 1.5vw, 1.3rem); max-width:44em; margin:0 0 clamp(2rem, 4vw, 3rem) }
.features { list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fit, minmax(17rem, 1fr)); gap:clamp(1.5rem, 3vw, 2.5rem) }
.features h3 { margin:0 0 .4rem; font-family:var(--serif); font-weight:600; font-size:1.2rem; letter-spacing:-.01em; color:var(--text) }
.features p { margin:0; color:var(--dim); font-size:1rem; line-height:1.6 }
.note { margin:clamp(2rem, 4vw, 3rem) 0 0; color:var(--dim); font-size:.95rem; padding-top:1.2rem; border-top:1px solid var(--rule) }
.steps { list-style:none; margin:0; padding:0; display:grid; gap:.7rem; max-width:44em; color:var(--dim); line-height:1.6 }
.steps b { color:var(--text); font-weight:600 }
.after { margin:2.2rem 0 0 }
.credit { max-width:44em; margin:0; color:var(--dim); font-size:.95rem; line-height:1.65 }
.credit b { color:var(--text); font-weight:600 }

/* The film: words beside a portrait player on wide screens, stacked on a phone. */
.film { display:grid; grid-template-columns:minmax(0, 1fr) auto; gap:clamp(2rem, 5vw, 4.5rem); align-items:center }
.film .about-lead { margin-bottom:1.6rem }
.film-frame { justify-self:center }
.film-frame video { display:block; height:min(78vh, 760px); width:auto; aspect-ratio:9 / 16; border-radius:20px; background:#0e1217;
  box-shadow:0 0 0 1px var(--rule), 0 30px 60px -30px rgba(0,0,0,.5) }
@media (max-width:860px) {
  .film { grid-template-columns:1fr }
  /* A phone: the player at most about two thirds of the screen, centred. */
  .film-frame { justify-self:center }
  .film-frame video { height:min(68svh, calc((100vw - 2.3rem) * 16 / 9)); width:auto; max-width:100% }
}

/* Pass it on: Share (where the device has a share sheet), Copy link, and the link itself. */
.btn.ghost { background:transparent; color:var(--text); box-shadow:inset 0 0 0 1px var(--rule) }
.btn.ghost:hover { opacity:1; box-shadow:inset 0 0 0 1px var(--ink) }
button.btn { border:0; font:inherit; font-weight:700; cursor:pointer }
.btn[hidden] { display:none }
.share { display:flex; flex-wrap:wrap; align-items:center; gap:.75rem }
.share-url { flex:1 1 16rem; max-width:24rem; min-width:0; padding:.8rem 1rem; border-radius:999px; border:1px solid var(--rule); background:transparent;
  color:var(--dim); font:inherit; font-size:.95rem }
.share-url:focus { outline:none; border-color:var(--ink); color:var(--text) }
.share-status { min-height:1.5em; margin:.8rem 0 0; color:var(--ink); font-size:.95rem; font-weight:600 }
@media (max-width:760px) { .share-url { flex-basis:100%; max-width:none } }

footer { max-width:74rem; margin:0 auto; padding:2.5rem clamp(1.25rem, 5vw, 3rem) 4rem; color:var(--dim); border-top:1px solid var(--rule); font-size:.9rem; line-height:1.7 }
footer nav { display:flex; flex-wrap:wrap; gap:.3rem 1.1rem; margin-bottom:.5rem }
footer a { color:inherit; text-decoration:none; border-bottom:1px solid var(--rule) }
footer a:hover { border-color:var(--ink) }

/* The hero's lines step in once. */
.reveal { opacity:0; transform:translateY(8px); animation:reveal .8s cubic-bezier(.22,1,.36,1) both; animation-delay:var(--d, 0s) }
@keyframes reveal { to { opacity:1; transform:none } }

/* ── Phones, portrait: the stage is its own 480 x 900 picture above the words, which take the
   lower half on a band of the page colour rather than a soft pool. ── */
@media (max-width:760px) {
  .top { padding:.6rem 1rem; padding-top:max(.6rem, env(safe-area-inset-top)); background:linear-gradient(to bottom, color-mix(in srgb, var(--bg) 94%, transparent) 40%, transparent) }
  .brand { font-size:.95rem }
  .brand img { width:24px; height:24px }
  .stop, .stop.right, .stop.left, .stop.hero { grid-template-columns:1fr; align-items:end; padding:5.5rem 1.15rem 2.5rem }
  .stop.right .words, .stop.left .words { grid-column:1 }
  .words { padding:1.15rem 1.1rem 1.3rem; border-radius:16px;
    background:linear-gradient(to bottom, transparent 0%, color-mix(in srgb, var(--bg) 88%, transparent) 14%, color-mix(in srgb, var(--bg) 95%, transparent) 100%);
    box-shadow:0 -30px 40px -20px color-mix(in srgb, var(--bg) 80%, transparent) }
  h1 { font-size:clamp(1.9rem, 8.8vw, 2.6rem); line-height:1.06 }
  h2 { font-size:clamp(1.75rem, 8vw, 2.3rem) }
  .lead { font-size:1.08rem }
  .words p.lead { margin:1rem 0 1.25rem }
  .words p { font-size:1.02rem; margin-bottom:.7rem }
  blockquote { margin:1.1rem 0 0 }
  blockquote p { font-size:1.05rem }
  .hint { margin-top:.9rem }
  /* One paragraph a stop on a phone: the band stays low, under the scene, and the rest is in the
     sections below. */
  .words p.more { display:none }
  .words p.cta { margin:.4rem 0 .6rem }
  .words p.cta { gap:.8rem 1.4rem }
  .words p.cta .btn { padding:.7rem 1.2rem; font-size:.95rem }
  .play { font-size:.95rem }
  .play svg { width:28px; height:28px }
  /* The band goes solid almost at once, so no line of the scene runs through an eyebrow. */
  .words { background:linear-gradient(to bottom, transparent 0%, color-mix(in srgb, var(--bg) 92%, transparent) 5%, color-mix(in srgb, var(--bg) 96%, transparent) 100%) }
  .stop, .stop.right, .stop.left, .stop.hero { padding-bottom:max(1.5rem, env(safe-area-inset-bottom)) }
  .about { padding:3rem 1.15rem }
  .about-lead { font-size:1.08rem }
  .features { grid-template-columns:1fr; gap:1.5rem }
  .features h3 { font-size:1.1rem }
  footer { padding:2rem 1.15rem 3rem }
}
/* Short phones: trim the vertical rhythm so a stop still fits one screen. */
@media (max-width:760px) and (max-height:720px) {
  .stop { padding-top:4.5rem; padding-bottom:1.75rem }
  h1 { font-size:2.15rem }
  h2 { font-size:1.6rem }
  .words p { font-size:.98rem; margin-bottom:.55rem }
  .words p.lead { margin:.8rem 0 1rem }
  blockquote p { font-size:1rem }
  .hint { display:none }
  /* The last stop carries the most; on a short screen its button waits for the sections below. */
  .stop[data-stop="day"] p.cta { display:none }
}

/* Frozen for a review screenshot (?p=): the continuous motion holds, the words show. */
.frozen .stars circle, .frozen .flame-flick, .frozen .fly, .frozen .meteor path, .frozen .birds-glide { animation-play-state:paused }
.frozen .lamp-lines path { animation:none; stroke-dashoffset:0 }
.frozen .meteor path { opacity:0 }  /* its streak is a moment; a still frame shows the dark between */
.frozen .reveal { animation:none; opacity:1; transform:none }
.frozen .stop { display:none } .frozen .stop.show { display:grid; position:fixed; inset:0; min-height:0 }
.frozen .ashore { display:none }

@media (prefers-reduced-motion:reduce) {
  html { scroll-behavior:auto }
  .cue, .flame-flick, .birds-glide, .stars circle, .reveal { animation:none }
  .stars circle, .reveal { opacity:1; transform:none }
  .fly { animation:none; opacity:.6 }
  .meteor path { animation:none; opacity:0 }
  .lamp-lines path { animation:none; stroke-dashoffset:0 }
  .words { transition:none; opacity:1; transform:none }
}
