/* Animatable colour tokens so Vibe changes cross-fade */
@property --sky1 { syntax: '<color>'; inherits: true; initial-value: #2b1b4d; }
@property --sky2 { syntax: '<color>'; inherits: true; initial-value: #7a3f7a; }
@property --sky3 { syntax: '<color>'; inherits: true; initial-value: #f0955a; }
@property --hill { syntax: '<color>'; inherits: true; initial-value: #3b2a5c; }
@property --tree1 { syntax: '<color>'; inherits: true; initial-value: #25264a; }
@property --tree2 { syntax: '<color>'; inherits: true; initial-value: #14172e; }
@property --ground { syntax: '<color>'; inherits: true; initial-value: #1f3a2b; }
@property --portal { syntax: '<color>'; inherits: true; initial-value: #a56bff; }
@property --portal2 { syntax: '<color>'; inherits: true; initial-value: #d8b8ff; }
@property --orb { syntax: '<color>'; inherits: true; initial-value: #7ff0ff; }
@property --celestial { syntax: '<color>'; inherits: true; initial-value: #ffe8b0; }
@property --rim { syntax: '<color>'; inherits: true; initial-value: #ffb27a; }
@property --fog { syntax: '<color>'; inherits: true; initial-value: #b58aa8; }
@property --cloud { syntax: '<color>'; inherits: true; initial-value: #f2b7a0; }
@property --grade { syntax: '<color>'; inherits: true; initial-value: #ff9a5a; }
@property --trail { syntax: '<color>'; inherits: true; initial-value: #6f5a3e; }

:root {
  /* character palette: stays the same in every vibe so he's recognisable */
  --robe: #1f5a58; --cape: #2b5e4c; --hat: #343a78;
  --ui-bg: #15110b; --ui-panel: rgba(24, 18, 11, .9); --ui-text: #f3ead6; --ui-dim: #c4b393;
  --gold: #e3b54f; --gold-2: #8a5f1a;
  --stars: .5; --firefly: #ffe98a; --shroom: #52f0d0;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  color-scheme: dark;
}

#app[data-vibe="dusk"]   { --sky1:#2b1b4d; --sky2:#8a4a7e; --sky3:#f4a062; --hill:#3b2a5c; --tree1:#27284f; --tree2:#13152b; --ground:#26402f; --portal:#a56bff; --portal2:#d8b8ff; --orb:#7ff0ff; --celestial:#ffe3a8; --rim:#ffb27a; --fog:#c08aa8; --cloud:#f2b7a0; --grade:#ff9a5a; --trail:#6e5638; --stars:.5; }
#app[data-vibe="night"]  { --sky1:#050818; --sky2:#12204a; --sky3:#2a3a7c; --hill:#17224a; --tree1:#0e1636; --tree2:#060a1c; --ground:#12302a; --portal:#3fc8ff; --portal2:#bff3ff; --orb:#9fffd6; --celestial:#f4f1de; --rim:#8fb7ff; --fog:#4a5fa0; --cloud:#7f93d0; --grade:#3a5cff; --trail:#3f4a52; --stars:1; }
#app[data-vibe="sunny"]  { --sky1:#4aa8ef; --sky2:#94d8ff; --sky3:#fff0c0; --hill:#6dbd68; --tree1:#2f8f4e; --tree2:#1b6638; --ground:#4aa35a; --portal:#ff6fd8; --portal2:#ffd0f3; --orb:#ffe36b; --celestial:#fff6a8; --rim:#fff2b0; --fog:#e8f6e0; --cloud:#ffffff; --grade:#ffe9a0; --trail:#b79a68; --stars:0; }

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body { background: var(--ui-bg); color: var(--ui-text); font: 16px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; overscroll-behavior: none; }

#app {
  height: 100dvh; display: grid; grid-template-rows: 1fr auto auto; max-width: 1100px; margin: 0 auto;
  transition: --sky1 1.4s, --sky2 1.4s, --sky3 1.4s, --hill 1.4s, --tree1 1.4s, --tree2 1.4s, --ground 1.4s,
              --portal 1.4s, --portal2 1.4s, --orb 1.4s, --celestial 1.4s, --rim 1.4s, --fog 1.4s, --cloud 1.4s, --grade 1.4s, --trail 1.4s;
}

/* ---------- stage ---------- */
.stage { position: relative; min-height: 0; background: var(--sky1); overflow: hidden; }
.topbar { position: absolute; inset: calc(env(safe-area-inset-top) + 8px) 12px auto 12px; display: flex; justify-content: space-between; align-items: center; pointer-events: none; }
.topbar > * { pointer-events: auto; }
.title { display: flex; flex-direction: column; line-height: 1.05; text-shadow: 0 2px 8px rgba(0,0,0,.7); font-family: var(--serif); }
.title b { font-size: 1.3rem; letter-spacing: .03em; font-weight: 700; }
.title span { font-size: .78rem; color: var(--ui-dim); font-style: italic; }
.actions { display: flex; gap: 8px; }

/* ---------- scene parts ---------- */
#celestial { fill: var(--celestial); }
#stars circle { fill: #fff; opacity: calc(var(--stars)); animation: twinkle 3s infinite; }
.cloud ellipse { fill: var(--cloud); opacity: .5; }
.cloud { animation: cloudDrift 140s linear infinite alternate; }
.cloud.c2 { animation-duration: 190s; animation-direction: alternate-reverse; }
.t1 use { fill: url(#pineG1); }
.trail { fill: var(--trail); opacity: .85; }
.pebbles ellipse { fill: #000; opacity: .22; }
#fern path { fill: color-mix(in srgb, var(--tree2) 80%, #000); }
#grass path { fill: none; stroke-linecap: round; transform-box: fill-box; transform-origin: 50% 100%; animation: sway var(--sd, 3s) ease-in-out infinite alternate; animation-delay: var(--dl, 0s); }

.window { fill: #ffd27a; filter: drop-shadow(0 0 5px #ffb347); animation: flicker 3.2s infinite; }
.bubbles circle { fill: #d4ffa0; opacity: 0; animation: bubble 2.6s ease-in infinite; }
.bubbles circle:nth-child(2) { animation-delay: -.9s; } .bubbles circle:nth-child(3) { animation-delay: -1.7s; }
.sign { transform-box: fill-box; transform-origin: 100% 50%; }

.stone path { fill: url(#stoneG); stroke: #25283a; stroke-width: 1.5; }
.stone .moss { fill: #4f8a3a; stroke: none; opacity: .75; }
.stone .rune { fill: var(--portal2); stroke: none; filter: drop-shadow(0 0 4px var(--portal)); animation: glimmer 3s infinite; }
#portal { transform-box: fill-box; transform-origin: center; animation: portalIdle 5s ease-in-out infinite; }
.swirl { animation: flow 6s linear infinite; }
.swirl.s2 { animation-duration: 4s; animation-direction: reverse; }

/* ---------- Bramwick ---------- */
.pool { animation: glimmer 3s ease-in-out infinite; }
.crystal { transform-box: fill-box; transform-origin: center; animation: pulse 2.6s ease-in-out infinite; }
.eye    { transform-box: fill-box; transform-origin: center; animation: blink 5.5s infinite; }
.eyes   { transition: transform .35s; }
.mouth  { transform-box: fill-box; transform-origin: center; transform: scaleY(.18); }
.brow   { transform-box: fill-box; transform-origin: center; transition: transform .3s; }

@keyframes cloudDrift { from { transform: translateX(-260px) } to { transform: translateX(300px) } }
@keyframes sway { from { transform: rotate(-4deg) } to { transform: rotate(5deg) } }
@keyframes smoke { 0% { transform: translate(0,0) scale(.6); opacity: 0 } 15% { opacity: .5 } 100% { transform: translate(26px,-60px) scale(2.2); opacity: 0 } }
@keyframes bubble { 0% { transform: translateY(0) scale(.4); opacity: 0 } 30% { opacity: .9 } 90% { transform: translateY(-9px) scale(1.2); opacity: .7 } 100% { transform: translateY(-11px) scale(1.6); opacity: 0 } }
@keyframes swing { from { transform: rotate(-8deg) } to { transform: rotate(8deg) } }
@keyframes blink { 0%,93%,100% { transform: scaleY(1) } 96% { transform: scaleY(.08) } }
@keyframes pulse { 0%,100% { opacity: .85; transform: scale(1) } 50% { opacity: 1; transform: scale(1.1) } }
@keyframes glimmer { 0%,100% { opacity: .45 } 50% { opacity: 1 } }
@keyframes twinkle { 0%,100% { opacity: calc(var(--stars)) } 50% { opacity: calc(var(--stars) * .3) } }
@keyframes flicker { 0%,100% { opacity: 1 } 45% { opacity: .78 } 60% { opacity: 1 } 75% { opacity: .86 } }
@keyframes flow { to { stroke-dashoffset: -192 } }
@keyframes portalIdle { 0%,100% { transform: scale(1) } 50% { transform: scale(1.025) } }
@keyframes gesture { 0%,100% { transform: rotate(-8deg) } 30% { transform: rotate(-52deg) } 60% { transform: rotate(-24deg) } 80% { transform: rotate(-64deg) } }
@keyframes talk { 0% { transform: scaleY(.18) } 40% { transform: scaleY(1) } 70% { transform: scaleY(.5) } 100% { transform: scaleY(.85) } }
@keyframes nod { 0%,100% { transform: rotate(0) } 25% { transform: rotate(1.6deg) translateY(1px) } 75% { transform: rotate(-1.4deg) } }
.leaf { animation: fall var(--t) linear infinite; animation-delay: var(--d); }
@keyframes drift { from { transform: translate(0,0) } to { transform: translate(var(--dx), var(--dy)) } }
@keyframes fall { from { transform: translate(0,-40px) rotate(0) } to { transform: translate(var(--dx), 620px) rotate(520deg) } }

/* ---------- RPG-style dialogue + composer ---------- */
#dialogue {
  position: relative; margin: 0 10px; padding: 18px 18px 10px; min-height: 7.6rem; max-height: 30dvh; overflow-y: auto;
  background: linear-gradient(180deg, rgba(34,24,58,.96), rgba(16,11,32,.96));
  border: 1px solid #e3b54f66; border-radius: 12px; box-shadow: inset 0 0 0 3px #15110b, inset 0 0 0 4px #e3b54f33, 0 -8px 24px #0008;
  transform: translateY(-14px); font-family: var(--serif);
}
.nameplate { position: sticky; top: -18px; display: flex; gap: 10px; align-items: baseline; margin: -30px 0 6px -6px; z-index: 1; width: max-content; max-width: 100%;
  padding: 3px 14px; border-radius: 8px; background: linear-gradient(#f0cb6a, #c8963a); color: #2a1a00; box-shadow: 0 2px 8px #0008; }
.nameplate b { font-size: .98rem; letter-spacing: .02em; }
.nameplate span { font-size: .78rem; font-style: italic; opacity: .8; }
#you { margin: 0 0 6px; color: var(--ui-dim); font-size: .92rem; font-style: italic; }
#you:not(:empty)::before { content: "You: "; opacity: .7; font-style: normal; }
#said { margin: 0; font-size: 1.14rem; line-height: 1.5; }

#composer { display: flex; gap: 8px; padding: 0 12px calc(env(safe-area-inset-bottom) + 10px); margin-top: -4px; background: transparent; }
#input { flex: 1; min-width: 0; padding: 12px 16px; border-radius: 12px; border: 1px solid #e3b54f55; background: #ffffff10; color: var(--ui-text); font: inherit; outline: none; }
#input::placeholder { color: #c4b39399; }
#input:focus-visible, button:focus-visible, select:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
button { font: inherit; color: inherit; cursor: pointer; }
.icon { width: 44px; height: 44px; border-radius: 12px; border: 1px solid #e3b54f55; background: #15110bcc; backdrop-filter: blur(6px); font-size: 1.15rem; }
.icon.live { background: #a02b22; animation: pulse 1s infinite; }
.send { padding: 0 20px; height: 44px; border-radius: 12px; border: 0; font-weight: 700; color: #2a1a00; background: linear-gradient(#f4d479, #c8963a); box-shadow: 0 2px 0 #7a5410; }
.send.big { height: 52px; font-size: 1.1rem; padding: 0 32px; }
/* while the woods load: muted, gently breathing, not clickable */
.send.big:disabled { cursor: progress; filter: saturate(.5) brightness(.8); font-weight: 600; font-size: 1rem; animation: gather 1.6s ease-in-out infinite; }
@keyframes gather { 50% { opacity: .65; } }
button:active { transform: translateY(1px) scale(.98); }

/* ---------- settings + splash ---------- */
dialog { width: min(92vw, 420px); border: 1px solid #e3b54f55; border-radius: 16px; background: #1e170e; color: var(--ui-text); padding: 20px; }
dialog::backdrop { background: #000a; backdrop-filter: blur(3px); }
dialog h2 { margin: 0 0 12px; font-family: var(--serif); }
dialog label { display: block; margin: 10px 0; font-size: .9rem; }
dialog label small { color: var(--ui-dim); margin-left: 6px; }
dialog select, dialog input[type=url] { display: block; width: 100%; margin-top: 4px; padding: 10px; border-radius: 10px; border: 1px solid #ffffff30; background: #ffffff10; color: inherit; font: inherit; }
dialog input[type=range] { display: block; width: 100%; margin: 6px 0 0; accent-color: var(--gold); }
dialog .row { display: flex; gap: 8px; align-items: center; }
dialog option { background: #1e170e; }
dialog summary { cursor: pointer; color: var(--ui-dim); margin-top: 8px; }
.acct, .mem { color: var(--ui-dim); font-size: .82rem; margin: 8px 0; }
/* Clear chat / Forget me share a row, Done fills the rest; under ~360 px Done drops to its own full-width row. Never wraps text. */
.dlg-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.dlg-actions button { flex: 1 1 auto; min-width: 0; height: 44px; white-space: nowrap; }
.dlg-actions button:not(.send) { background: none; border: 1px solid #ffffff30; border-radius: 12px; padding: 0 12px; }
.dlg-actions .send { flex: 1 0 100%; padding: 0 16px; }
@media (min-width: 400px) { .dlg-actions .send { flex: 1 1 auto; } }
/* admin-only rows: hidden unless <html class="admin"> (set from ?admin). Obscurity only. */
html:not(.admin) .admin-only { display: none !important; }
/* response type: 3-way segmented control */
dialog .field { margin: 10px 0; font-size: .9rem; }
dialog .flabel { display: block; margin-bottom: 6px; }
.seg { display: flex; border: 1px solid #ffffff30; border-radius: 12px; overflow: hidden; background: #ffffff10; }
.seg button { flex: 1 1 0; min-width: 0; height: 44px; border: 0; background: none; padding: 0 6px; font-size: .9rem; white-space: nowrap; }
.seg button + button { border-left: 1px solid #ffffff22; }
.seg button[aria-checked="true"] { background: linear-gradient(#f4d479, #c8963a); color: #2a1a00; font-weight: 700; }
/* scenery icons on one row, skin swatches spread across the row below */
.pick-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 14px; margin: 14px 0 6px; }
.vibes { display: flex; gap: 6px; }
.vibes button { width: 44px; height: 44px; border-radius: 12px; border: 1px solid #ffffff30; background: #ffffff10; font-size: 1.2rem; padding: 0; }
.vibes button[aria-checked="true"] { border-color: var(--gold); background: #e3b54f33; box-shadow: 0 0 0 1px var(--gold); }
.swatches { flex: 1 0 100%; display: flex; justify-content: space-between; gap: 2px; }
.swatches button { width: 36px; min-width: 0; flex: 0 1 36px; height: 44px; padding: 0; border: 0; background: none; display: grid; place-items: center; }
.swatches button::before { content: ""; width: 26px; height: 26px; border-radius: 50%; background: var(--sw); box-shadow: inset 0 0 0 1px #0004, 0 0 0 1px #ffffff30; }
.swatches button[aria-checked="true"]::before { box-shadow: inset 0 0 0 1px #0004, 0 0 0 2px #1e170e, 0 0 0 4px var(--gold); }

/* splash: golden hour in the wood. Warm low sun top-left, light shafts through the canopy, layered tree
   silhouettes, drifting motes. Pure CSS so it paints instantly while the 3D scene loads behind it. */
#splash { position: fixed; inset: 0; display: grid; place-items: center; z-index: 10; padding: 24px; text-align: center; overflow: hidden;
  background:
    radial-gradient(ellipse 70% 45% at 28% 18%, rgba(255, 196, 110, .55), rgba(255, 160, 70, 0) 70%),
    radial-gradient(ellipse 120% 80% at 50% 110%, #0c0f08 30%, rgba(12, 15, 8, 0) 75%),
    linear-gradient(180deg, #3a2a16 0%, #5a3e1c 30%, #2e2a14 62%, #12140c 100%);
  transition: opacity .5s ease-out, visibility .5s; }
#splash::before { content: ""; position: absolute; inset: -20%; pointer-events: none; mix-blend-mode: screen; opacity: .5;
  background: repeating-conic-gradient(from 200deg at 22% 4%, rgba(255, 214, 140, .22) 0deg 3deg, rgba(255, 214, 140, 0) 3deg 11deg);
  -webkit-mask-image: radial-gradient(ellipse 80% 70% at 22% 4%, #000 20%, transparent 75%); mask-image: radial-gradient(ellipse 80% 70% at 22% 4%, #000 20%, transparent 75%);
  animation: shafts 14s ease-in-out infinite alternate; }
#splash::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(circle at 12% 70%, rgba(255, 220, 150, .9) 0 1.5px, transparent 2.5px),
    radial-gradient(circle at 78% 58%, rgba(255, 220, 150, .8) 0 1.2px, transparent 2px),
    radial-gradient(circle at 64% 82%, rgba(255, 220, 150, .7) 0 1.6px, transparent 2.6px),
    radial-gradient(circle at 34% 40%, rgba(255, 220, 150, .6) 0 1px, transparent 2px),
    radial-gradient(circle at 88% 30%, rgba(255, 220, 150, .6) 0 1.3px, transparent 2.2px),
    linear-gradient(90deg, rgba(8, 10, 6, .85) 0, rgba(8, 10, 6, 0) 9%, rgba(8, 10, 6, 0) 91%, rgba(8, 10, 6, .85) 100%);
  animation: motes 18s linear infinite; }
@keyframes shafts { from { transform: rotate(-2deg); opacity: .4; } to { transform: rotate(2deg); opacity: .6; } }
@keyframes motes { from { background-position: 0 0, 0 0, 0 0, 0 0, 0 0, 0 0; } to { background-position: 30px -120px, -20px -90px, 25px -140px, -15px -70px, 10px -110px, 0 0; } }
#splash.gone { opacity: 0; visibility: hidden; }
.splash-card { position: relative; z-index: 1; max-width: 380px; display: grid; gap: 14px; justify-items: center; font-family: var(--serif); }
.splash-card h1 { margin: 0; font-size: clamp(2.8rem, 13vw, 3.8rem); letter-spacing: .04em; color: #f6d88a;
  text-shadow: 0 2px 0 #6b4512, 0 0 30px rgba(255, 170, 70, .55); }
.splash-card h2 { margin: -10px 0 0; font-size: 1.05rem; font-weight: 400; font-style: italic; color: #e2c99a; }
.splash-card h2::before, .splash-card h2::after { content: ""; display: inline-block; vertical-align: middle; width: 28px; height: 1px; margin: 0 .7em; background: linear-gradient(90deg, transparent, #e2c99a99, transparent); }
.splash-card p { margin: 0; color: #f3e6c8; opacity: .9; line-height: 1.5; text-shadow: 0 1px 3px rgba(0, 0, 0, .6); }
.splash-card small { color: #d8c49c; opacity: .7; font-family: system-ui, sans-serif; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  [data-state="speaking"] .mouth { animation: none; transform: scaleY(.7); }
}

/* sound board (Settings) */
