/* The Great Work — palette and type from goldenmonkey.life
   (--bg #0E0B08, --fg #F3EAD8, --gold #E7B864, --ember #DA8E48; Fraunces + Archivo). */
:root {
  --bg: #0E0B08;
  --bg2: #17130F;
  --fg: #F3EAD8;
  --muted: color-mix(in srgb, var(--fg) 62%, transparent);
  --gold: #E7B864;
  --ember: #DA8E48;
  --line: rgba(231, 184, 100, .3);
  --panel: rgba(10, 7, 5, .9);
  /* stage colours: the four phases of the Work */
  --c-prima: #8a5a2b;
  --c-nigredo: #3b3936;
  --c-albedo: #e8e4d8;
  --c-citrinitas: #E7B864;
  --c-rubedo: #c0392b;
  --c-turn: #f2c04e;
  --c-card: #c9953f;
  --c-myth: #5fb3a6;
  --stage: var(--c-prima);
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; }
body {
  background: radial-gradient(120% 70% at 50% 0%, #241a10 0%, var(--bg) 60%);
  background-color: var(--bg);
  color: var(--fg);
  font-family: 'Archivo', system-ui, sans-serif;
  font-weight: 350;
  line-height: 1.55;
  min-height: 100vh;
}
button { font: inherit; cursor: pointer; color: inherit; }
button:disabled { cursor: default; opacity: .35; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
h1, h2, h3 { font-family: 'Fraunces', serif; font-weight: 400; margin: 0; }
.kicker { font-size: 12px; letter-spacing: .28em; text-transform: uppercase; color: var(--gold); font-weight: 600; margin: 0 0 6px; }
.muted { color: var(--muted); }

.ribbon { text-align: center; font-size: 12px; letter-spacing: .08em; padding: 6px 16px; background: #2a1b0e; color: #F6E3B6; border-bottom: 1px solid var(--line); }
.top { position: relative; z-index: 2; display: flex; justify-content: space-between; align-items: center; padding: 16px clamp(16px, 4vw, 40px); max-width: 1100px; margin: 0 auto; }
.brand { display: flex; align-items: center; gap: 10px; font-size: 15px; }
@media (max-width: 560px) {
  .top { gap: 10px; }
  .brand i { display: none; }
}
.brand b { font-family: 'Fraunces', serif; font-weight: 500; color: var(--gold); }
.brand i { color: var(--muted); }
.brand i::before { content: " · "; font-style: normal; }

.ghost { background: rgba(255,255,255,.05); border: 1px solid var(--line); border-radius: 999px; padding: 9px 16px; font-size: .9rem; color: #EAD9B4; }
.ghost:hover { background: rgba(231,184,100,.14); }
.gold { background: var(--gold); color: #17130F; font-weight: 600; border: 0; border-radius: 999px; padding: 12px 22px; }
.gold:hover { background: var(--ember); }
.danger { background: transparent; border: 1px solid #a5463a; color: #f0b3a8; border-radius: 999px; padding: 10px 18px; }
.round { width: 44px; height: 44px; border-radius: 50%; background: rgba(255,255,255,.06); border: 1px solid var(--line); font-size: 1.4rem; line-height: 1; display: flex; align-items: center; justify-content: center; }

/* ---------- the path ---------- */
html, body { overflow-x: clip; }
.path { position: relative; max-width: 1100px; margin: 0 auto; padding: 0 clamp(16px, 4vw, 40px) 60px; }
/* The lead pouring in and the gold pouring out: large, off the right edge,
   beside Module 01. right: 50% - 50vw puts its edge on the viewport edge. */
.hero-art { position: absolute; top: -30px; right: calc(50% - 50vw - 7vw); width: min(62vw, 940px); z-index: 0; pointer-events: none; filter: drop-shadow(0 30px 60px rgba(0,0,0,.55)); }
.hero, .modules, .care { position: relative; z-index: 1; }
.hero { padding: clamp(24px, 6vh, 60px) 0 clamp(20px, 4vh, 40px); max-width: 62ch; }
.hero h1 { font-size: clamp(1.3rem, 5.4vw, 3.8rem); line-height: 1.02; white-space: nowrap; font-variation-settings: 'opsz' 144, 'WONK' 1; }
.lede { font-size: clamp(1.05rem, 1.5vw, 1.2rem); margin: 18px 0 0; color: color-mix(in srgb, var(--fg) 86%, transparent); }
.frame { font-size: .9rem; color: var(--muted); font-style: italic; margin: 14px 0 0; }

.modules { list-style: none; margin: 0; padding: 0; display: grid; gap: 18px; position: relative; }
.mod { position: relative; display: grid; grid-template-columns: 88px 1fr; gap: 18px; align-items: start; background: linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,.01)); border: 1px solid var(--line); border-radius: 16px; padding: 18px; }
.mod-art { width: 88px; height: 88px; object-fit: contain; filter: drop-shadow(0 8px 18px rgba(0,0,0,.5)); }
.mod.locked .mod-art { filter: grayscale(.85) brightness(.55); }
.mod h3 { font-size: clamp(1.3rem, 2.4vw, 1.7rem); line-height: 1.15; }
.mod .n { font-family: 'Fraunces', serif; color: var(--gold); font-size: .95rem; letter-spacing: .1em; }
.mod p { margin: 6px 0 0; color: color-mix(in srgb, var(--fg) 80%, transparent); }
.tier { display: inline-block; font-size: 10px; letter-spacing: .2em; text-transform: uppercase; font-weight: 700; padding: 3px 10px; border-radius: 999px; background: rgba(231,184,100,.15); color: var(--gold); border: 1px solid var(--line); margin-left: 8px; vertical-align: middle; }
.tier.free { background: var(--gold); color: #17130F; }
.mod .row { margin-top: 14px; }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.lockmsg { font-size: .88rem; color: var(--muted); margin-top: 10px; }

.mod-body { grid-column: 1 / -1; display: grid; gap: 16px; grid-template-columns: 1fr; margin-top: 6px; }
/* Module 01 sits in the left column, beside the hero image. */
@media (min-width: 900px) {
  .mod.feature { max-width: 600px; background: linear-gradient(180deg, rgba(23,19,15,.92), rgba(14,11,8,.86)); }
  .mod.feature .mod-art { width: 88px; }
}
@media (max-width: 899px) {
  .hero-art { width: 100vw; right: calc(50% - 50vw - 34vw); top: -10px; opacity: .3; }
}
.course-head, .journey { position: relative; z-index: 1; scroll-margin-top: 20px; }
.course-head { margin: 10px 0 18px; }
.course-head h2, .journey h2 { font-size: clamp(1.8rem, 4vw, 2.6rem); font-variation-settings: 'opsz' 144, 'WONK' 1; }
.journey { margin-top: clamp(56px, 9vh, 100px); padding-top: clamp(28px, 4vh, 44px); border-top: 1px solid rgba(231,184,100,.2); }
.journey > .lede { max-width: 62ch; }
.jrow { margin-top: 34px; }
.jrow-head { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.jrow-head h3 { font-size: 1.4rem; }
.jrow > .muted { margin: 4px 0 14px; max-width: 70ch; }
/* Card rows: centred on the page, and a shorter last row centred under the
   fuller one (a flex row with fixed-width cards rather than a grid). */
.jgrid { --gap: 16px; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--gap); max-width: calc(var(--cols, 3) * 150px); margin: 0 auto; }
.jgrid > .jcard { width: calc((100% - (var(--cols, 3) - 1) * var(--gap)) / var(--cols, 3)); }
.jcard { background: none; border: 0; padding: 0; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 4px; transition: transform .3s cubic-bezier(.16,.7,.3,1); }
/* Every tarot card sits in the same card-shaped frame and is shown whole:
   contain, never cover, so no printed border is cut. The three wider cards
   (Fool, Magician, Hermit) rest on the dark frame with a little space above
   and below. Corners round by only 3px so the printed borders stay intact. */
.jcard img { width: 100%; aspect-ratio: 9 / 16; object-fit: contain; background: #0f0b07; border-radius: 3px; box-shadow: 0 12px 26px rgba(0,0,0,.55), 0 0 0 1px rgba(231,184,100,.22); }
.jcard b { font-family: 'Fraunces', serif; font-weight: 500; color: var(--gold); font-size: .9rem; margin-top: 4px; }
.jcard span { font-size: .82rem; color: var(--muted); line-height: 1.25; }
.jcard:hover { transform: translateY(-5px); }
.jcard.dim img { filter: saturate(.55) brightness(.8); }
@media (max-width: 520px) { .jgrid { --gap: 10px; } }
.jcard.mine img { outline: 2px solid var(--gold); outline-offset: 3px; box-shadow: 0 0 26px rgba(231,184,100,.45); }
.mine-tag { display: block; font-style: normal; font-size: .72rem; color: var(--gold); line-height: 1.3; }
.mine-line { color: var(--gold); font-size: .9rem; }
.chart-sheet .form { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; margin-top: 16px; }
.chart-sheet label { display: flex; flex-direction: column; gap: 5px; font-size: .85rem; color: var(--muted); }
.chart-sheet label.check { flex-direction: row; align-items: center; gap: 8px; color: var(--fg); }
.chart-sheet .wide, .chart-sheet .small, .chart-sheet .manual { grid-column: 1 / -1; }
.chart-sheet .manual { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; }
.chart-sheet .manual[hidden] { display: none; }
.chart-sheet input[type=date], .chart-sheet input[type=time], .chart-sheet input[type=text], .chart-sheet input[type=number], .chart-sheet select { background: rgba(255,255,255,.07); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; font: inherit; color: var(--fg); }
.chart-sheet input:disabled { opacity: .4; }
.chart-sheet .small { font-size: .8rem; margin: 0; }
.chart-sheet .msg { color: #f0b3a8; min-height: 1.2em; margin: 10px 0 0; }
.chart-table { width: 100%; border-collapse: collapse; margin-top: 8px; font-size: .92rem; }
.chart-table th { text-align: left; font-size: 10px; letter-spacing: .2em; text-transform: uppercase; color: var(--gold); font-weight: 600; padding: 6px 4px; }
.chart-table td { padding: 7px 4px; border-top: 1px solid rgba(231,184,100,.14); }
.chart-table td b { font-weight: 600; }
@media (max-width: 520px) { .chart-sheet .form, .chart-sheet .manual { grid-template-columns: 1fr; } }
.card-sheet { text-align: center; }
.card-sheet img { display: block; margin: 0 auto 16px; max-height: 58vh; max-width: 100%; border-radius: 3px; box-shadow: 0 20px 50px rgba(0,0,0,.6), 0 0 0 1px rgba(231,184,100,.22); }
.card-sheet h2 { font-size: 1.6rem; }
.sheet.card-sheet .row { justify-content: center; }
.card-tag { margin: 0; font-family: 'Fraunces', serif; font-size: .9rem; color: var(--gold); letter-spacing: .06em; }
.panel { background: rgba(0,0,0,.25); border: 1px solid rgba(231,184,100,.18); border-radius: 12px; padding: 14px 16px; }
.panel h4 { margin: 0 0 10px; font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--gold); font-weight: 600; }
.rooms { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.rooms button { width: 100%; display: flex; justify-content: space-between; gap: 10px; align-items: center; text-align: left; background: transparent; border: 1px solid transparent; border-radius: 10px; padding: 8px 10px; }
.rooms button:not(:disabled):hover { border-color: var(--line); background: rgba(231,184,100,.06); }
.rooms .st { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.rooms .done .st { color: var(--gold); }
.swatch { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 8px; background: var(--c-prima); vertical-align: 1px; }

.ingots { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 8px; }
.ingot { text-align: center; font-size: 11px; color: var(--muted); }
/* Each ingot carries its phase colour: black, white, yellow, red. Dim until
   its room is walked, lit once it is, crowned with a golden glow (still in its
   own colour) once the experiment is walked in real life. */
.ingot[data-stage=nigredo] { --tint: grayscale(1) brightness(.42) contrast(1.35); --glow: rgba(190,190,190,.45); }
.ingot[data-stage=albedo] { --tint: grayscale(1) brightness(1.7) contrast(.92); --glow: rgba(240,236,224,.7); }
.ingot[data-stage=citrinitas] { --tint: sepia(1) saturate(3.4) hue-rotate(6deg) brightness(1.08); --glow: rgba(231,184,100,.7); }
.ingot[data-stage=rubedo] { --tint: sepia(1) saturate(5.5) hue-rotate(-38deg) brightness(.82); --glow: rgba(214,72,56,.7); }
.ingot img { width: 100%; max-width: 70px; display: block; margin: 0 auto 4px; transition: filter 1.2s ease, opacity 1.2s ease; filter: var(--tint, grayscale(1) brightness(.45)); opacity: .55; }
.ingot.heated img { filter: var(--tint) drop-shadow(0 0 9px var(--glow)); opacity: 1; }
.ingot.gilt img { filter: var(--tint) brightness(1.12) drop-shadow(0 0 4px rgba(255,214,120,.95)) drop-shadow(0 0 16px rgba(231,184,100,.85)); opacity: 1; }
.ingot.gilt::after { content: "✦ gold"; display: block; font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--gold); margin-top: 2px; }
.ingot[data-stage=nigredo] { color: #a9a49b; }
.ingot[data-stage=albedo] { color: #ece7da; }
.ingot[data-stage=citrinitas] { color: var(--gold); }
.ingot[data-stage=rubedo] { color: #e9796a; }
.exp { border-top: 1px solid rgba(231,184,100,.14); padding: 10px 0 2px; }
.exp b { font-weight: 600; }
.exp p { margin: 2px 0 8px; font-size: .9rem; }
.exp .ghost { padding: 6px 12px; font-size: .82rem; }
.hint { font-size: .82rem; color: var(--muted); margin: 0 0 8px; }
.seal { display: flex; gap: 14px; align-items: center; margin-top: 12px; }
.seal-disc { width: 64px; height: 64px; flex: 0 0 64px; border-radius: 50%; display: grid; place-items: center; font-size: 26px; border: 1px solid var(--line); background: radial-gradient(circle, #3b2a14, #120d08); filter: grayscale(1); opacity: .5; }
.seal.earned .seal-disc { filter: none; opacity: 1; box-shadow: 0 0 22px rgba(231,184,100,.35); }
.seal.gilded .seal-disc { background: radial-gradient(circle, #f6d27a, #a8761f); box-shadow: 0 0 34px rgba(231,184,100,.7); }
.care { margin-top: 48px; font-size: .8rem; color: var(--muted); border-top: 1px solid rgba(231,184,100,.15); padding-top: 16px; }

/* ---------- the crucible stage ---------- */
.stage { position: fixed; inset: 0; z-index: 50; height: 100dvh; overflow: hidden; background: radial-gradient(120% 90% at 50% 10%, #241a10 0%, #140f0a 46%, #0b0806 100%); opacity: 0; transition: opacity .5s ease; }
.stage.open { opacity: 1; }
/* A room's scene, behind everything, fading into the dark at the edges. */
.stage-bg { position: absolute; inset: 0; background-size: cover; background-position: center; opacity: 0; transition: opacity 1s ease; pointer-events: none;
  -webkit-mask-image: radial-gradient(120% 90% at 50% 35%, #000 35%, transparent 85%); mask-image: radial-gradient(120% 90% at 50% 35%, #000 35%, transparent 85%); }
.stage.has-bg .stage-bg { opacity: .34; }
.myth-art { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 10px; box-shadow: 0 14px 30px rgba(0,0,0,.55); }
.myth-feature { grid-template-columns: minmax(220px, 340px) 1fr; }
@media (max-width: 640px) { .myth-feature { grid-template-columns: 1fr; } }
.stage-glow { position: absolute; left: 50%; top: 18%; width: min(90vw, 900px); height: 70vh; transform: translateX(-50%); background: radial-gradient(circle, color-mix(in srgb, var(--stage) 38%, transparent), transparent 62%); filter: blur(30px); transition: background 1.4s ease; pointer-events: none; }
.stage-bar { position: absolute; top: 0; left: 0; right: 0; z-index: 6; display: flex; justify-content: space-between; align-items: flex-start; padding: calc(16px + env(safe-area-inset-top, 0px)) clamp(16px, 4vw, 40px) 0; }
.stage-bar h2 { font-size: clamp(1.3rem, 2.6vw, 1.8rem); }
.stage-bar-r { display: flex; gap: 14px; align-items: center; }
.dots { list-style: none; display: flex; gap: 6px; margin: 0; padding: 0; }
.dots li { width: 8px; height: 8px; border-radius: 50%; background: rgba(243,234,216,.2); }
.dots li.on { background: var(--gold); }
.dots li.now { background: var(--fg); box-shadow: 0 0 8px var(--gold); }

.altar { position: absolute; left: 50%; top: clamp(64px, 9vh, 100px); transform: translateX(-50%); width: min(44vw, 340px, 34vh); display: flex; flex-direction: column; align-items: center; z-index: 2; }
.room-art.is-card { width: auto; height: 24vh; max-height: 24vh; object-fit: contain; border-radius: 3px; box-shadow: 0 0 40px color-mix(in srgb, var(--stage) 45%, transparent); }
.room-art.rise { animation: cardRise .9s cubic-bezier(.16,.7,.3,1), float 7s ease-in-out .9s infinite; }
@keyframes cardRise { 0% { transform: translateY(40px) rotateY(80deg); opacity: 0; } 100% { transform: none; opacity: 1; } }
.room-art { width: 46%; border-radius: 6px; max-height: 18vh; object-fit: contain; filter: drop-shadow(0 10px 26px rgba(0,0,0,.6)); animation: float 7s ease-in-out infinite; transition: opacity .6s; }
@keyframes float { 0%,100% { translate: 0 0; } 50% { translate: 0 -8px; } }
/* Find-the-symbol: the card grows, the crucible steps back, taps land on a layer. */
.stage.finding .crucible-wrap { opacity: 0; transition: opacity .4s; pointer-events: none; }
.room-art.findable { height: min(48vh, 520px) !important; max-height: none !important; width: auto !important; animation: none !important; transition: height .5s cubic-bezier(.16,.7,.3,1); }
.find-layer { position: absolute; z-index: 4; display: none; pointer-events: none; }
.room-art.findable { cursor: crosshair; position: relative; z-index: 3; }
.stage.finding .find-layer { display: block; }
.find-dot { position: absolute; width: 34px; height: 34px; margin: -17px 0 0 -17px; border-radius: 50%; border: 2px solid var(--gold); box-shadow: 0 0 14px var(--gold), inset 0 0 10px rgba(231,184,100,.5); pointer-events: none; animation: dotIn .5s cubic-bezier(.2,.9,.3,1.3); }
.find-dot.hint { border-style: dashed; animation: pulse 1.2s ease-in-out infinite; }
@keyframes dotIn { from { transform: scale(2.2); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pulse { 0%,100% { transform: scale(1); opacity: .6; } 50% { transform: scale(1.3); opacity: 1; } }
.fj-feature { display: grid; grid-template-columns: 170px 1fr; gap: 22px; align-items: start; background: linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,.01)); border: 1px solid var(--line); border-radius: 16px; padding: 18px; }
.fj-feature .jcard img { width: 100%; }
.fj-info h3 { font-size: clamp(1.4rem, 2.6vw, 1.8rem); }
.fj-info p { margin: 6px 0 12px; color: color-mix(in srgb, var(--fg) 80%, transparent); }
.fj-info .n { font-family: 'Fraunces', serif; color: var(--gold); font-size: .95rem; letter-spacing: .1em; }
@media (max-width: 640px) { .fj-feature { grid-template-columns: 1fr; } .fj-feature > .jcard { max-width: 180px; } }
/* The lead hovers just above the mouth, a little in front of the rim, about
   to go in. On "Offer it" it falls: in front of the rim, then behind it. */
.room-art.hover-lead { position: relative; z-index: 3; width: 50%; max-height: none; margin-bottom: -19%; border-radius: 0; }
/* On the drop, the falling ingot (.drop) takes over from the hovering one. */
.room-art.hover-lead.dropping { opacity: 0; transition: none; animation: none; }
.crucible-wrap { position: relative; width: 100%; margin-top: -3%; }
/* The other courses (Fool's Journey, Atlantis & Lemuria, Sacred Marriage) play
   without the crucible; the room's art takes the space it leaves. */
.stage.open-stage .crucible-wrap { display: none; }
.stage.open-stage .room-art.is-card { height: 40vh; max-height: 40vh; }
.stage.open-stage .room-art:not(.is-card) { width: 80%; max-height: 34vh; }
.stage.open-stage .breath { top: 18vh; }
/* The fire burns beneath the crucible, behind its body, showing between the legs. */
.under-fire { position: absolute; left: 50%; bottom: -30%; width: 78%; transform: translateX(-50%); z-index: 0; pointer-events: none; filter: drop-shadow(0 0 18px rgba(218,120,40,.65)); animation: flame 2.4s ease-in-out infinite; transform-origin: 50% 100%; }
@keyframes flame { 0%,100% { transform: translateX(-50%) scale(1, 1); } 50% { transform: translateX(-50%) scale(.96, 1.07); } }
/* The two side flames are exact mirror images at the same height, flickering
   in step, so the fire sits balanced under the pot. Centred with a margin
   (not a translate) so the right flame can be mirrored with scale: -1 1. */
.under-fire.side { width: 56%; bottom: -24%; margin-left: -28%; transform: none; opacity: .9; animation: flameSide 3.1s ease-in-out -.8s infinite; }
.under-fire.side.l { left: 36%; rotate: -14deg; }
.under-fire.side.r { left: 64%; rotate: 14deg; scale: -1 1; }
@keyframes flameSide { 0%,100% { transform: scale(1, 1); } 50% { transform: scale(.96, 1.07); } }
.under-glow { position: absolute; left: 10%; right: 10%; bottom: -24%; height: 30%; border-radius: 50%; background: radial-gradient(ellipse, rgba(232,140,50,.55), transparent 70%); filter: blur(10px); z-index: 0; pointer-events: none; }
.crucible { position: relative; width: 100%; display: block; object-fit: contain; z-index: 1; filter: drop-shadow(0 20px 40px rgba(0,0,0,.6)); }
.crucible-fire { position: absolute; left: 16%; right: 16%; top: 2%; height: 24%; border-radius: 50%; z-index: 2; background: radial-gradient(ellipse at center, var(--stage) 0%, color-mix(in srgb, var(--stage) 40%, transparent) 55%, transparent 72%); filter: blur(8px); opacity: .9; mix-blend-mode: screen; transition: background 1.4s ease; animation: flicker 3.2s ease-in-out infinite; }
@keyframes flicker { 0%,100% { opacity: .75; } 50% { opacity: 1; } }
/* The falling ingot lives in a box that ends at the crucible's front lip
   (about 22% down the pot); its bottom corners curve up with the rim, so the
   bar disappears into the mouth instead of passing in front of the pot. */
.drop-clip { position: absolute; left: 6%; right: 6%; top: -320%; bottom: 78%; overflow: hidden; border-bottom-left-radius: 50% 22px; border-bottom-right-radius: 50% 22px; z-index: 3; pointer-events: none; }
.drop { position: absolute; opacity: 0; max-width: none; filter: drop-shadow(0 12px 18px rgba(0,0,0,.55)); }
.breath { position: absolute; top: 30%; left: 50%; width: 150px; height: 150px; margin-left: -75px; border-radius: 50%; border: 1px solid var(--gold); display: none; place-items: center; font-family: 'Fraunces', serif; font-size: 2rem; color: var(--gold); background: radial-gradient(circle, rgba(10,7,5,.75) 40%, rgba(231,184,100,.14) 70%, transparent 72%); z-index: 3; }
.breath.on { display: grid; animation: breathe 10s ease-in-out infinite; }
@keyframes breathe { 0%,100% { transform: scale(.78); } 50% { transform: scale(1.12); } }
.stage.transmute .crucible-fire { animation: transmute 4.2s linear forwards; }
@keyframes transmute { 0% { background: radial-gradient(ellipse, #333, transparent 70%); } 25% { background: radial-gradient(ellipse, #e8e4d8, transparent 70%); } 50% { background: radial-gradient(ellipse, #E7B864, transparent 70%); } 75% { background: radial-gradient(ellipse, #c0392b, transparent 70%); } 100% { background: radial-gradient(ellipse, #ffd86b, transparent 72%); transform: scale(1.4); } }

/* Aurek and Moki: the pop-up pattern from the site's Living Crucible.
   The speaker rises into full light; the other sits lower, dimmed, still present. */
.guide { position: absolute; bottom: 0; height: min(62vh, 640px); max-width: 44vw; object-fit: contain; object-position: bottom; z-index: 1; pointer-events: none; opacity: 0; transform: translateY(30%); filter: brightness(.55); transition: opacity .7s ease, transform .8s cubic-bezier(.16,.7,.3,1), filter .7s ease; }
.guide-a { left: min(2vw, 30px); }
.guide-m { right: min(2vw, 30px); }
.guide.idle { opacity: .4; transform: translateY(16%); filter: brightness(.5) saturate(.7); }
.guide.speaking { opacity: 1; transform: translateY(0); filter: brightness(1); z-index: 2; }
.guide-m.speaking { animation: hop .6s cubic-bezier(.2,.9,.3,1.3); }
@keyframes hop { 0% { transform: translateY(30%); } 60% { transform: translateY(-3%); } 100% { transform: translateY(0); } }
.guide.away { opacity: 0; transform: translateY(40%); }

.dock { position: absolute; left: 0; right: 0; bottom: 0; z-index: 5; display: flex; flex-direction: column; align-items: center; padding: 0 clamp(12px, 4vw, 48px) calc(clamp(16px, 3vh, 30px) + env(safe-area-inset-bottom, 0px)); }
.box { width: 100%; max-width: 760px; background: var(--panel); border: 1px solid rgba(231,184,100,.35); border-radius: 14px; padding: 18px 22px 20px; box-shadow: 0 24px 70px rgba(0,0,0,.55); cursor: pointer; }
.name { display: inline-block; font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: #17130F; background: var(--gold); font-weight: 700; padding: 4px 12px; border-radius: 999px; margin-bottom: 10px; }
.name.you { background: rgba(243,234,216,.9); }
.name.joel { background: transparent; color: var(--gold); border: 1px dashed var(--gold); }
.name:empty { display: none; }
.line:empty { min-height: 0; }
.line { margin: 0; font-size: clamp(1.02rem, 1.6vw, 1.26rem); line-height: 1.55; color: #F6EFDF; min-height: 1.5em; font-family: 'Fraunces', serif; font-variation-settings: 'opsz' 30; font-weight: 360; }
.hist[hidden] { display: none; }
.hist { float: right; display: flex; gap: 6px; align-items: center; }
.hist button { width: 32px; height: 32px; border-radius: 50%; background: rgba(255,255,255,.06); border: 1px solid var(--line); }
.hist span { font-size: 11px; letter-spacing: .1em; color: var(--muted); min-width: 3.2em; text-align: center; }
.extra:empty { display: none; }
.extra { margin-top: 14px; cursor: default; }
.actions { width: 100%; max-width: 760px; margin-top: 12px; display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.chip { background: rgba(255,255,255,.05); border: 1px solid var(--line); color: #EAD9B4; border-radius: 999px; padding: 10px 16px; font-size: .9rem; min-height: 44px; }
.chip:hover { background: rgba(231,184,100,.14); }
.link-chip { display: inline-flex; align-items: center; text-decoration: none; color: var(--gold); border-color: var(--gold); }
.chip.sel { background: rgba(231,184,100,.24); border-color: var(--gold); color: var(--fg); }

textarea { width: 100%; background: rgba(255,255,255,.07); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; font: inherit; font-size: 1rem; color: var(--fg); resize: vertical; min-height: 54px; }
.quote { border-left: 2px solid var(--gold); padding: 4px 0 4px 14px; font-style: italic; color: color-mix(in srgb, var(--fg) 90%, transparent); }
.joelcard { border: 1px dashed var(--gold); border-radius: 12px; padding: 12px 14px; color: #EAD9B4; font-size: .95rem; }
.sort-items, .sort-bins { display: flex; flex-wrap: wrap; gap: 8px; }
.sort-bins { margin-top: 12px; }
.bin { flex: 1 1 140px; min-height: 64px; border-radius: 12px; border: 1px solid var(--line); background: rgba(0,0,0,.3); padding: 8px 10px; text-align: left; font-size: .8rem; }
.bin b { display: block; font-size: 11px; letter-spacing: .16em; text-transform: uppercase; margin-bottom: 4px; }
.bin[data-stage=nigredo] b { color: #b5b0a6; }
.bin[data-stage=albedo] b { color: #f3efe4; }
.bin[data-stage=citrinitas] b { color: var(--c-citrinitas); }
.bin[data-stage=rubedo] b { color: #f07a6c; }
.bin[data-stage=fire] b { color: #f08a4b; }
.bin[data-stage=water] b { color: #7fb6e0; }
.bin[data-stage=air] b { color: #d9e4ee; }
.bin[data-stage=earth] b { color: #a9c27a; }
.bin[data-stage=atlantis] b { color: #8fc9ff; }
.bin[data-stage=lemuria] b { color: #9fd59a; }
.bin[data-stage=square] b { color: #d9a46a; }
.bin[data-stage=triangle] b { color: #e8d48a; }
.bin[data-stage=circle] b { color: #f3efe4; }
.bin[data-stage=sol] b { color: #f2c04e; }
.bin[data-stage=luna] b { color: #cfd6e6; }
.bin span { display: block; color: var(--muted); margin-top: 2px; }
.card { display: flex; gap: 14px; align-items: center; }
.card img { width: 64px; height: 64px; object-fit: contain; }
.card p { margin: 2px 0 0; font-size: .92rem; color: color-mix(in srgb, var(--fg) 84%, transparent); }
.care-note { font-size: .78rem; color: var(--muted); margin-top: 8px; }

/* ---------- sheets ---------- */
.sheet { width: min(640px, calc(100% - 32px)); max-height: 86vh; overflow: auto; border: 1px solid var(--line); border-radius: 16px; padding: 28px clamp(20px, 5vw, 40px); color: var(--fg); background: #1c1611; box-shadow: 0 30px 100px #000; }
.sheet::backdrop { background: rgba(0,0,0,.7); }
.sheet h2 { font-size: 1.8rem; margin-bottom: 6px; }
.sheet .row { justify-content: flex-end; margin-top: 22px; }
.note { border-top: 1px solid rgba(231,184,100,.15); padding: 12px 0; }
.note b { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--gold); }
.note p { margin: 4px 0 0; white-space: pre-wrap; }
.price b { color: var(--gold); }
.test { font-size: .85rem; background: rgba(231,184,100,.08); border: 1px dashed var(--line); border-radius: 10px; padding: 10px 12px; }
/* The bundle offer under a single course's purchase. */
.bundle { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.bundle p { margin: 0 0 10px; font-size: .9rem; color: var(--muted, inherit); }

@media (max-width: 760px) {
  /* Characters sit above the dialog box so the speaker stays visible. */
  .guide { height: 34vh; max-width: 52vw; bottom: calc(190px + env(safe-area-inset-bottom, 0px)); }
  .guide-a { left: -8%; }
  .guide-m { right: -8%; }
  .altar { width: min(50vw, 220px, 30vh); top: 9vh; }
  .stage-bar .kicker { display: none; }
  .dots { display: none; }
  .box { padding: 14px 16px 16px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ---------- interactive beats ---------- */
/* Heat from stoking grows the fire beneath the pot; a flare brightens it. */
.flames { position: absolute; inset: 0; z-index: 0; transform-origin: 50% 100%; scale: calc(1 + var(--heat, 0) * .45); transition: scale .5s cubic-bezier(.2,.9,.3,1.2), filter .4s; pointer-events: none; }
.under-glow { opacity: calc(.6 + var(--heat, 0) * .4); }
.stage.flare .flames { animation: flare .6s ease-out; }
@keyframes flare { 0% { filter: brightness(1.9) saturate(1.3); } 100% { filter: none; } }
.stage.stoking .crucible-wrap { cursor: pointer; pointer-events: auto; }
.stage.stoking .crucible { animation: beckon 1.6s ease-in-out infinite; }
@keyframes beckon { 0%,100% { filter: drop-shadow(0 20px 40px rgba(0,0,0,.6)); } 50% { filter: drop-shadow(0 0 22px rgba(231,184,100,.55)); } }
.hint-line { margin: 0; font-size: .85rem; color: var(--gold); letter-spacing: .04em; }
.burn-input { width: 100%; background: rgba(255,255,255,.07); border: 1px solid var(--line); border-radius: 999px; padding: 12px 16px; font: inherit; color: var(--fg); margin-bottom: 8px; }
.burn-word { position: absolute; left: 50%; top: 30%; transform: translateX(-50%); z-index: 4; font-family: 'Fraunces', serif; font-size: 1.3rem; color: #ffd38a; text-shadow: 0 0 12px #e88a2a; white-space: nowrap; pointer-events: none; animation: burnIn 1.5s ease-in forwards; }
@keyframes burnIn { 0% { top: 0%; opacity: 0; } 20% { opacity: 1; } 70% { opacity: 1; filter: none; } 100% { top: 38%; opacity: 0; filter: blur(6px); letter-spacing: .4em; color: #ff7a2a; } }
.slider { padding: 4px 2px; }
.slider input[type=range] { width: 100%; accent-color: var(--gold); }
.slider-ends { display: flex; justify-content: space-between; align-items: center; font-size: .85rem; color: var(--muted); margin-top: 4px; }
.slider-ends b { font-family: 'Fraunces', serif; font-size: 1.4rem; color: var(--gold); font-weight: 500; }
.room-art { transition: opacity .6s, scale .35s ease; }
.breath.manual { animation: none; transform: scale(.78); transition: transform 4s ease-in-out; }
.breath.manual.inhale { transform: scale(1.15); }
.breathe-btn { min-width: 220px; touch-action: none; user-select: none; -webkit-user-select: none; }
.order-seq { list-style: none; counter-reset: ord; display: flex; flex-wrap: wrap; gap: 8px; padding: 0; margin: 0 0 10px; min-height: 10px; }
.order-seq li { counter-increment: ord; background: rgba(231,184,100,.16); border: 1px solid var(--gold); color: var(--fg); border-radius: 999px; padding: 8px 14px; font-size: .9rem; }
.order-seq li::before { content: counter(ord) " · "; color: var(--gold); }
.chip.shake { animation: shake .4s; }
@keyframes shake { 20%,60% { translate: -5px 0; } 40%,80% { translate: 5px 0; } }
.match { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.match-col { display: flex; flex-direction: column; gap: 8px; }
.chip.paired { background: rgba(231,184,100,.22); border-color: var(--gold); color: var(--fg); opacity: .8; }
.card-back { display: grid; place-items: center; width: 120px; aspect-ratio: 9 / 16; margin: 0 auto; border-radius: 6px; border: 1px solid var(--gold); color: var(--gold); font-size: .78rem; padding: 10px; text-align: center; background: repeating-linear-gradient(45deg, #1d150c 0 10px, #24190e 10px 20px), #1d150c; box-shadow: 0 0 0 4px #120d08, 0 0 0 5px rgba(231,184,100,.5), 0 14px 30px rgba(0,0,0,.6); transition: transform .3s; }
.card-back:hover { transform: translateY(-4px) rotate(-1deg); }

/* ---------- practice tracking ---------- */
.progress { display: flex; align-items: center; gap: 10px; margin: 2px 0 8px; }
.progress .bar { flex: 1; height: 6px; border-radius: 999px; background: rgba(243,234,216,.1); overflow: hidden; }
.progress .bar span { display: block; height: 100%; background: linear-gradient(90deg, var(--ember), var(--gold)); border-radius: 999px; transition: width .6s ease; }
.progress-label { font-size: .78rem; color: var(--muted); white-space: nowrap; }
.last-entry { font-size: .82rem; color: color-mix(in srgb, var(--fg) 70%, transparent); font-style: italic; margin: 0 0 8px; }
.log-sheet .form, .practice-sheet .form { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 16px; margin-top: 14px; }
.log-sheet label { display: flex; flex-direction: column; gap: 5px; font-size: .85rem; color: var(--muted); }
.log-sheet .wide { grid-column: 1 / -1; }
.log-sheet input, .log-sheet textarea { background: rgba(255,255,255,.07); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; font: inherit; color: var(--fg); }
.log-sheet label[hidden] { display: none; }
.log-sheet .msg { color: #f0b3a8; min-height: 1.2em; margin: 10px 0 0; }
.practice-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 14px 0 6px; }
.practice-stats div { background: rgba(231,184,100,.08); border: 1px solid var(--line); border-radius: 12px; padding: 12px; text-align: center; }
.practice-stats b { display: block; font-family: 'Fraunces', serif; font-size: 1.8rem; color: var(--gold); font-weight: 500; }
.practice-stats span { font-size: .78rem; color: var(--muted); }
.practice-exp { border-top: 1px solid rgba(231,184,100,.15); padding: 14px 0 6px; }
.practice-exp h3 { font-size: 1.15rem; margin: 2px 0 2px; }
.practice-exp > .muted { margin: 0 0 8px; font-size: .85rem; }
.practice-entry { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; padding: 8px 0; border-top: 1px dashed rgba(231,184,100,.12); }
.practice-entry b { font-size: .8rem; color: var(--gold); font-weight: 600; }
.practice-entry p { margin: 2px 0 0; font-size: .92rem; }
.small-btn { padding: 6px 12px; font-size: .8rem; }
@media (max-width: 520px) { .log-sheet .form { grid-template-columns: 1fr; } .practice-stats b { font-size: 1.4rem; } }

/* The Parse: Grandpa Jester's word game. Seams sit between the letters; a found
   seam opens with a spark, then the word falls into its pieces and notions. */
.parse { display: grid; justify-items: center; gap: 8px; margin: 6px 0 4px; }
.parse-word { display: flex; align-items: stretch; font-family: 'Fraunces', serif; font-size: clamp(1.6rem, 5vw, 2.4rem); letter-spacing: .02em; color: var(--fg); }
.parse-ltr { padding: 0 1px; }
.parse-gap { width: 12px; margin: 4px 0; padding: 0; border: 0; border-radius: 4px; background: transparent; cursor: pointer; position: relative; transition: width .3s ease, background .2s; }
.parse-gap:hover, .parse-gap:focus-visible { background: color-mix(in srgb, var(--gold) 28%, transparent); outline: none; }
.parse-gap.cut { width: 26px; background: none; cursor: default; }
.parse-gap.cut::after { content: "✦"; position: absolute; inset: 0; display: grid; place-items: center; font-size: .5em; color: var(--gold); text-shadow: 0 0 10px var(--gold); }
.parse-gap.shake { animation: shake .4s; }
.parse-hint { margin: 0; font-size: .85rem; color: color-mix(in srgb, var(--fg) 65%, transparent); }
.parse-pieces { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.parse-piece { display: grid; justify-items: center; gap: 2px; padding: 8px 14px; border: 1px solid var(--line); border-radius: 12px; background: rgba(255,255,255,.04); opacity: 0; animation: pieceIn .5s cubic-bezier(.2,.9,.3,1.2) forwards; }
.parse-piece b { font-family: 'Fraunces', serif; font-size: clamp(1.3rem, 4vw, 1.8rem); color: var(--gold); font-weight: 500; }
.parse-piece span { font-size: .85rem; color: color-mix(in srgb, var(--fg) 80%, transparent); max-width: 16ch; text-align: center; }
@keyframes pieceIn { from { opacity: 0; transform: translateY(8px) scale(.9); } to { opacity: 1; transform: none; } }

/* Large art (the CERN lead-to-gold image): the crucible steps aside and the
   image takes its place, as large as the stage allows above the dialogue. */
.stage.art-big .crucible-wrap { display: none; }
.stage.art-big .altar { width: min(92vw, 820px); }
/* The box hugs the image, and only a thin band at each edge fades into the
   stage, so nothing in the picture is dimmed or lost. */
.stage.art-big .room-art { width: auto; max-width: 100%; height: min(52vh, 615px); max-height: none; filter: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 3%, #000 97%, transparent), linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to bottom, transparent, #000 3%, #000 97%, transparent), linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
  mask-composite: intersect; }

/* An ingot shown large in its phase colour (the Map room). */
.stage.art-big .room-art[data-tint] { height: min(30vh, 320px); -webkit-mask-image: none; mask-image: none; transition: filter .8s ease; }
.stage .room-art[data-tint=nigredo], .drop[data-tint=nigredo] { filter: grayscale(1) brightness(.42) contrast(1.35) drop-shadow(0 0 22px rgba(190,190,190,.45)); }
.stage .room-art[data-tint=albedo], .drop[data-tint=albedo] { filter: grayscale(1) brightness(1.7) contrast(.92) drop-shadow(0 0 22px rgba(240,236,224,.7)); }
.stage .room-art[data-tint=citrinitas], .drop[data-tint=citrinitas] { filter: sepia(1) saturate(3.4) hue-rotate(6deg) brightness(1.08) drop-shadow(0 0 22px rgba(231,184,100,.7)); }
.stage .room-art[data-tint=rubedo], .drop[data-tint=rubedo] { filter: sepia(1) saturate(5.5) hue-rotate(-38deg) brightness(.82) drop-shadow(0 0 22px rgba(214,72,56,.7)); }
/* The spiral, alone on the stage: a little smaller than a full scene. */
.stage.art-big .room-art[src*="spiral"], .stage.art-big .room-art[src*="moon.png"], .stage.art-big .room-art[src*="sun.png"], .stage.art-big .room-art[src*="three-shapes"] { height: min(44vh, 480px); -webkit-mask-image: none; mask-image: none; }
/* The breath circle sits over the centre of a large image. */
.stage.art-big .breath { top: calc(min(22vh, 240px) - 75px); }

/* Zodiac glyphs: a single sign named in a line takes the stage; every sign
   named shows as a chip under the line; the chart table carries mid-sized ones. */
.stage.art-big .room-art[src*="zodiac/"] { height: min(30vh, 300px); -webkit-mask-image: none; mask-image: none; filter: drop-shadow(0 0 26px rgba(231,184,100,.45)); }
.sign-chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.sign-chip { display: inline-flex; align-items: center; gap: 8px; padding: 3px 14px 3px 3px; border: 1px solid var(--line); border-radius: 999px; background: rgba(255,255,255,.04); font-size: .9rem; color: var(--gold); }
.sign-chip img { width: 36px; height: 36px; }
.chart-sign { display: inline-flex; align-items: center; gap: 6px; margin-left: 6px; }
.chart-sign img { width: 34px; height: 34px; vertical-align: middle; }

/* Planet and element symbols in chips, bins, match pairs and the chart. */
.sign-chip .sym { width: 30px; height: 30px; margin-right: -2px; }
.bin-sym { display: block; width: 44px; height: 44px; margin: 0 auto 4px; }
.chip .sym { width: 24px; height: 24px; vertical-align: middle; margin-right: 6px; }
.chart-planet { display: inline-flex; align-items: center; gap: 8px; }
.chart-planet .sym { width: 40px; height: 40px; }

/* Catch the spell: every word is a button; caught words strike through in red,
   then the wizard's line rises in gold. */
.catch { display: grid; gap: 8px; margin: 4px 0; }
.catch-line { margin: 0; font-family: 'Fraunces', serif; font-size: clamp(1.15rem, 3.2vw, 1.4rem); line-height: 1.7; }
.cw { background: none; border: 0; padding: 1px 3px; margin: 0 -1px; border-radius: 6px; font: inherit; color: inherit; cursor: pointer; }
.cw:hover, .cw:focus-visible { background: color-mix(in srgb, var(--gold) 18%, transparent); outline: none; }
.cw.caught { color: #e9796a; text-decoration: line-through; text-decoration-thickness: 2px; cursor: default; }
.cw.shake { animation: shake .4s; }
.catch-wizard { margin: 0; font-family: 'Fraunces', serif; font-size: clamp(1.15rem, 3.2vw, 1.4rem); color: var(--gold); text-shadow: 0 0 18px rgba(231,184,100,.35); animation: pieceIn .6s cubic-bezier(.2,.9,.3,1.2) both; }

/* Tarot scenes: each card opened out into its landscape. A cover across the
   top of a playable card's panel, and a header on every card sheet. */
.fj-cover { grid-column: 1 / -1; width: 100%; aspect-ratio: 16 / 9; max-height: 300px; object-fit: cover; object-position: center 30%; border-radius: 12px; box-shadow: 0 14px 30px rgba(0,0,0,.45); }
.card-sheet img.card-scene { width: 100%; max-height: none; height: auto; aspect-ratio: auto; object-fit: contain; border-radius: 10px; margin-bottom: 14px; box-shadow: 0 14px 30px rgba(0,0,0,.5); }
.card-sheet img.card-scene + #cardImg { max-height: 34vh; }

/* ---------- tidy dashboard (2 Nov 2026) ----------
   Feature panels stack: the full image on top (uncropped), a short line, then
   a fold holding everything else. */
.fj-feature, .myth-feature { grid-template-columns: 1fr; gap: 14px; }
.fj-cover, .myth-art { width: 100%; height: auto; max-height: none; aspect-ratio: auto; object-fit: contain; border-radius: 12px; box-shadow: 0 14px 30px rgba(0,0,0,.45); }
.fj-feature > .jcard { max-width: 150px; }
.fj-inner { display: grid; grid-template-columns: 150px 1fr; gap: 18px; align-items: start; }
@media (max-width: 640px) { .fj-inner { grid-template-columns: 1fr; } .fj-inner > .jcard { max-width: 160px; } }

/* Folds: a quiet gold summary line with a turning chevron. */
.fold { margin-top: 8px; border-top: 1px solid var(--line); }
.fold > summary { list-style: none; cursor: pointer; padding: 12px 2px; font-size: .92rem; letter-spacing: .04em; color: var(--gold); display: flex; align-items: center; gap: 8px; }
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after { content: "▾"; transition: transform .25s ease; }
.fold[open] > summary::after { transform: rotate(180deg); }
.fold > summary:hover, .fold > summary:focus-visible { color: var(--fg); outline: none; }
.fold-body { padding-bottom: 6px; animation: pieceIn .35s ease both; }

/* Ingots are buttons now: a phase description on hover, the log on click. */
.ingot { background: none; border: 0; padding: 4px 2px; cursor: pointer; font: inherit; font-size: 11px; position: relative; border-radius: 10px; }
.ingot:hover, .ingot:focus-visible { background: rgba(255,255,255,.05); outline: none; }
.ingot[data-tip]:hover::before, .ingot[data-tip]:focus-visible::before {
  content: attr(data-tip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); z-index: 5;
  width: max-content; max-width: 220px; padding: 8px 10px; border-radius: 10px; background: #1d150e; border: 1px solid var(--line);
  color: var(--fg); font-size: 12px; line-height: 1.4; text-align: left; letter-spacing: 0; text-transform: none; box-shadow: 0 10px 24px rgba(0,0,0,.5); pointer-events: none; }
.ingots .ingot:first-child[data-tip]:hover::before { left: 0; transform: none; }
.ingots .ingot:last-child[data-tip]:hover::before { left: auto; right: 0; transform: none; }

/* The practice log: what has already been logged, newest first. */
.log-past { list-style: none; margin: 4px 0 10px; padding: 0; max-height: 160px; overflow: auto; font-size: .88rem; }
.log-past li { padding: 6px 0; border-bottom: 1px solid var(--line); }
.log-past b { color: var(--gold); font-weight: 500; margin-right: 4px; }

/* The sound menu: a small panel under whichever ♪ button opened it, above
   the stage and everything else. */
.sound-panel { position: fixed; z-index: 80; width: min(280px, calc(100vw - 24px)); padding: 14px 16px 10px; border-radius: 14px; background: #1b140d; border: 1px solid var(--line); box-shadow: 0 18px 40px rgba(0,0,0,.6); }
.sound-panel[hidden] { display: none; }
.sound-panel .kicker { margin: 0 0 8px; }
.snd-row { display: grid; grid-template-columns: 96px 1fr; align-items: center; gap: 10px; padding: 6px 0; }
.snd-toggle { display: flex; align-items: center; gap: 8px; font-size: .92rem; cursor: pointer; }
.snd-toggle input { accent-color: var(--gold); width: 16px; height: 16px; }
.snd-row input[type=range] { width: 100%; accent-color: var(--gold); }
.snd-row input[type=range]:disabled { opacity: .35; }
.sound-btn.off { opacity: .55; }
.stage-bar-r .sound-btn { font-size: 1.1rem; }

/* The practice log: the phase's ingot above the title, the aim and progress
   as a single gold line, and the practice in its own soft panel. */
.log-head { text-align: center; }
.log-ingot { display: block; width: 96px; margin: -12px auto 2px; filter: grayscale(1) brightness(.6); animation: float 7s ease-in-out infinite; }
.log-ingot[hidden] { display: none; }
.log-ingot[data-tint=nigredo], .pl-ingot[data-tint=nigredo] { filter: grayscale(1) brightness(.5) contrast(1.35) drop-shadow(0 0 16px rgba(190,190,190,.45)); }
.log-ingot[data-tint=albedo], .pl-ingot[data-tint=albedo] { filter: grayscale(1) brightness(1.7) contrast(.92) drop-shadow(0 0 16px rgba(240,236,224,.7)); }
.log-ingot[data-tint=citrinitas], .pl-ingot[data-tint=citrinitas] { filter: sepia(1) saturate(3.4) hue-rotate(6deg) brightness(1.08) drop-shadow(0 0 16px rgba(231,184,100,.7)); }
.log-ingot[data-tint=rubedo], .pl-ingot[data-tint=rubedo] { filter: sepia(1) saturate(5.5) hue-rotate(-38deg) brightness(.82) drop-shadow(0 0 16px rgba(214,72,56,.7)); }
.log-ingot.gilt, .pl-ingot.gilt { filter: sepia(1) saturate(3) hue-rotate(8deg) brightness(1.15) drop-shadow(0 0 6px rgba(255,214,120,.95)) drop-shadow(0 0 22px rgba(231,184,100,.85)); }
.log-head .kicker { margin: 0 0 2px; }
.log-head h2 { margin-bottom: 4px; }
.log-aim { margin: 0 0 12px; color: var(--gold); font-size: .92rem; letter-spacing: .02em; }
.log-practice { padding: 14px 16px; border-radius: 12px; background: rgba(255,255,255,.04); border: 1px solid var(--line); text-align: left; }
.log-practice .kicker { margin: 0 0 4px; }
.log-practice p:last-child { margin: 0; line-height: 1.55; }
.log-sheet .form { margin-top: 14px; }
.log-sheet .form textarea { min-height: 0; }
.log-sheet label > span { color: var(--fg); font-size: .9rem; }

/* ---------- Practice log: a playful ledger of the Work ----------
   A crucible over a flickering fire heads the sheet; three medallions count
   up; each practice is a card in its phase colour with a row of embers that
   light one per action logged, and a timeline of what was lived. Nothing is
   ever taken away and there are no streaks. */
.practice-sheet { background: radial-gradient(120% 60% at 50% -10%, rgba(231,184,100,.16), transparent 60%), #1c1611; }
.pl-hero { display: grid; grid-template-columns: 96px 1fr; gap: 18px; align-items: center; }
.pl-hero h2 { margin: 0 0 4px; }
.pl-hero .muted { margin: 4px 0 0; font-size: .86rem; }
.pl-quip { margin: 0; font-family: 'Fraunces', serif; font-style: italic; color: var(--gold); font-size: 1.05rem; text-shadow: 0 0 18px rgba(231,184,100,.35); }
.pl-pot { position: relative; width: 96px; height: 112px; }
.pl-crucible { position: absolute; left: 0; top: 0; width: 100%; height: 84px; object-fit: contain; z-index: 1; animation: float 6s ease-in-out infinite; filter: drop-shadow(0 6px 14px rgba(0,0,0,.6)); }
.pl-fire { position: absolute; left: 50%; bottom: 0; width: 46%; transform: translateX(-50%); transform-origin: 50% 100%; opacity: .9; animation: flame 1.6s ease-in-out infinite, flicker 2.3s ease-in-out infinite; filter: drop-shadow(0 0 14px rgba(255,140,40,.6)); }

.practice-stats { gap: 12px; margin: 22px 0 10px; }
.practice-stats .pl-stat { position: relative; padding: 16px 10px 12px; border-radius: 16px; overflow: hidden;
  background: linear-gradient(160deg, rgba(231,184,100,.16), rgba(231,184,100,.03)); border: 1px solid rgba(231,184,100,.3);
  box-shadow: inset 0 1px 0 rgba(255,235,190,.15), 0 8px 20px rgba(0,0,0,.35); animation: pieceIn .5s cubic-bezier(.2,.9,.3,1.2) both; }
.practice-stats .pl-stat:nth-child(2) { animation-delay: .08s; }
.practice-stats .pl-stat:nth-child(3) { animation-delay: .16s; }
.pl-stat .pl-icon { display: block; width: 34px; height: 34px; margin: 0 auto 4px; background: center / contain no-repeat; }
.pl-stat.pl-s-fire .pl-icon { background-image: url(img/fire.png); filter: drop-shadow(0 0 8px rgba(255,140,40,.6)); animation: flicker 2s ease-in-out infinite; }
.pl-stat.pl-s-gold .pl-icon { background-image: url(img/lead.png); filter: sepia(1) saturate(3) hue-rotate(8deg) brightness(1.15) drop-shadow(0 0 8px rgba(231,184,100,.8)); }
.pl-stat.pl-s-time .pl-icon { background-image: url(img/symbols/saturn.webp); filter: drop-shadow(0 0 6px rgba(231,184,100,.5)); }
.practice-stats .pl-stat b { font-size: 2.1rem; line-height: 1.1; text-shadow: 0 0 20px rgba(231,184,100,.4); }

.practice-exp { position: relative; margin: 14px 0 0; padding: 16px 16px 14px 18px; border: 1px solid var(--line); border-radius: 16px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--stage) 22%, transparent), rgba(255,255,255,.02) 55%);
  box-shadow: inset 4px 0 0 var(--stage); animation: pieceIn .45s cubic-bezier(.2,.9,.3,1.2) both; }
.practice-exp.gilt { border-color: rgba(231,184,100,.6); box-shadow: inset 4px 0 0 var(--gold), 0 0 0 1px rgba(231,184,100,.2), 0 0 26px rgba(231,184,100,.18); }
.pl-head { display: grid; grid-template-columns: 52px 1fr; gap: 12px; align-items: center; }
.pl-head .kicker { font-size: 10px; margin: 0 0 2px; }
.pl-head h3 { margin: 0; font-size: 1.15rem; }
.pl-ingot { width: 52px; filter: grayscale(1) brightness(.6); transition: transform .3s cubic-bezier(.2,.9,.3,1.2); }
.practice-exp:hover .pl-ingot { transform: rotate(-8deg) scale(1.08); }
.pl-embers { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 12px 0 4px; }
.pl-embers span:not(.pl-count) { width: 12px; height: 12px; border-radius: 50%; background: rgba(243,234,216,.1); border: 1px solid rgba(231,184,100,.25); }
.pl-embers span.lit { background: radial-gradient(circle at 35% 35%, #fff2c4, var(--gold) 45%, var(--ember)); border-color: transparent; box-shadow: 0 0 8px rgba(255,170,60,.75); animation: dotIn .45s cubic-bezier(.2,.9,.3,1.2) both; }
.pl-count { margin-left: 6px; font-size: .78rem; color: var(--muted); }
.practice-exp.gilt .pl-count { color: var(--gold); }

.pl-timeline { position: relative; margin: 8px 0 4px; padding-left: 18px; }
.pl-timeline::before { content: ""; position: absolute; left: 5px; top: 10px; bottom: 10px; width: 2px; border-radius: 2px; background: linear-gradient(var(--gold), color-mix(in srgb, var(--stage) 70%, transparent)); opacity: .5; }
.pl-timeline .practice-entry { position: relative; border-top: 0; padding: 7px 0; }
.pl-timeline .practice-entry::before { content: ""; position: absolute; left: -17px; top: 13px; width: 10px; height: 10px; border-radius: 50%; background: var(--gold); box-shadow: 0 0 0 3px #1c1611, 0 0 10px rgba(231,184,100,.6); }
.pl-date { display: inline-block; padding: 1px 9px; border-radius: 999px; background: rgba(231,184,100,.12); border: 1px solid rgba(231,184,100,.25); font-size: .74rem !important; letter-spacing: .03em; }
.pl-del { flex: none; width: 28px; height: 28px; padding: 0; border-radius: 50%; border: 1px solid transparent; background: none; color: var(--muted); font-size: 1.1rem; line-height: 1; cursor: pointer; opacity: .45; transition: opacity .2s, color .2s, border-color .2s; }
.practice-entry:hover .pl-del, .pl-del:focus-visible { opacity: 1; }
.pl-del:hover, .pl-del:focus-visible { color: #f0b3a8; border-color: rgba(240,179,168,.4); outline: none; }
.pl-add { margin-top: 8px; border-style: dashed; }
.pl-add:hover { border-style: solid; }

.pl-empty { display: grid; justify-items: center; gap: 6px; padding: 20px 0 6px; text-align: center; }
.pl-empty img { width: 120px; animation: float 6s ease-in-out infinite; filter: drop-shadow(0 10px 20px rgba(0,0,0,.5)); }
.pl-empty p { max-width: 34ch; margin: 0; }

@media (max-width: 520px) {
  .pl-hero { grid-template-columns: 72px 1fr; gap: 12px; }
  .pl-pot { width: 72px; height: 86px; } .pl-crucible { height: 64px; }
  .practice-stats { gap: 8px; }
  .practice-stats .pl-stat { padding: 12px 6px 10px; }
  .practice-stats .pl-stat b { font-size: 1.5rem; }
  .pl-stat .pl-icon { width: 26px; height: 26px; }
}
/* A Fool's Journey practice carries its card instead of an ingot. */
.pl-card { width: 52px; aspect-ratio: 9 / 16; object-fit: cover; border-radius: 5px; border: 1px solid rgba(231,184,100,.55); box-shadow: 0 0 0 2px #120d08, 0 8px 16px rgba(0,0,0,.5); transform: rotate(-4deg); transition: transform .3s cubic-bezier(.2,.9,.3,1.2); }
.practice-exp:hover .pl-card { transform: rotate(2deg) scale(1.06); }
.pl-card.gilt { border-color: var(--gold); box-shadow: 0 0 0 2px #120d08, 0 0 14px rgba(231,184,100,.7), 0 8px 16px rgba(0,0,0,.5); }

/* ---------- The menu: courses and tools behind one button ---------- */
.menu-wrap { position: relative; }
.menu-btn { display: inline-flex; align-items: center; gap: 10px; }
.menu-icon { display: inline-grid; gap: 4px; width: 16px; }
.menu-icon i { display: block; height: 2px; border-radius: 2px; background: var(--gold); transition: transform .3s cubic-bezier(.2,.9,.3,1.2), opacity .2s; }
.menu-btn.open .menu-icon i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu-btn.open .menu-icon i:nth-child(2) { opacity: 0; }
.menu-btn.open .menu-icon i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }
.main-menu { position: absolute; right: 0; top: calc(100% + 10px); z-index: 60; width: 280px; padding: 16px; border-radius: 16px;
  background: radial-gradient(120% 70% at 100% 0%, rgba(231,184,100,.14), transparent 60%), #1b140d; border: 1px solid var(--line);
  box-shadow: 0 24px 50px rgba(0,0,0,.65); transform-origin: top right; animation: menuIn .28s cubic-bezier(.2,.9,.3,1.2) both; }
.main-menu[hidden] { display: none; }
/* A long menu scrolls inside itself; swipes never reach the page behind. */
.main-menu { max-height: calc(100dvh - var(--menu-top, 80px) - 16px); overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.main-menu .kicker { font-size: 10px; margin: 0 0 6px; }
.main-menu .kicker:not(:first-child) { margin-top: 14px; }
.menu-courses, .menu-tools { display: grid; gap: 2px; }
.menu-courses a, .menu-tools button { display: block; width: 100%; text-align: left; padding: 9px 12px; border: 0; border-radius: 10px; background: none; font: inherit; font-size: .95rem; color: var(--fg); text-decoration: none; cursor: pointer; transition: background .2s, color .2s, padding-left .2s; }
.menu-courses a { font-family: 'Fraunces', serif; font-size: 1.05rem; }
.menu-courses a:hover, .menu-courses a:focus-visible, .menu-tools button:hover, .menu-tools button:focus-visible { background: rgba(231,184,100,.12); color: var(--gold); padding-left: 16px; outline: none; }
.menu-tools { grid-template-columns: 1fr 1fr; gap: 6px; }
.menu-tools button { border: 1px solid var(--line); text-align: center; padding: 9px 8px; font-size: .86rem; }
.menu-tools button:hover, .menu-tools button:focus-visible { padding-left: 8px; }
@keyframes menuIn { from { opacity: 0; transform: translateY(-6px) scale(.96); } to { opacity: 1; transform: none; } }
@media (max-width: 560px) {
  .main-menu { position: fixed; left: 16px; right: 16px; top: var(--menu-top, 64px); width: auto; }
  /* While the menu is open on a phone, the page behind holds still. */
  html.menu-open, html.menu-open body { overflow: hidden; overscroll-behavior: none; }
}

/* Card sheet: the lines under the card sit in one measured, balanced column. */
.card-sheet h2, .card-sheet #cardModule, .card-sheet #cardLine, .card-sheet #cardNote, .card-sheet .mine-line { max-width: 34rem; margin-left: auto; margin-right: auto; text-wrap: balance; }
.card-sheet #cardModule { margin-top: 0; margin-bottom: 14px; font-size: .92rem; letter-spacing: .02em; }
.card-sheet #cardLine { font-family: 'Fraunces', serif; font-size: 1.15rem; line-height: 1.5; margin-bottom: 14px; }
.card-sheet #cardNote { max-width: 28rem; font-size: .88rem; line-height: 1.6; padding-top: 14px; border-top: 1px solid rgba(231,184,100,.16); }

/* ---------- the Fool's Journey: the road and the stage ----------
   The road itself is drawn as a map further down this file. */
.jcard.ready img { box-shadow: 0 0 0 2px var(--gold), 0 0 22px rgba(231,184,100,.55); }
.jcard.walked img { box-shadow: 0 0 0 2px var(--gold), 0 0 10px rgba(255,214,120,.7); filter: sepia(.25) saturate(1.2); }
.jcard.soon img, .jcard.waiting img { filter: saturate(.4) brightness(.6); }
.jcard.sel { transform: translateY(-6px); }
.jcard.sel b { text-decoration: underline; text-underline-offset: 4px; }
.road-mark { display: block; font-style: normal; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--gold); }
.fj-stage { margin-top: 30px; scroll-margin-top: 16px; }
.fj-stage .mine-line { margin: -6px 0 6px; color: var(--gold); font-size: .9rem; }

/* The hover preview: the card's world, large, with its name and line. */
.road-peek { position: fixed; z-index: 60; border-radius: 14px; overflow: hidden; background: #1b140d; border: 1px solid var(--line); box-shadow: 0 22px 50px rgba(0,0,0,.65); opacity: 0; transform: translateY(6px) scale(.98); transition: opacity .18s ease, transform .18s ease; pointer-events: none; }
.road-peek.on { opacity: 1; transform: none; }
.road-peek img { display: block; width: 100%; height: auto; }
.road-peek-body { padding: 10px 14px 12px; }
.road-peek-body .n { font-family: 'Fraunces', serif; color: var(--gold); font-size: .8rem; letter-spacing: .08em; }
.road-peek-body b { display: block; font-family: 'Fraunces', serif; font-weight: 500; font-size: 1.15rem; margin: 2px 0 2px; }
.road-peek-body p { margin: 0; font-size: .88rem; color: color-mix(in srgb, var(--fg) 80%, transparent); }
@media (hover: none) { .road-peek { display: none; } }
/* The stage sits straight under its act heading, above the map. */
.jrow > .fj-stage { margin-top: 6px; }
.jrow > .kicker { margin-bottom: 4px; }
.jrow { scroll-margin-top: 16px; }

/* ---------- the Fool's Journey map ----------
   A dark map with faint contour lines, a region for each act, and the road
   drawn in SVG behind the stops: dashed where it waits, gold where walked. */
.jmap { --cols: 7; position: relative; isolation: isolate; overflow: hidden; display: grid; grid-template-columns: repeat(var(--cols), minmax(0, 1fr)); column-gap: 10px; row-gap: 56px; align-items: start; margin: 34px 0 0; padding: 48px clamp(26px, 5vw, 50px) 110px; border: 1px solid var(--line); border-radius: 20px; outline: 1px solid rgba(231,184,100,.12); outline-offset: -9px;
  background:
    repeating-radial-gradient(circle at 16% 20%, transparent 0 38px, rgba(231,184,100,.045) 38px 39px),
    repeating-radial-gradient(circle at 86% 74%, transparent 0 46px, rgba(231,184,100,.04) 46px 47px),
    radial-gradient(130% 90% at 50% 0%, #251b10, #110c07 72%); }
.jmap-region { grid-column: 1 / -1; margin: -16px -20px; border-radius: 18px; z-index: 0; pointer-events: none; border: 1px dashed rgba(231,184,100,.1); }
.jmap-region.r1 { background: radial-gradient(80% 100% at 15% 30%, rgba(231,160,80,.13), transparent 72%); }
.jmap-region.r2 { background: radial-gradient(80% 100% at 85% 50%, rgba(110,140,215,.13), transparent 72%); }
.jmap-region.r3 { background: radial-gradient(80% 100% at 25% 60%, rgba(255,214,120,.14), transparent 72%); }
.jmap-act { position: relative; z-index: 2; max-width: 30rem; align-self: center; }
.jmap-act.end { justify-self: end; text-align: right; }
.jmap-act h3 { display: inline; font-size: 1.3rem; font-style: italic; }
.jmap-act p { margin: 5px 0 0; font-size: .84rem; line-height: 1.45; color: var(--muted); }
.jmap .mstop { position: relative; z-index: 2; width: 100%; max-width: 94px; justify-self: center; translate: 0 var(--dy, 0px); }
.jmap .mstop b { font-size: .85rem; }
.jmap .mstop span { font-size: .74rem; text-shadow: 0 1px 4px #000; }
.jmap .mstop.sel img { outline: 2px solid #fff3d6; outline-offset: 3px; }
.here { position: absolute; top: -24px; left: 50%; transform: translateX(-50%); white-space: nowrap; font-style: normal; font-size: .6rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: #1b130b; background: var(--gold); padding: 3px 9px; border-radius: 999px; box-shadow: 0 4px 12px rgba(0,0,0,.5); }
.jmap .mstop.ready img { animation: herePulse 2.6s ease-in-out infinite; }
@keyframes herePulse { 50% { box-shadow: 0 0 0 2px var(--gold), 0 0 34px rgba(231,184,100,.85); } }
@media (prefers-reduced-motion: reduce) { .jmap .mstop.ready img { animation: none; } }
.jmap-road { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.road-bed { fill: none; stroke: rgba(231,184,100,.09); stroke-width: 24; stroke-linecap: round; }
.road-base { fill: none; stroke: rgba(231,184,100,.5); stroke-width: 3; stroke-dasharray: 2 10; stroke-linecap: round; }
.road-lit { fill: none; stroke: var(--gold); stroke-width: 3.5; stroke-linecap: round; filter: drop-shadow(0 0 6px rgba(255,200,100,.6)); }
.jmap-start { position: relative; z-index: 2; justify-self: center; align-self: center; background: none; border: 0; padding: 0; color: inherit; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.jmap-start img { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 2px var(--gold), 0 8px 20px rgba(0,0,0,.6); }
.jmap-start.sel img { outline: 2px solid #fff3d6; outline-offset: 3px; }
.jmap-start.walked img { box-shadow: 0 0 0 2px var(--gold), 0 0 18px rgba(255,214,120,.7); }
.jmap-start b { font-family: 'Fraunces', serif; font-weight: 500; color: var(--gold); font-size: .82rem; }
.jmap-start span { font-size: .7rem; color: var(--muted); }
.jmap-compass { position: absolute; left: 24px; bottom: 16px; width: 72px; z-index: 1; color: rgba(231,184,100,.45); pointer-events: none; text-align: center; }
.jmap-compass svg { display: block; width: 100%; }
.jmap-compass b { position: absolute; top: -14px; left: 0; right: 0; font-family: 'Fraunces', serif; font-size: .8rem; }
@media (max-width: 520px) { .jmap { column-gap: 8px; row-gap: 44px; padding: 44px 24px 100px; } .jmap-act h3 { font-size: 1.1rem; } }

/* Sort bins with a painted emblem: a fixed stage so faces of different
   scales sit on one centre line; the image is sized from --s. */
.bin-art { height: 174px; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.bin-art img { width: calc(74px * var(--s, 1)); height: auto; flex: none; filter: drop-shadow(0 6px 14px rgba(0,0,0,.55)); }
.bin:has(.bin-art) b { text-align: center; }

/* ---------- phones ----------
   Room lists stack each room's state under its name, and every course's
   intro breathes before its card. */
.journey > .lede { margin-bottom: 18px; }
@media (max-width: 560px) {
  .rooms button { flex-direction: column; align-items: flex-start; gap: 2px; }
  .rooms .st { font-size: 10px; padding-left: 18px; }
}
/* The Fool's Journey road in its fold. */
.jmap-fold { margin-top: 26px; }
.jmap-fold > .jmap { margin-top: 14px; }
/* The Great Work's room list in its fold: the summary reads like a panel heading. */
.rooms-fold > summary { padding: 0; font-size: 11px; letter-spacing: .22em; text-transform: uppercase; font-weight: 600; }
.rooms-fold[open] > summary { margin-bottom: 10px; }
/* Locked and coming cards on the map, and the stage's lock line. */
.road-mark.lock, .road-mark.soon { color: var(--muted); }
.stage-lock { margin: 4px 0 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: rgba(0,0,0,.25); color: var(--muted); font-size: .9rem; }
.fj-info > .row { margin: 4px 0 8px; }

/* A card's world filling the screen (a room's `scene`): bright and close,
   easing in from a little nearer, with the edges darkened enough for the
   guides and the words to read. */
.stage.scene .stage-bg { -webkit-mask-image: none; mask-image: none; opacity: .82; animation: sceneOpen 18s cubic-bezier(.2,.6,.3,1) both; }
.stage.scene .stage-bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(11,8,6,.7) 0%, rgba(11,8,6,.1) 22%, rgba(11,8,6,.05) 48%, rgba(11,8,6,.82) 100%); }
@keyframes sceneOpen { from { opacity: 0; transform: scale(1.12); } 12% { opacity: .82; } to { opacity: .82; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .stage.scene .stage-bg { animation: none; } }

/* ---------- the Fool's Journey lobby ----------
   Full screen over the Holy Phool's landscape, scrolling within itself;
   card rooms open above it (the stage sits higher). */
.lobby { position: fixed; inset: 0; z-index: 45; height: 100dvh; background: #0b0806; opacity: 0; transition: opacity .4s ease; }
.lobby.open { opacity: 1; }
.lobby-bg { position: absolute; inset: 0; background: url("img/holy-phool.webp") center 30% / cover no-repeat; opacity: .5; pointer-events: none; }
.lobby-bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(11,8,6,.55) 0%, rgba(11,8,6,.35) 30%, rgba(11,8,6,.88) 62%, #0b0806 100%); }
.lobby-scroll { position: relative; height: 100%; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.lobby-bar { position: sticky; top: 0; z-index: 3; display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding: calc(14px + env(safe-area-inset-top, 0px)) clamp(16px, 4vw, 40px) 18px; background: rgba(11,8,6,.97); border-bottom: 1px solid rgba(231,184,100,.12); box-shadow: 0 10px 24px rgba(0,0,0,.4); }
.lobby-bar h2 { font-size: clamp(1.4rem, 3vw, 2rem); }
.lobby-inner { max-width: 1100px; margin: 0 auto; padding: 0 clamp(16px, 4vw, 40px) 80px; }
.lobby-welcome { display: grid; grid-template-columns: auto 1fr; gap: clamp(14px, 3vw, 30px); align-items: end; min-height: 46vh; padding-top: 20px; }
.lobby-host { height: clamp(220px, 40vh, 420px); width: auto; filter: drop-shadow(0 18px 30px rgba(0,0,0,.6)); }
.lobby-greet { max-width: 34rem; padding-bottom: 12px; }
.lobby-greet .name { display: inline-block; font-size: 11px; letter-spacing: .2em; text-transform: uppercase; font-weight: 700; color: #1b130b; background: var(--gold); padding: 4px 12px; border-radius: 999px; }
.lobby-greet > p { font-family: 'Fraunces', serif; font-size: clamp(1.05rem, 2.2vw, 1.3rem); line-height: 1.5; margin: 10px 0 14px; text-shadow: 0 2px 10px rgba(0,0,0,.7); }
.lobby-meter { height: 6px; border-radius: 999px; background: rgba(255,255,255,.1); overflow: hidden; max-width: 320px; }
.lobby-meter i { display: block; height: 100%; background: linear-gradient(90deg, #b8862f, var(--gold)); border-radius: 999px; }
.lobby-count { font-size: .82rem; color: var(--muted); margin: 6px 0 14px; letter-spacing: .04em; }
.lobby #journeyRows { margin-top: 10px; }
@media (max-width: 640px) {
  .lobby-welcome { grid-template-columns: 1fr; min-height: 0; align-items: start; }
  .lobby-host { height: 210px; justify-self: center; }
  .lobby-greet { padding-bottom: 0; }
}
/* The entry card on the page. */
.fj-entry .fj-cover { cursor: pointer; }
.fj-entry { margin-top: 10px; }
/* The Great Work's forge behind the crucible: wider and warmer than a myth
   backdrop, its dark centre left for the vessel. */
.stage.forge .stage-bg { opacity: .55; -webkit-mask-image: radial-gradient(140% 110% at 50% 40%, #000 45%, transparent 92%); mask-image: radial-gradient(140% 110% at 50% 40%, #000 45%, transparent 92%); }
@media (max-width: 640px) { .stage.forge .stage-bg { background-position: 20% center; opacity: .6; } }
/* A Fool's Journey card's own world behind its rooms: present but quiet, so
   the card and the guides stay in front. */
.stage.world .stage-bg { opacity: .5; -webkit-mask-image: radial-gradient(140% 110% at 50% 40%, #000 45%, transparent 92%); mask-image: radial-gradient(140% 110% at 50% 40%, #000 45%, transparent 92%); }
.stage.world .stage-bg::after { content: ""; position: absolute; inset: 0; background: radial-gradient(60% 55% at 50% 30%, rgba(11,8,6,.55), transparent 75%), linear-gradient(to bottom, rgba(11,8,6,.4), transparent 30%, rgba(11,8,6,.6)); }
/* The sound controls inside the menu: always open, part of the menu itself. */
.menu-sound { margin-top: 14px; }
.sound-panel.inline { position: static; width: auto; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
.sound-panel.inline .kicker { margin: 0 0 4px; }
/* The opening note: visible only until the app has started, or naming what
   stopped it. */
.boot-note { margin: 18px 0 0; font-size: .9rem; color: var(--muted); letter-spacing: .04em; }
.boot-note.err { color: #f0b37a; border: 1px solid rgba(240,179,122,.4); border-radius: 10px; padding: 10px 12px; background: rgba(0,0,0,.3); }
/* A room walked with an answer still waiting. */
.rooms .waiting .st { color: #f0b37a; }

/* ---------- the sanctum: the chamber of doors ---------- */
/* The round chamber stands behind the whole app: clear in the chamber itself,
   dimmed and softened inside a course so the words stay easy to read. Embers
   drift up through it. Art: Joel's ChatGPT "Golden Monkey Artwork" chat,
   3 Nov 2026 (img/chamber/). */
.sanctum { position: fixed; inset: 0; z-index: -1; background: #0b0806 url(img/chamber/rotunda-640.webp) center 38% / cover no-repeat; transition: opacity 1s ease, filter 1s ease; }
@media (min-width: 700px) { .sanctum { background-image: url(img/chamber/rotunda-1024.webp); } }
.sanctum::after { content: ""; position: absolute; inset: 0; background: radial-gradient(120% 80% at 50% 40%, rgba(11,8,6,.05), rgba(11,8,6,.7) 78%), linear-gradient(rgba(11,8,6,.45), rgba(11,8,6,.1) 30%, rgba(11,8,6,.65)); }
.sanctum::before { content: ""; position: absolute; inset: -20% 0 0; z-index: 1; opacity: .55; pointer-events: none;
  background-image: radial-gradient(1.5px 1.5px at 12% 80%, #ffcf7a, transparent), radial-gradient(1px 1px at 33% 60%, #ffd894, transparent), radial-gradient(1.5px 1.5px at 58% 90%, #ffc56a, transparent), radial-gradient(1px 1px at 76% 70%, #ffe0a6, transparent), radial-gradient(1.5px 1.5px at 90% 85%, #ffcf7a, transparent), radial-gradient(1px 1px at 46% 75%, #ffd894, transparent);
  background-size: 100% 60%; animation: embers 26s linear infinite; }
@keyframes embers { from { background-position: 0 100%; } to { background-position: 0 -100%; } }
body[data-view="room"] .sanctum { opacity: .32; filter: blur(3px) saturate(.8); }
body { background: var(--bg); }

.chamber[hidden], .course[hidden], .journey[hidden] { display: none; }
.chamber { position: relative; z-index: 1; }

/* The garden wing. The Eden plate sits behind the doors rather than beside
   them, dimmed and blurred at the edges so door art and copy stay readable.
   The gradient under it is the fallback: until the plate is in place the
   wing still reads as a warm green clearing instead of a broken image. */
.eden::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(ellipse 120% 80% at 50% 0%, rgba(0,0,0,.72), rgba(0,0,0,.94) 70%),
    url("img/myth/eden.jpg") center / cover no-repeat,
    radial-gradient(ellipse at 50% 30%, #1d2a16, #0a0f08 70%);
}
body[data-view="eden"] .sanctum { opacity: .12; }
.chamber .hero { text-align: center; margin: 0 auto; max-width: 46ch; padding-top: clamp(20px, 6vh, 64px); }
.chamber .hero h1 { white-space: normal; font-size: clamp(2.3rem, 9vw, 4.4rem); text-shadow: 0 2px 30px rgba(0,0,0,.8); }
.chamber .hero .lede { text-shadow: 0 1px 12px rgba(0,0,0,.9); }
.chamber .frame { text-align: center; max-width: 60ch; margin: clamp(36px, 6vh, 60px) auto 0; }

.doors { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(26px, 4vw, 40px) clamp(14px, 3vw, 30px); max-width: 1000px; margin: clamp(26px, 5vh, 50px) auto 0; }
/* Ten doors in rows of three leave one over: it stands centred. */
.door:last-child:nth-child(3n+1) { grid-column: 2; }
@media (min-width: 1000px) { .doors { grid-template-columns: repeat(5, 1fr); } .door:last-child:nth-child(3n+1) { grid-column: auto; } }
.door { display: flex; flex-direction: column; align-items: center; text-align: center; color: var(--fg); text-decoration: none; -webkit-tap-highlight-color: transparent; }
.door:focus-visible { outline: none; }
.door-glyph { font-family: 'Fraunces', serif; font-size: 1.4rem; line-height: 1; color: var(--gold); text-shadow: 0 0 14px rgba(231,184,100,.6); margin-bottom: 10px; }
/* The arch: a stone ring around two oak leaves, the course's art waiting behind. */
.door-arch { position: relative; display: block; width: 100%; aspect-ratio: .64; background: #120c07; perspective: 600px;
  border-radius: 50% 50% 4px 4px / 30% 30% 4px 4px; clip-path: inset(0 round 50% 50% 4px 4px / 30% 30% 4px 4px); }
/* The stone ring, drawn over the leaves. */
.door-arch::after { content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 0 0 4px #4d3c2b, inset 0 0 0 5px rgba(231,184,100,.35), inset 0 0 0 7px rgba(0,0,0,.55), inset 0 14px 24px rgba(0,0,0,.55); transition: box-shadow .3s; }
.door-wrap { display: block; width: 100%; max-width: 168px; filter: drop-shadow(0 22px 26px rgba(0,0,0,.75)); }
.door-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transform: scale(1.15); filter: brightness(.5) saturate(.85); transition: transform 1.3s cubic-bezier(.2,.7,.2,1), filter 1s ease; }
.door-light { position: absolute; inset: 0; background: radial-gradient(60% 50% at 50% 62%, rgba(255,192,104,.6), transparent 72%); mix-blend-mode: screen; opacity: 0; transition: opacity .9s ease; }
.door-leaf { position: absolute; top: 0; bottom: 0; width: 50%; background-size: 100% 100%; backface-visibility: hidden; transition: transform .95s cubic-bezier(.55,.05,.25,1); }
.door-leaf.l { left: 0; background-image: url(img/chamber/leaf-left.webp); transform-origin: left center; }
.door-leaf.r { right: 0; background-image: url(img/chamber/leaf-right.webp); transform-origin: right center; }
@media (hover: hover) {
  .door:hover .door-leaf.l { transform: rotateY(-16deg); }
  .door:hover .door-leaf.r { transform: rotateY(16deg); }
  .door:hover .door-light { opacity: .55; }
}
.door:focus-visible .door-arch::after { box-shadow: inset 0 0 0 4px #4d3c2b, inset 0 0 0 6px var(--gold), inset 0 14px 24px rgba(0,0,0,.55); }
.door.opening .door-leaf.l { transform: rotateY(-106deg); }
.door.opening .door-leaf.r { transform: rotateY(106deg); }
.door.opening .door-art { transform: scale(1); filter: brightness(1.05) saturate(1); }
.door.opening .door-light { opacity: 1; }
.door-name { font-family: 'Fraunces', serif; font-size: 1.04rem; line-height: 1.2; margin-top: 14px; text-shadow: 0 1px 10px #000; }
.door-state { font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold); margin-top: 5px; text-shadow: 0 1px 8px #000; }
@media (max-width: 520px) {
  .door-glyph { font-size: 1.15rem; margin-bottom: 7px; }
  .door-name { font-size: .9rem; margin-top: 10px; }
  .door-state { font-size: 9px; letter-spacing: .1em; }
}

/* Inside a course: a way back to the chamber, and a soft arrival. */
.course { position: relative; z-index: 1; }
.back-to-chamber { display: inline-block; color: var(--gold); text-decoration: none; font-size: 12px; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; margin: clamp(8px, 2vh, 18px) 0 clamp(14px, 3vh, 24px); }
.back-to-chamber:hover { color: var(--ember); }
body[data-view="room"] .journey { margin-top: 0; padding-top: 0; border-top: 0; }
body[data-view="room"] main > section:not([hidden]) { animation: room-in .8s cubic-bezier(.2,.7,.2,1) both; }
body[data-view="chamber"] .chamber { animation: room-in .8s cubic-bezier(.2,.7,.2,1) both; }
@keyframes room-in { from { opacity: 0; transform: scale(.985); filter: blur(2px); } }
@media (prefers-reduced-motion: reduce) {
  .sanctum::before, body[data-view] main > section, body[data-view="chamber"] .chamber { animation: none; }
  .door-leaf, .door-art { transition: none; }
}

/* The privacy link under the care note. */
.legal { position: relative; z-index: 1; margin: 10px 0 0; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; }
.legal a { color: var(--muted); text-decoration: none; }
.legal a:hover { color: var(--gold); }

/* Restore purchases: email, then the six-digit code. */
.restore-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.restore-row input { flex: 1 1 200px; min-width: 0; background: rgba(255,255,255,.07); border: 1px solid var(--line); border-radius: 999px; padding: 11px 16px; font: inherit; color: var(--fg); }
#restoreCode { letter-spacing: .3em; font-variant-numeric: tabular-nums; }
.restore-status { min-height: 1.5em; color: var(--muted); font-size: .92rem; margin: 12px 0 4px; }
.linkish { display: block; margin: 16px auto 0; background: none; border: 0; color: var(--gold); font-size: .9rem; text-decoration: underline; text-underline-offset: 3px; }
/* Buttons styled display:block still honour [hidden] (restore stays out of
   sight until /api/config says it is on). */
.menu-tools button[hidden], .linkish[hidden] { display: none; }

/* A short passing note at the foot of the screen (say()). */
.say-note { position: fixed; left: 50%; bottom: max(18px, env(safe-area-inset-bottom)); z-index: 90; transform: translate(-50%, 20px); max-width: min(92vw, 460px); margin: 0; padding: 12px 18px; border-radius: 14px; background: #1b140d; border: 1px solid var(--line); color: var(--fg); font-size: .92rem; box-shadow: 0 16px 40px rgba(0,0,0,.6); opacity: 0; pointer-events: none; transition: opacity .3s, transform .3s; }
.say-note.on { opacity: 1; transform: translate(-50%, 0); }
