:root {
  --bg-deep: #0b1220;
  --bg-panel: #111d31;
  --bg-panel-2: #16243b;
  --gold: #d4a441;
  --gold-light: #f3d58a;
  --gold-dark: #7a531b;
  --border-brown: #6a5431;
  --text: #eef1f7;
  --text-dim: #aeb6c6;
  --blue: #2f6fd6;
  --blue-light: #4d8df0;
  --nav-h: 66px;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: #05080f;
  color: var(--text);
  font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
}

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

.app {
  position: relative;
  max-width: 420px;
  height: 100dvh;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background:
    radial-gradient(120% 60% at 50% 0%, #17243a 0%, transparent 70%),
    repeating-linear-gradient(0deg, rgba(255,255,255,.012) 0 2px, transparent 2px 4px),
    var(--bg-deep);
  box-shadow: 0 0 60px rgba(0,0,0,.6);
}

/* ================= TOP BAR ================= */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 8px 5px;
  background: linear-gradient(#0d1627, #0b1322);
  border-bottom: 1px solid #1d2a40;
  flex-shrink: 0;
  z-index: 5;
}

.player { display: flex; align-items: center; gap: 6px; min-width: 0; }

.avatar {
  position: relative;
  width: 44px; height: 44px;
  border-radius: 50%;
  padding: 2px;
  background: linear-gradient(145deg, var(--gold-light), var(--gold) 45%, var(--gold-dark));
  box-shadow: 0 0 0 1px #000, 0 2px 6px rgba(0,0,0,.6);
  flex-shrink: 0;
}
.avatar > img { width: 100%; height: 100%; border-radius: 50%; display: block; object-fit: cover; background: radial-gradient(circle at 50% 40%, #3d5f9a, #15223b); }
.avatar-badge {
  position: absolute; left: -4px; bottom: -3px;
  width: 20px; height: 22px;
}
.avatar-badge svg { width: 100%; height: 100%; }

.player-info {
  background: linear-gradient(90deg, rgba(30,42,64,.9), rgba(20,30,48,.6));
  border: 1px solid #253451;
  border-radius: 6px;
  padding: 3px 8px 5px;
  width: 138px;
}
.player-name { font-size: 11.5px; font-weight: 600; letter-spacing: .2px; }
.player-level { display: flex; align-items: center; gap: 8px; font-size: 10.5px; color: var(--text-dim); margin-top: 1px; }
.xpbar {
  position: relative;
  flex: 1;
  height: 12px;
  background: #0a1120;
  border: 1px solid #2a3a58;
  border-radius: 3px;
  overflow: hidden;
}
.xpbar-fill {
  height: 100%;
  width: 32%;
  background: linear-gradient(#5aa0ff, #2a64d0);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35);
  transition: width .6s ease;
}
.xpbar span {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 9px; color: #fff; font-weight: 500;
  text-shadow: 0 1px 1px #000;
}

/* The HUD's HP bar (the level row's main bar; XP lives in the bottom bar). Fills
   live with out-of-combat regen; colored like the mobs' bars (app.js renderHp). */
.player-info:has(.hpbar) { width: auto; }
.hpbar { position: relative; flex: 1; min-width: 210px; height: 19px; background: #1b1512; border: 1px solid #4a3a2c; border-radius: 5px; overflow: hidden; box-shadow: inset 0 2px 3px #0007; }
.hpbar-fill { position: relative; height: 100%; width: 100%; background: var(--health-color, #39a76b); box-shadow: inset 0 2px #ffffff45, inset 0 -2px #00000030; transition: width .25s linear, background .4s ease; }
/* the damage tail: pale, behind the fill; it waits, then drains (app.js renderHp) */
.hpbar-tail { position: absolute; left: 0; top: 0; height: 100%; width: 100%; background: linear-gradient(#fff4d6, #f0b98a); box-shadow: inset 0 0 6px #ff5a3c80; transition: width .75s cubic-bezier(.45, 0, .2, 1); }
.hpbar.is-hit { animation: hp-jolt .32s ease-out; }
.hpbar.is-hit .hpbar-fill { animation: hp-flash .32s ease-out; transition: width .1s ease-out, background .4s ease; }
@keyframes hp-jolt { 0% { transform: translateX(0); } 20% { transform: translateX(-3px); } 45% { transform: translateX(3px); } 70% { transform: translateX(-1px); } 100% { transform: none; } }
@keyframes hp-flash { 0% { filter: brightness(2.2) saturate(.4); } 100% { filter: none; } }
@media (prefers-reduced-motion: reduce) { .hpbar.is-hit, .hpbar.is-hit .hpbar-fill { animation: none; } }
.hpbar span { position: absolute; inset: 0; display: grid; place-items: center; font-size: 11px; line-height: 1; color: #fffdf4; font-weight: 800; text-shadow: 0 1px 2px #000, 1px 0 #000, -1px 0 #000; }
@media (max-width: 600px) { .hpbar { height: 17px; min-width: 130px; } }
.hpbar.is-low .hpbar-fill { animation: hp-low 1s ease-in-out infinite; }
@keyframes hp-low { 50% { filter: brightness(1.5); } }

.currencies { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.currency-pill {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 8px;
  background: rgba(22,32,50,.9);
  border: 1px solid #243350;
  border-radius: 10px;
  font-size: 12px; font-weight: 500;
}
.currency-pill > span:nth-child(3) { margin-left: 6px; }
.coin {
  width: 16px; height: 16px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #ffe9a3, #e9b534 45%, #a8741a);
  box-shadow: inset 0 0 0 2px #c48e22, 0 0 0 1px #6e4b10;
  position: relative;
}
.coin::after {
  content: ""; position: absolute; inset: 4px;
  border-radius: 50%; border: 1.5px solid #b57f1c;
}
.gem { width: 16px; height: 18px; display: inline-flex; }
.gem svg { width: 100%; height: 100%; filter: drop-shadow(0 0 3px rgba(80,150,255,.6)); }
.icon-btn { width: 26px; height: 26px; display: grid; place-items: center; }
.icon-btn svg { width: 22px; height: 22px; }

/* ================= POMODORO ================= */
/* Fixed + centered on the viewport, not a flex child of .topbar -- so it
   stays put, front and center, in every screen the app has, world or
   combat or menus alike, instead of living inside whichever container
   happens to be visible right now. */
#pomodoroMount { position: fixed; top: 8px; left: 0; right: 0; z-index: 50; display: flex; justify-content: center; pointer-events: none; }
.pomodoro-pill {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 18px;
  background: rgba(22,32,50,.94);
  border: 1.5px solid #243350;
  border-radius: 14px;
  box-shadow: 0 4px 14px rgba(0,0,0,.4);
  font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--text);
  transition: background-color .2s, border-color .2s;
  pointer-events: auto;
}
.pomodoro-icon { width: 24px; height: 24px; display: inline-flex; flex-shrink: 0; }
.pomodoro-icon svg { width: 100%; height: 100%; }
.pomodoro-pill.is-focus {
  background: rgba(209, 69, 59, .25);
  border-color: rgba(230, 75, 60, .7);
}
.pomodoro-pill.is-focus .pomodoro-icon { animation: pomodoroPulse 1.6s ease-in-out infinite; }
.pomodoro-pill.is-break {
  background: rgba(76, 209, 55, .2);
  border-color: rgba(76, 209, 55, .6);
  color: #bdf2b0;
}
@keyframes pomodoroPulse { 50% { transform: scale(1.15); } }
@media (prefers-reduced-motion: reduce) {
  .pomodoro-pill.is-focus .pomodoro-icon { animation: none; }
}
@media (max-width: 480px) {
  /* At phone width the player-info block and the currency pills already
     span nearly the full bar, so a truly centered pill here overlaps one
     side or the other no matter how it's sized. Drop it to its own row
     just under the header instead -- still centered, nothing left to
     collide with there. */
  #pomodoroMount { top: 72px; }
  .pomodoro-pill { font-size: 15px; padding: 7px 14px; }
  .pomodoro-icon { width: 20px; height: 20px; }
}

.pomodoro-intro { text-align: left; }
.pomodoro-intro h3 { text-align: center; }
.pomodoro-intro-note {
  margin-top: 12px !important;
  padding: 8px 10px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.1);
  border-radius: 8px;
  font-size: 12.5px !important;
  font-style: italic;
}

/* ================= VIEWS ================= */
.views {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding-bottom: calc(var(--nav-h) + 6px);
  scrollbar-width: none;
}
.views::-webkit-scrollbar { display: none; }
.view { display: none; }
.view.is-active { display: block; animation: fadeIn .25s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* World is the one view that fills the content area exactly, instead of
   scrolling like the other pages — it hosts a fixed-size canvas, not text. */
.view[data-view="world"].is-active {
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
}
.world-root {
  flex: 1;
  min-height: 0;
  display: flex;
}
.view[data-view="world"] { --world-progress-height: 46px; }
.world-progress { position: absolute; left: 0; right: 0; bottom: 0; height: var(--world-progress-height); z-index: 12; display: block!important; visibility: visible!important; opacity: 1!important; box-sizing: border-box; padding: 3px 10px; background: #263e42; border-top: 2px solid #af995f; color: #eee6c9; font-size: 11px; }
.world-progress-row { display: flex; align-items: center; gap: 8px; min-width: 0; height: 19px; }
.world-deck-path { display: flex; align-items: baseline; gap: 4px; flex: 1; min-width: 55px; overflow: hidden; white-space: nowrap; }
#worldDeckName { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; }
#worldDeckCategory { overflow: hidden; text-overflow: ellipsis; color: #8a7d64; font-size: 9px; }
#worldDeckPercent, #worldLevel, #worldXpText { white-space: nowrap; }
#worldXpText { color: #c7d4ce; font-size: 9px; font-variant-numeric: tabular-nums; }
#worldDeckPercent { color: #e4cf87; }
.anki-count { display: inline-flex; align-items: baseline; gap: 2px; white-space: nowrap; font-size: 8px; font-weight: 650; }
.anki-count b { font-size: 10px; font-variant-numeric: tabular-nums; }
.anki-new { color: #4f8fdc; }.anki-learn { color: #c15f59; }.anki-due { color: #559b62; }
#worldXp { flex: 1; min-width: 20px; height: 8px; appearance: none; border: 1px solid #13272c; background: #13272c; border-radius: 3px; overflow: hidden; }
#worldXp::-webkit-progress-bar { background: repeating-linear-gradient(90deg,#13272c 0 calc(10% - 2px),#41504d calc(10% - 2px) 10%); }
#worldXp::-webkit-progress-value { background: repeating-linear-gradient(90deg,#b7c978 0 calc(10% - 2px),#74834d calc(10% - 2px) 10%); }
#worldXp::-moz-progress-bar { background: repeating-linear-gradient(90deg,#b7c978 0 calc(10% - 2px),#74834d calc(10% - 2px) 10%); }
.view[data-view="world"] .encounter-sheet { bottom: var(--world-progress-height); }

/* Current page's name -- appended directly into #worldRoot by WorldScene
   itself (see loadZone), positioned relative to .view[data-view="world"]
   since #worldRoot has no position of its own. Sits above the chat log/
   input (also bottom-left, see .chat-log/.chat-input below) so the two
   bottom-left overlays don't stack on top of each other. */
.room-label {
  position: absolute; left: 8px; bottom: 138px; z-index: 4;
  font-size: 11px; color: rgba(255, 255, 255, .75);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
  pointer-events: none;
}

/* Bottom-left chat: appended directly into #worldRoot by WorldScene, same
   pattern as .room-label. Same "transparent box, readable text" look as
   .net-badge (see ACCOUNT & CONNECTION section) so the whole HUD matches. */
.chat-log {
  /* bottom offset clears .world-progress (z-index 12, opaque), which
     otherwise sits on top of and fully hides both this and .chat-input --
     same fix as .encounter-sheet's own bottom: var(--world-progress-height). */
  position: absolute; left: 8px; bottom: calc(var(--world-progress-height, 0px) + 34px); z-index: 4;
  width: 62%; max-height: 96px;
  overflow-y: auto;
  padding: 4px 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  font-size: 11px; line-height: 1.4;
  color: rgba(255, 255, 255, .92);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .8), 0 1px 4px rgba(0, 0, 0, .8);
}
.chat-log-line { word-wrap: break-word; transition: opacity .6s ease; }
.chat-log-name { font-weight: 700; }

.chat-input {
  position: absolute; left: 8px; bottom: calc(var(--world-progress-height, 0px) + 8px); z-index: 4;
  width: 62%;
  padding: 5px 10px;
  border-radius: 8px;
  background: rgba(8, 12, 22, .7);
  border: 1px solid rgba(255, 255, 255, .18);
  box-shadow: none;
  color: var(--text);
  font: inherit; font-size: 11px;
}
.chat-input:focus { outline: none; border-color: rgba(255, 255, 255, .4); background: rgba(8, 12, 22, .85); box-shadow: none; }
.chat-input::placeholder { color: rgba(255, 255, 255, .55); }

/* ================= HERO ================= */
.hero {
  position: relative;
  aspect-ratio: 400 / 296;
  overflow: hidden;
  border-bottom: 2px solid #5a4528;
  box-shadow: inset 0 0 40px rgba(0,0,0,.45);
}
.hero-scene { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

.plaque {
  position: absolute;
  top: 3.5%;
  left: 50%;
  transform: translateX(-50%);
  width: 58%;
  aspect-ratio: 900 / 352;
  z-index: 3;
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.6));
}
.plaque-frame { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.plaque-text {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-family: Cinzel, Georgia, serif;
  line-height: 1;
  padding-bottom: 2px;
}
.plaque-top {
  font-size: clamp(13px, 4.9vw, 20px);
  font-weight: 700;
  letter-spacing: 1px;
  color: #f1e2b8;
  text-shadow: 0 2px 0 #3a2a10, 0 0 6px rgba(0,0,0,.6);
}
.plaque-main {
  margin-top: 2px;
  font-size: clamp(22px, 8vw, 33px);
  font-weight: 900;
  letter-spacing: .5px;
  background:
    linear-gradient(110deg, transparent 42%, rgba(255,255,255,.95) 50%, transparent 58%) no-repeat,
    linear-gradient(#fff2c2 0%, #f1c65a 45%, #c48a2a 60%, #f6d680 100%);
  background-size: 250% 100%, 100% 100%;
  background-position: 160% 0, 0 0;
  animation: shine 5s ease-in-out infinite 1s;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 0 #3b2508) drop-shadow(0 0 1px #1a1005);
}
.hero-sub {
  position: absolute;
  top: 36.5%;
  left: 50%;
  z-index: 3;
  transform: translateX(-50%);
  width: 100%;
  margin: 0;
  text-align: center;
  font-size: clamp(9px, 2.8vw, 11.5px);
  font-weight: 500;
  letter-spacing: .6px;
  line-height: 1.35;
  text-transform: uppercase;
  color: #f4f6fb;
  text-shadow: 0 1px 2px #000, 0 0 8px rgba(0,0,0,.7);
}

/* painted layers — positions are % of the 400×296 hero */
.scene-layer { position: absolute; display: block; pointer-events: none; }
.scene-layer > img { display: block; width: 100%; height: auto; }
img.scene-layer { height: auto; }
.books-left { left: -5%; top: 61%; width: 33%; z-index: 2; }
.book-label {
  position: absolute; left: 19.5%;
  transform: translateY(-50%) rotate(9.8deg);
  transform-origin: left center;
  font-family: Cinzel, Georgia, serif; font-weight: 700;
  font-size: clamp(5.5px, 1.75vw, 7.2px);
  letter-spacing: .3px; text-transform: uppercase;
  color: #f3dfa6;
  text-shadow: 0 1px 1px rgba(0,0,0,.9);
  white-space: nowrap;
  padding: 1px 4px 0;
  background: linear-gradient(rgba(34,22,14,.88), rgba(20,12,8,.88));
  border: 1px solid rgba(212,164,65,.7);
  border-radius: 2px;
}
.hero-char { left: 11.5%; top: 36%; width: 43%; z-index: 1; }
.scroll-text {
  position: absolute; left: 74%; top: 73%;
  transform: translate(-50%, -50%) rotate(-4deg);
  font-family: "Dancing Script", cursive; font-weight: 600;
  font-size: clamp(9px, 3vw, 12.5px);
  line-height: 1.25; text-align: center;
  color: #3d2814;
}
.books-owl { left: 66%; top: 77%; width: 21%; z-index: 1; }
.owl { left: 60.5%; top: 57%; width: 31%; aspect-ratio: 480 / 297; z-index: 1; }
.lantern { left: 85.5%; top: 71.5%; width: 14%; z-index: 2; }

/* ================= SCENE ANIMATION ================= */
[data-poke] { pointer-events: auto; cursor: pointer; -webkit-tap-highlight-color: transparent; }

/* hero: slow breathing, hop when tapped */
.hero-char { transform-origin: 50% 100%; animation: heroIdle 4.2s ease-in-out infinite; }
.hero-char.is-poked { animation: heroHop .55s cubic-bezier(.3,.7,.4,1); }
@keyframes heroIdle { 50% { transform: translateY(-1.5px) scale(1.008, 1.014); } }
@keyframes heroHop {
  0% { transform: none; }
  25% { transform: translateY(2px) scale(1.04, .95); }
  55% { transform: translateY(-12px) scale(.98, 1.03); }
  80% { transform: translateY(1px) scale(1.02, .98); }
  100% { transform: none; }
}

/* owl: one image cut into body + two wings, wings rotate at the shoulders */
.owl { animation: owlBob 3.2s ease-in-out infinite; }
.owl > img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.owl-body {
  clip-path: polygon(33% 18%, 40% 9%, 50% 7%, 60% 9%, 67% 18%, 70% 35%, 69% 60%, 66% 78%, 64% 92%, 58% 100%, 42% 100%, 36% 92%, 34% 78%, 31% 60%, 30% 35%);
}
.owl-wing-l {
  clip-path: polygon(0 0, 36% 0, 32% 35%, 33% 58%, 28% 80%, 0 80%);
  transform-origin: 33% 52%;
  animation: flapL 3.2s ease-in-out infinite;
}
.owl-wing-r {
  clip-path: polygon(64% 0, 100% 0, 100% 80%, 72% 80%, 67% 58%, 68% 35%);
  transform-origin: 67% 52%;
  animation: flapR 3.2s ease-in-out infinite;
}
.owl.is-poked { animation: owlHop .6s cubic-bezier(.3,.7,.4,1); }
.owl.is-poked .owl-wing-l { animation: flapFastL .2s ease-in-out 3; }
.owl.is-poked .owl-wing-r { animation: flapFastR .2s ease-in-out 3; }
@keyframes owlBob { 50% { transform: translateY(-3px) rotate(-1.5deg); } }
@keyframes owlHop { 40% { transform: translateY(-14px) rotate(4deg); } 70% { transform: translateY(-4px) rotate(-3deg); } }
@keyframes flapL { 0%, 30%, 100% { transform: none; } 8%, 22% { transform: rotate(14deg); } 15% { transform: rotate(-6deg); } }
@keyframes flapFastL { 50% { transform: rotate(18deg); } }
@keyframes flapFastR { 50% { transform: rotate(-18deg); } }
@keyframes flapR { 0%, 30%, 100% { transform: none; } 8%, 22% { transform: rotate(-14deg); } 15% { transform: rotate(6deg); } }

.owl-bubble {
  position: absolute; right: 13%; top: 41%;
  z-index: 4;
  max-width: 44%;
  padding: 5px 9px;
  border-radius: 10px;
  background: #fbf3dc;
  color: #2b1e0e;
  font-size: 11px; font-weight: 600;
  box-shadow: 0 3px 8px rgba(0,0,0,.45), inset 0 0 0 1.5px #c99b45;
  opacity: 0; transform: translateY(6px) scale(.9);
  pointer-events: none;
  transition: opacity .2s, transform .2s;
}
.owl-bubble::after {
  content: ""; position: absolute; left: 40%; bottom: -5px;
  width: 10px; height: 10px; background: #fbf3dc;
  transform: rotate(45deg);
  box-shadow: 1.5px 1.5px 0 #c99b45;
}
.owl-bubble.is-showing { opacity: 1; transform: none; }

/* lantern: flickering flame glow, flare when tapped */
.lantern > img { position: relative; z-index: 0; }
.lantern-flame {
  position: absolute; left: 50%; top: 50%;
  width: 90%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,225,140,.75) 0%, rgba(255,170,60,.35) 35%, transparent 70%);
  mix-blend-mode: screen;
  animation: flame 1.9s ease-in-out infinite;
}
.lantern.is-poked .lantern-flame { animation: flare .7s ease-out; }
.lantern-glow { transform-box: fill-box; transform-origin: center; animation: glow 2.6s ease-in-out infinite; }
@keyframes flame {
  0%, 100% { opacity: .9; transform: translate(-50%, -50%) scale(1); }
  20% { opacity: .65; transform: translate(-50%, -52%) scale(.92); }
  45% { opacity: 1; transform: translate(-50%, -49%) scale(1.06); }
  70% { opacity: .75; transform: translate(-50%, -51%) scale(.96); }
}
@keyframes flare { 30% { opacity: 1; transform: translate(-50%, -50%) scale(1.9); } }
@keyframes glow { 0%, 100% { opacity: 1; } 30% { opacity: .8; transform: scale(.96); } 60% { opacity: .95; transform: scale(1.03); } 80% { opacity: .78; } }

/* dust motes in the window light */
.motes { position: absolute; left: 14%; right: 18%; top: 30%; bottom: 4%; z-index: 2; pointer-events: none; }
.motes i {
  position: absolute; left: var(--x); bottom: 0;
  width: 3px; height: 3px; border-radius: 50%;
  background: #fff4cf;
  box-shadow: 0 0 6px 2px rgba(255,220,140,.6);
  opacity: 0;
  animation: mote var(--d) linear infinite var(--delay);
}
@keyframes mote {
  0% { transform: translate(0, 0) scale(.6); opacity: 0; }
  15% { opacity: .9; }
  50% { transform: translate(10px, -90px) scale(1); }
  85% { opacity: .6; }
  100% { transform: translate(-6px, -180px) scale(.5); opacity: 0; }
}

/* sky, flag, banner */
.sky-clouds { animation: drift 26s ease-in-out infinite alternate; }
@keyframes drift { from { transform: translateX(-14px); } to { transform: translateX(14px); } }
.castle-flag { transform-box: fill-box; transform-origin: 0 50%; animation: flag .9s ease-in-out infinite alternate; }
@keyframes flag { from { transform: scaleX(1) skewY(0); } to { transform: scaleX(.7) skewY(8deg); } }
.banner { transform-box: fill-box; transform-origin: 50% 0; animation: sway 5.5s ease-in-out infinite; }
@keyframes sway { 0%, 100% { transform: skewX(0); } 30% { transform: skewX(1.6deg); } 70% { transform: skewX(-1.6deg); } }
.banner-star-glow { animation: starPulse 2.4s ease-in-out infinite; }
@keyframes starPulse { 50% { opacity: .35; } }

/* title plaque: light sweep over the gold letters + twinkling diamonds */
@keyframes shine { 0%, 55% { background-position: 160% 0, 0 0; } 100% { background-position: -60% 0, 0 0; } }
.twinkle {
  position: absolute; width: 14px; height: 14px;
  transform: translate(-50%, -50%) scale(0);
  background: radial-gradient(circle, #fff 0 12%, transparent 13%),
    conic-gradient(from 45deg, transparent 0 20%, rgba(255,240,190,.95) 25%, transparent 30% 45%, rgba(255,240,190,.95) 50%, transparent 55% 70%, rgba(255,240,190,.95) 75%, transparent 80% 95%, rgba(255,240,190,.95) 100%);
  -webkit-mask: radial-gradient(circle, #000 25%, transparent 70%);
  mask: radial-gradient(circle, #000 25%, transparent 70%);
  animation: twinkle 3.4s ease-in-out infinite;
  pointer-events: none;
}
.twinkle-sm { width: 10px; height: 10px; }
@keyframes twinkle {
  0%, 60%, 100% { transform: translate(-50%, -50%) scale(0) rotate(0); opacity: 0; }
  75% { transform: translate(-50%, -50%) scale(1.4) rotate(45deg); opacity: 1; }
  90% { transform: translate(-50%, -50%) scale(0) rotate(90deg); opacity: 0; }
}

/* upload arrow + active nav */
.cloud-arrow { animation: arrowUp 2.2s ease-in-out infinite; }
.dropzone.is-over .cloud-arrow { animation-duration: .7s; }
@keyframes arrowUp { 0%, 100% { transform: translateY(1px); } 50% { transform: translateY(-3px); } }
@keyframes navGlow {
  50% { box-shadow: 0 0 16px rgba(212,164,65,.7), inset 0 0 12px rgba(212,164,65,.4); }
}

@media (prefers-reduced-motion: reduce) {
  .hero *, .hero-char, .owl, .banner, .sky-clouds, .castle-flag, .lantern-glow, .motes, .cloud-arrow, .nav-item.is-active, .plaque-main {
    animation: none !important;
  }
  .motes { display: none; }
}

/* ================= PANELS ================= */
.panel {
  margin: 6px 8px 0;
  background: linear-gradient(180deg, var(--bg-panel-2), var(--bg-panel));
  border: 2px solid var(--border-brown);
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px #2a2215, inset 0 0 24px rgba(0,0,0,.35), 0 3px 10px rgba(0,0,0,.4);
}

.upload-panel { padding: 7px; margin-top: 6px; }
.dropzone {
  display: flex; flex-direction: column; align-items: center;
  padding: 10px 12px 8px;
  border: 1.5px dashed rgba(190,200,220,.45);
  border-radius: 6px;
  cursor: pointer;
  transition: background .2s, border-color .2s;
}
.dropzone.is-over { background: rgba(77,141,240,.12); border-color: var(--blue-light); }
.dropzone.is-busy { pointer-events: none; opacity: .85; }
.cloud { width: 42px; height: 32px; margin-bottom: 4px; }
.drop-title { font-size: 14.5px; font-weight: 500; text-align: center; }
.drop-or { font-size: 12px; color: var(--text-dim); margin: 1px 0 4px; }
.btn-primary {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 62%;
  height: 35px;
  border-radius: 4px;
  background: linear-gradient(#3b80ea, #2560c8);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 2px 0 #163e85;
  font-size: 15px; font-weight: 500; color: #fff;
  transition: filter .15s, transform .1s;
}
.btn-primary svg { width: 13px; height: 15px; }
.btn-primary:hover { filter: brightness(1.1); }
.btn-primary:active { transform: translateY(1px); }
.drop-hint { font-size: 10.5px; color: var(--text-dim); margin-top: 7px; }

.features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding: 8px 4px;
}
.feature {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  text-align: center;
  font-size: 10.5px; line-height: 1.25; color: #dfe4ee;
}
.feature + .feature { border-left: 1px solid #2a3852; }
.feature svg { width: 36px; height: 30px; }

/* ================= BOTTOM NAV ================= */
.bottomnav {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--nav-h);
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: center;
  padding: 5px 5px 6px;
  background:
    linear-gradient(180deg, #2a303c, #171c26);
  border-top: 2px solid #3b3f48;
  box-shadow: 0 -4px 14px rgba(0,0,0,.5);
  z-index: 10;
}
.nav-item {
  height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  color: #aab1be;
  font-size: 10.5px;
  white-space: nowrap;
  border-radius: 8px;
  border: 1.5px solid transparent;
  position: relative;
}
.nav-item + .nav-item::before {
  content: ""; position: absolute; left: -3px; top: 18%; bottom: 18%;
  width: 1px; background: #353b47;
}
.nav-item svg { width: 24px; height: 22px; }
.nav-item.is-active {
  animation: navGlow 2.8s ease-in-out infinite;
  color: #fff;
  border-color: var(--gold);
  background: radial-gradient(90% 80% at 50% 100%, rgba(255,160,60,.35), transparent 70%), linear-gradient(#3a2e22, #22190f);
  box-shadow: 0 0 10px rgba(212,164,65,.45), inset 0 0 8px rgba(212,164,65,.25);
}
.nav-item.is-active::before, .nav-item.is-active + .nav-item::before { display: none; }
.nav-item:not(.is-active) svg path[fill="#f4e2b0"] { fill: currentColor; }

/* ================= SECONDARY PAGES ================= */
.page-head { padding: 18px 16px 4px; }
.page-head h2 {
  margin: 0;
  font-family: Cinzel, Georgia, serif;
  font-weight: 900;
  font-size: 26px;
  background: linear-gradient(#fff2c2, #e2ad42 60%, #b37a22);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.page-head p { margin: 4px 0 0; color: var(--text-dim); font-size: 13px; }

.deck-list { display: flex; flex-direction: column; }
.deck-card { padding: 12px 14px; display: flex; align-items: center; gap: 12px; }
.deck-card .deck-icon {
  width: 42px; height: 42px; flex-shrink: 0;
  border-radius: 8px;
  display: grid; place-items: center;
  background: linear-gradient(#3b80ea, #1f4ea5);
  font-family: Cinzel, serif; font-weight: 900; font-size: 18px;
}
.deck-card .deck-meta { flex: 1; min-width: 0; }
.deck-card .deck-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.deck-card .deck-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.deck-info-btn {
  display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0;
  background: none; border: none; padding: 0; margin: 0;
  text-align: left; cursor: pointer; color: inherit; font: inherit;
}
.deck-info-btn:hover .deck-name { text-decoration: underline; }

/* ============ DECK LIBRARY ============ */
.upload-deck-card {
  width: 100%; margin: 0 0 10px;
  padding: 12px 14px; display: flex; align-items: center; gap: 12px;
  border: 1px dashed var(--gold);
  cursor: pointer; text-align: left; font: inherit; color: inherit;
}
.upload-deck-card .upload-deck-icon {
  width: 42px; height: 42px; flex-shrink: 0; border-radius: 8px;
  display: grid; place-items: center;
  background: rgba(217, 169, 67, .18); color: var(--gold);
  font-size: 22px; font-weight: 700;
}
.upload-deck-card .deck-name, .upload-deck-card .deck-sub { display: block; }

.library-tabs { display: flex; gap: 6px; margin: 10px 0 8px; }
.library-tab {
  flex: 1; padding: 8px 0; border-radius: 8px;
  background: none; border: 1px solid var(--border-brown);
  color: var(--text-dim); font: inherit; font-weight: 600; font-size: 13px; cursor: pointer;
}
.library-tab.is-active { background: var(--gold); border-color: var(--gold); color: #2a2110; }

.library-filters { display: flex; gap: 8px; margin-bottom: 8px; }
.library-select {
  flex: 1; min-width: 0; padding: 7px 8px; border-radius: 8px;
  border: 1px solid var(--border-brown);
  background: var(--bg-panel-2); color: inherit; font: inherit; font-size: 12.5px;
}

/* Tighter than a normal .deck-card so more decks fit on screen at once, with
   its own scroll region so the tabs/filters above stay put while browsing. */
.library-scroll { max-height: 52vh; overflow-y: auto; }
.library-card { padding: 8px 10px; gap: 10px; margin-bottom: 6px; }
.library-card .deck-icon { width: 32px; height: 32px; font-size: 14px; background: linear-gradient(#8a5cd6, #4d2f96); }
.library-card .deck-rank, .library-card .library-rank {
  width: 32px; height: 32px; flex-shrink: 0; border-radius: 8px;
  display: grid; place-items: center;
  background: rgba(217, 169, 67, .18); color: var(--gold); font-weight: 800; font-size: 12px;
}
.library-card .deck-name { font-size: 13px; }
.library-card .deck-sub { font-size: 11px; }
.library-stats { display: flex; gap: 10px; margin-top: 2px; font-size: 11px; }
.library-stars { color: var(--gold); white-space: nowrap; }
.library-downloads { color: var(--text-dim); white-space: nowrap; }
.library-author { font-size: 11px; color: var(--text-dim); }

.deck-options { text-align: left; }
.deck-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 18px; }
.deck-stat-tile { padding: 10px 6px; border-radius: 6px; background: #0a1120; border: 1px solid #2a3a58; text-align: center; }
.deck-stat-value { font-size: 18px; font-weight: 700; }
.deck-stat-label { font-size: 10px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; margin-top: 2px; }
.study-override-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; color: var(--text-dim); }
.btn-small {
  padding: 8px 12px;
  border-radius: 5px;
  font-size: 13px; font-weight: 600;
  background: linear-gradient(#3b80ea, #2560c8);
  box-shadow: 0 2px 0 #163e85;
}
.btn-ghost { background: transparent; border: 1px solid #3a4a66; box-shadow: none; color: var(--text-dim); }
.empty-state { padding: 22px 16px; text-align: center; color: var(--text-dim); font-size: 13px; }
.empty-state .btn-small { margin-top: 12px; display: inline-block; }

.quest-bar { height: 8px; border-radius: 4px; background: #0a1120; border: 1px solid #2a3a58; margin-top: 6px; overflow: hidden; }
.quest-bar > div { height: 100%; background: linear-gradient(90deg, #d4a441, #f3d58a); }

/* ================= QUEST COMPLETED TOAST ================= */
.quest-toast {
  position: fixed; top: 40%; left: 50%; z-index: 300; text-align: center; pointer-events: none;
  width: min(90vw, 520px);
  transform: translate(-50%, -50%) scale(.92); opacity: 0;
  transition: opacity .4s ease, transform .4s ease;
}
.quest-toast.is-visible { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.quest-toast-title {
  font: 800 24px/1.3 Cinzel, Georgia, serif; color: #ffd93d; white-space: normal; overflow-wrap: break-word;
  text-shadow: -2px -2px 0 #201400, 2px -2px 0 #201400, -2px 2px 0 #201400, 2px 2px 0 #201400, 0 4px 10px #000a;
}
.quest-toast-xp {
  margin-top: 6px; font: 700 17px/1 Inter, system-ui, sans-serif; color: #c79bff;
  text-shadow: -1px -1px 0 #1c0f2a, 1px -1px 0 #1c0f2a, -1px 1px 0 #1c0f2a, 1px 1px 0 #1c0f2a, 0 2px 6px #000a;
}
@media (max-width: 600px) {
  .quest-toast-title { font-size: 18px; }
  .quest-toast-xp { font-size: 14px; }
}

/* A plain status line (pomodoro cancel/timeout) -- smaller and lower than
   the celebratory quest-toast above, since it isn't a reward moment. */
.pomodoro-status-toast {
  position: fixed; bottom: 90px; left: 50%; z-index: 300; text-align: center; pointer-events: none;
  width: min(90vw, 420px);
  padding: 10px 16px;
  border-radius: 10px;
  background: rgba(10, 16, 28, .92);
  border: 1px solid rgba(255, 255, 255, .12);
  font: 500 13px/1.4 Inter, system-ui, sans-serif; color: var(--text);
  transform: translate(-50%, 8px); opacity: 0;
  transition: opacity .3s ease, transform .3s ease;
}
.pomodoro-status-toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* The completion celebration -- reuses .quest-toast-title's look for the
   headline, but is its own box (a full reminder sentence + icon below the
   title needs more room than the quick generic quest-toast gives), stays
   up longer, and can be dismissed early with a click. */
.pomodoro-complete-toast {
  position: fixed; top: 32%; left: 50%; z-index: 300; text-align: center; cursor: pointer;
  width: min(92vw, 460px);
  padding: 18px 20px;
  border-radius: 14px;
  background: rgba(10, 16, 28, .95);
  border: 1px solid rgba(255, 217, 61, .35);
  box-shadow: 0 10px 30px rgba(0,0,0,.5);
  transform: translate(-50%, -50%) scale(.92); opacity: 0;
  transition: opacity .35s ease, transform .35s ease;
}
.pomodoro-complete-toast.is-visible { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.pomodoro-stretch-row {
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid rgba(255,255,255,.12);
  display: flex; align-items: center; gap: 10px; text-align: left;
  font: 500 13px/1.45 Inter, system-ui, sans-serif; color: var(--text-dim);
}
.pomodoro-stretch-icon { width: 30px; height: 30px; flex-shrink: 0; color: #7ce07c; }
.pomodoro-stretch-icon svg { width: 100%; height: 100%; }
@media (max-width: 600px) {
  .pomodoro-complete-toast .quest-toast-title { font-size: 18px; }
  .pomodoro-stretch-row { font-size: 12px; }
}

/* ================= GRADE BUTTONS (reused inside the encounter sheet) ================= */
.answer-actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin-top: 12px; }
.answer-actions button { padding: 10px 4px; border-radius: 6px; font-size: 13px; font-weight: 600; box-shadow: 0 2px 0 rgba(0,0,0,.4); }
.answer-actions small { display: block; font-weight: 400; font-size: 10px; opacity: .8; }
.a-again { background: #b8323a; } .a-hard { background: #9a6a22; } .a-good { background: #2f8a4a; } .a-easy { background: #2560c8; }

/* ================= ENCOUNTER SHEET ================= */
.encounter-sheet {
  position: absolute; left: 0; right: 0; bottom: 0;
  /* Translucent + blurred where there's no text/image of its own (the HP
     row, status row, padding) -- keeps the zoomed-in fight peeking through
     for immersion. .sheet-card-content (the actual card face) stays fully
     opaque below, for reading clarity. */
  background: rgba(17, 29, 49, .72);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-top: 1px solid #2a3a58;
  box-shadow: 0 -6px 16px rgba(0,0,0,.5);
  /* The top-third minimum is enforced in JS (EncounterPanel._maxSheetHeightPx),
     not here -- this app's height chain leaves a percentage max-height unable
     to resolve against a definite value (<main> has no explicit height/flex). */
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: height .25s ease;
  z-index: 5;
}
.sheet-handle {
  flex-shrink: 0;
  height: 18px;
  display: flex; align-items: center; justify-content: center;
  cursor: grab;
  touch-action: none;
}
.sheet-handle::before {
  content: ""; width: 36px; height: 4px; border-radius: 2px; background: #3a4a66;
}
.sheet-content { flex: 1; min-height: 0; padding: 4px 12px 12px; }

/* A card's own layout: the front/back/status scroll independently in
   .sheet-scroll; .sheet-footer (grade buttons, reveal button, the
   review-controller pad) stays outside that scroller so it's always
   reachable in one tap, however long the card content runs. */
.sheet-combat { display: flex; flex-direction: column; height: 100%; }
.sheet-scroll { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
/* The card face specifically (not the HP/status header above it) centers in
   whatever room is left: the sheet is now a fixed height for the whole
   fight (see world-controls.css's .in-combat rules), so a short card no
   longer just leaves dead space below it. Long content that overflows still
   scrolls normally -- centering only affects the resting/unscrolled position. */
.sheet-card-slot { flex: 0 0 auto; min-height: 0; display: flex; flex-direction: column; justify-content: flex-start; }
.sheet-footer { flex-shrink: 0; display: flex; flex-direction: column; align-items: center; width: 100%; position: relative; z-index: 9; }
.encounter-sheet.is-measuring .sheet-content,.encounter-sheet.is-measuring .sheet-combat { flex: none; height: auto; min-height: 0; }
.encounter-sheet.is-measuring .sheet-scroll,.encounter-sheet.is-measuring .sheet-card-slot { flex: none; overflow: visible; }

.sheet-peek-outer { display: flex; flex-direction: column; gap: 10px; }
.sheet-peek { display: flex; align-items: center; gap: 10px; }
.sheet-portrait {
  width: 56px; height: 56px; border-radius: 10px; object-fit: cover;
  background: transparent;
  border: 0;
}
.sheet-peek-text { flex: 1; min-width: 0; }
.sheet-peek-name { font-size: 14px; font-weight: 600; color: #fff; display: flex; align-items: center; gap: 6px; }
.sheet-peek-hp { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.sheet-peek-actions { display: flex; gap: 8px; }
.sheet-peek-actions .btn-small { flex: 1; }
.encounter-sheet.is-peek { left: 50%; right: auto; top: 10px; bottom: auto!important; width: min(430px, calc(100% - 24px)); height: auto!important; transform: translateX(-50%); border: 1px solid rgba(92,75,45,.72); border-radius: 9px; background: rgba(52,45,34,.7)!important; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); box-shadow: 0 4px 14px rgba(20,15,8,.25)!important; }
.encounter-sheet.is-peek .sheet-handle { display: none; }
.encounter-sheet.is-peek .sheet-content { padding: 10px; }
.encounter-sheet.is-peek .sheet-peek-outer { flex-direction: row; align-items: center; }
.encounter-sheet.is-peek .sheet-peek { flex: 1; min-width: 0; }
.encounter-sheet.is-peek .sheet-peek-name,.encounter-sheet.is-peek .sheet-peek-hp { color: #fff4dc; }
.encounter-sheet.is-peek .sheet-peek-actions { flex: 0 0 auto; }
.encounter-sheet.is-peek .sheet-peek-actions .btn-small { background: #7b6545; color: #fff4dc; opacity: 1; }

.tag {
  font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 8px;
  background: rgba(212,164,65,.25); color: var(--gold-light);
}

.sheet-card-status { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.tag-new { background: rgba(94, 203, 94, .25); color: #8fe08f; }
.level-label { --level-color: #9ba3a0; display: inline-flex; align-items: center; gap: 4px; line-height: 1; white-space: nowrap; color: var(--level-color); }
.level-label::before { content: ""; width: 12px; height: 14px; flex: 0 0 auto; background: var(--level-color); clip-path: polygon(50% 0,93% 18%,84% 73%,50% 100%,16% 73%,7% 18%); filter: drop-shadow(0 1px 0 rgba(0,0,0,.35)); }
.level-tier-low { --level-color: #9ba3a0; }.level-tier-mid { --level-color: #78a96d; }.level-tier-high { --level-color: #6597cf; }.level-tier-legend { --level-color: #d1a851; }
.tag.level-label::before { width: 9px; height: 10px; }
.explain-btn { font-size: 11px; padding: 4px 10px; min-height: auto; }

.sheet-message { padding: 20px 10px; text-align: center; color: var(--text-dim); font-size: 13px; }
.sheet-message .btn-small { margin-top: 12px; }

.sheet-hp-row { margin-bottom: 10px; }
.sheet-hp-label { display: flex; justify-content: space-between; font-size: 12px; color: var(--text-dim); }
.sheet-hp-bar { height: 10px; border-radius: 3px; background: #0a1120; border: 1px solid #2a3a58; overflow: hidden; margin-top: 4px; }
.sheet-hp-bar > div { height: 100%; background: linear-gradient(#5ecb5e, #2f8a4a); transition: width .35s ease; }

.sheet-card-content {
  padding: 14px;
  border-radius: 8px;
  background: linear-gradient(#f6ecd0, #e3cf9f);
  color: #2b1e0e;
  box-shadow: inset 0 0 0 2px #b8975c;
  font-size: 15px; line-height: 1.4; text-align: center;
  overflow-wrap: anywhere;
}
.sheet-card-content img { max-width: 100%; max-height: 150px; object-fit: contain; cursor: zoom-in; }
.type-answer-form { display: flex; flex-direction: column; gap: 8px; width: 100%; max-width: 680px; margin: 0 auto; }
.type-answer-input { min-height: 48px; }
.type-answer-form .btn-primary { width: 100%; }
.quiz-feedback.is-wrong { color: #c94a3f; font-weight: 700; }
.quiz-feedback.is-correct { color: #3aa65a; font-weight: 700; }

/* Correct/wrong flash around the card face for a typed answer -- the only
   feedback that reliably reads as "yes/no" without depending on the player
   noticing a small status line under the input. */
@keyframes card-flash-correct { 0% { box-shadow: 0 0 0 4px rgba(58,166,90,0); } 25% { box-shadow: 0 0 0 4px rgba(58,166,90,.9); } 100% { box-shadow: 0 0 0 4px rgba(58,166,90,0); } }
@keyframes card-flash-wrong { 0% { box-shadow: 0 0 0 4px rgba(201,74,63,0); } 25% { box-shadow: 0 0 0 4px rgba(201,74,63,.9); } 100% { box-shadow: 0 0 0 4px rgba(201,74,63,0); } }
.sheet-card-content.is-flash-correct { animation: card-flash-correct .9s ease; }
.sheet-card-content.is-flash-wrong { animation: card-flash-wrong .9s ease; }
.sheet-card-answer {
  margin-top: 10px; padding-top: 10px; border-top: 1px dashed #a4844c;
  font-weight: 500; text-align: center;
}
.sheet-reveal-btn { display: block; width: min(100%, 680px); margin: 12px auto 0; }

@media(pointer:coarse),(max-width:600px){
  .encounter-sheet.is-reading .sheet-content{padding:8px 5px}
  .encounter-sheet.is-reading .sheet-card-status{margin-bottom:2px}
  .encounter-sheet.is-reading .sheet-card-content{margin:8px auto;padding:11px;line-height:1.5!important}
  .encounter-sheet.is-reading .answer-actions{margin-top:8px}
  .encounter-sheet.is-reading .sheet-reveal-btn{margin-top:8px!important}
}

.lightbox {
  position: fixed; inset: 0; z-index: 30;
  background: rgba(0,0,0,.9);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.lightbox-img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* Death (app.js playerDefeatAndRespawn): darkness closes in from the edges,
   YOU DIED resolves slowly on a dark band, then it all lifts at home. */
@property --close { syntax: "<percentage>"; inherits: false; initial-value: 140%; }
.defeat-fade { position: fixed; inset: 0; z-index: 10000; pointer-events: none; display: flex; flex-direction: column; align-items: center; justify-content: center; transition: opacity 1.2s ease; }
.defeat-fade.is-lifting { opacity: 0; }
.defeat-dark {
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 45%, transparent 0, transparent var(--close), rgba(0, 0, 0, .96) calc(var(--close) + 22%));
  transition: --close 1.3s cubic-bezier(.55, 0, .75, .3), background-color .4s ease 1s;
}
.defeat-fade.is-closing .defeat-dark { --close: 0%; background-color: #000; }
.defeat-band {
  position: relative; width: 100%; padding: 4.5vh 0; display: grid; place-items: center;
  background: linear-gradient(90deg, transparent, rgba(40, 0, 0, .55) 18%, rgba(55, 2, 4, .7) 50%, rgba(40, 0, 0, .55) 82%, transparent);
  box-shadow: 0 0 60px rgba(90, 0, 0, .35);
  opacity: 0; transform: scaleY(.2); transition: opacity 1.4s ease, transform 1.8s cubic-bezier(.2, .8, .2, 1);
}
.defeat-fade.is-titled .defeat-band { opacity: 1; transform: none; }
.defeat-text {
  font: 700 clamp(44px, 10vw, 96px)/1 Georgia, "Times New Roman", serif; color: #a3140f; text-transform: uppercase;
  letter-spacing: .06em; text-shadow: 0 0 18px rgba(200, 20, 10, .55), 0 3px 0 #2a0302, 0 0 60px rgba(120, 0, 0, .6);
  opacity: 0; filter: blur(12px); transform: scale(1.35);
  transition: opacity 1.6s ease .2s, filter 1.8s ease .2s, transform 4.2s cubic-bezier(.15, .75, .25, 1) .2s, letter-spacing 4.2s cubic-bezier(.15, .75, .25, 1) .2s;
}
.defeat-fade.is-titled .defeat-text { opacity: 1; filter: blur(0); transform: none; letter-spacing: .28em; }
.defeat-sub { position: relative; margin-top: 3vh; font: 600 15px/1.3 system-ui, sans-serif; color: #a79f93; letter-spacing: .08em; opacity: 0; transition: opacity 1.2s ease 2.2s; }
.defeat-fade.is-titled .defeat-sub { opacity: 1; }
/* while dying: the card sheet sinks away and takes no taps */
body.is-dying .encounter-sheet { filter: grayscale(1) brightness(.45); pointer-events: none; transition: filter 1.2s ease; }
@media (prefers-reduced-motion: reduce) {
  .defeat-text { transform: none; filter: none; transition: opacity 1s ease; }
  .defeat-band { transform: none; }
}

.deck-card.is-active-deck { box-shadow: inset 0 0 0 1px var(--gold); }

/* ================= INVENTORY ================= */
.inventory-layout { display: flex; gap: 12px; padding: 4px 14px 14px; align-items: flex-start; }
.inventory-left { flex: 0 0 42%; min-width: 0; }
.inventory-right { flex: 1; min-width: 0; }

.inventory-character {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 16px 10px; text-align: center;
  background: var(--bg-panel); border-radius: 10px; border: 1px solid #24324a;
}
.inventory-portrait {
  width: 100%; max-width: 140px; aspect-ratio: 1213 / 1296; object-fit: contain;
  background: radial-gradient(circle at 50% 35%, #1c2a44, #0c1220);
  border-radius: 10px; border: 1px solid #2a3a58; padding: 6px;
}
.inventory-name { font-weight: 700; font-size: 15px; margin-top: 4px; }
.inventory-level { font-size: 12px; color: var(--text-dim); }
.inventory-character .btn-small { width: 100%; margin-top: 6px; }
.equipment-slots { width: 100%; display: grid; gap: 5px; margin-top: 6px; }
.equipment-slot { display: flex; justify-content: space-between; gap: 8px; padding: 6px 8px; border: 1px solid #2a3a58; border-radius: 6px; background: #111b2e; font-size: 11px; text-align: left; }
.equipment-slot-label { color: var(--text-dim); font-weight: 700; }
.equipment-slot-value { flex: 1; min-width: 0; overflow: hidden; color: var(--text); text-overflow: ellipsis; white-space: nowrap; }

.inventory-stats {
  background: var(--bg-panel); border-radius: 10px; border: 1px solid #24324a;
  padding: 10px; display: flex; flex-direction: column; gap: 8px;
}
.stats-back { align-self: flex-start; }
.stat-list { display: flex; flex-direction: column; gap: 8px; max-height: 60vh; overflow-y: auto; }
.stat-row {
  padding: 8px 10px; border-radius: 8px; background: #101b2e; border: 1px solid #223252; cursor: pointer;
}
.stat-row-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.stat-name { font-size: 12.5px; font-weight: 600; color: #fff; }
.stat-value { font-size: 13px; font-weight: 700; color: var(--gold-light); }
.stat-plain { font-size: 11px; color: var(--blue-light); margin-top: 4px; }
.stat-math { font-size: 10.5px; color: #5a6478; margin-top: 4px; line-height: 1.4; }

.inventory-tabs { display: flex; gap: 6px; margin-bottom: 10px; }
.inventory-tab-btn {
  flex: 1; padding: 8px 4px; border-radius: 7px; font-size: 12px; font-weight: 600;
  background: #101b2e; border: 1px solid #223252; color: var(--text-dim);
}
.inventory-tab-btn.is-active {
  background: linear-gradient(#3b80ea, #2560c8); border-color: #2560c8; color: #fff;
}
.inventory-list { display: flex; flex-direction: column; gap: 8px; max-height: 60vh; overflow-y: auto; }
.inventory-item { padding: 10px 12px; display: flex; align-items: center; gap: 10px; }
.inventory-item-pic {
  width: 36px; height: 36px; border-radius: 6px; object-fit: cover; flex-shrink: 0;
  background: #101b2e; border: 1px solid #223252;
}
.inventory-item-info { flex: 1; min-width: 0; }
.inventory-item-name { font-size: 13px; font-weight: 600; }
.inventory-item-desc { font-size: 11px; color: var(--text-dim); margin-top: 2px; }
.inventory-item-qty { font-size: 12px; color: var(--gold-light); font-weight: 700; flex-shrink: 0; }

/* ================= MODAL ================= */
.modal {
  position: absolute; inset: 0; z-index: 20;
  display: grid; place-items: center;
  background: rgba(3,6,12,.7);
  backdrop-filter: blur(2px);
  padding: 20px;
}
.modal-card { margin: 0; width: 100%; padding: 22px 18px; text-align: center; animation: pop .25s ease; }
@keyframes pop { from { transform: scale(.92); opacity: 0; } }
.modal-card h3 {
  margin: 0 0 6px;
  font-family: Cinzel, serif; font-weight: 900; font-size: 22px; color: var(--gold-light);
}
.modal-card p { margin: 6px 0; color: var(--text-dim); font-size: 14px; }
.modal-card .reward { display: flex; justify-content: center; gap: 16px; margin: 14px 0; font-weight: 600; }
.modal-actions { display: flex; gap: 8px; justify-content: center; margin-top: 14px; }

/* ================= ACCOUNT & CONNECTION ================= */
.icon-btn { position: relative; }
/* Friends online, on the Friends button (app.js refreshFriendsBadge). */
.friends-count {
  position: absolute; top: -5px; right: -6px; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 8px; background: #3f8a3a; border: 1.5px solid #1d2a1a; color: #fff;
  font: 700 10px/13px system-ui, sans-serif; text-align: center; pointer-events: none;
}
.friends-count[hidden] { display: none; }
/* Painted by Astra (assets/ui/friends-button-sheet.png, cut to friends.png + friends-hover.png). */
.friends-btn .friends-icon { width: 26px; height: 26px; object-fit: contain; pointer-events: none; }
.friends-btn:hover .friends-icon, .friends-btn:focus-visible .friends-icon { content: url("assets/ui/friends-hover.png"); }
.net-dot {
  position: absolute; right: 0; top: 1px;
  width: 8px; height: 8px; border-radius: 50%;
  border: 1.5px solid #0b1322;
  background: #6b7385;
}
.net-dot[data-state="open"] { background: #4cd137; box-shadow: 0 0 6px rgba(76, 209, 55, .7); }
.net-dot[data-state="connecting"],
.net-dot[data-state="reconnecting"] { background: #e8c547; animation: netPulse 1s ease-in-out infinite; }
.net-dot[data-state="closed"] { background: #d1453b; }
@keyframes netPulse { 50% { opacity: .35; } }

.net-badge {
  position: absolute; right: 8px; top: 8px; z-index: 4;
  padding: 3px 8px;
  border-radius: 10px;
  background: rgba(8, 12, 22, .7);
  border: 1px solid rgba(255, 255, 255, .12);
  font-size: 10.5px; color: rgba(255, 255, 255, .85);
  pointer-events: none;
}
.net-badge[data-state="reconnecting"], .net-badge[data-state="closed"] { color: #ffd98a; }

.auth-form { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; text-align: left; }
.text-input {
  width: 100%;
  padding: 10px 12px;
  border-radius: 6px;
  border: 1px solid #34466a;
  background: #0a1120;
  color: var(--text);
  font: inherit; font-size: 14px;
}
.text-input:focus { outline: none; border-color: var(--gold); box-shadow: 0 0 0 2px rgba(212, 164, 65, .25); }
.study-number-input { width: 80px; display: inline-block; margin-left: 8px; }
.form-error { min-height: 1.2em; margin: 0 !important; color: #ff8a80 !important; font-size: 12.5px !important; }
.social-buttons { display: grid; gap: 8px; margin: 10px 0 4px; }
.social-btn { width: 100%; }
.auth-or { margin: 12px 0 0; font-size: 13px; opacity: .8; }
/* The welcome / sign-in screens over the loading camp on a first visit (app.js boot) */
body.welcoming .modal { position: fixed; z-index: 20001; background: rgba(8, 6, 12, .35); backdrop-filter: none; }
body.welcoming .loading-bar, body.welcoming .loading-step, body.welcoming .loading-tip { visibility: hidden; }
body.welcoming .loading-card { margin-bottom: 62vh; }
.welcome-play { width: 100%; margin-top: 10px; padding-top: 12px; padding-bottom: 12px; font-size: 16px; }
.auth-links.welcome-links { justify-content: center; }
.auth-links { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 6px; }
.link-btn {
  margin-top: 10px;
  color: var(--gold-light);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.btn-small:disabled { opacity: .6; cursor: default; }

@media (prefers-reduced-motion: reduce) {
  .net-dot { animation: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .modal-card, .view.is-active { animation: none !important; }
}

/* ============ HOME HEADER ACTIONS (Sync / Daily quests) ============ */
.home-header-actions { display: flex; gap: 6px; flex-shrink: 0; }

/* ============ DECK DETAIL (browse/edit cards + settings) ============ */
.deck-detail-study-btn { width: calc(100% - 16px); margin: 4px 8px 10px; }

.deck-card-list { display: flex; flex-direction: column; padding: 0 8px; }
.deck-card-row { padding: 0; margin: 0 0 6px; overflow: hidden; }
.deck-card-row.is-edited { box-shadow: inset 0 0 0 1px var(--gold); }
.deck-card-summary {
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px 12px;
  cursor: pointer;
  list-style: none;
}
.deck-card-summary::-webkit-details-marker { display: none; }
.deck-card-preview-front { font-size: 13.5px; font-weight: 600; }
.deck-card-preview-back { font-size: 12px; color: var(--text-dim); }
.deck-card-row[open] .deck-card-summary { border-bottom: 1px solid #2a3a58; }
.deck-card-editor { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px 12px; }
.deck-card-editor label { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; }
.deck-card-input { resize: vertical; font-size: 13.5px; text-transform: none; letter-spacing: normal; color: var(--text); }

/* ============ DECK EDIT BAR (persistent "unsaved changes" prompt) ============ */
.deck-edit-bar {
  position: absolute; left: 8px; right: 8px; bottom: calc(var(--nav-h) + 8px);
  z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px;
  border-radius: 8px;
  background: linear-gradient(180deg, var(--bg-panel-2), var(--bg-panel));
  border: 2px solid var(--gold);
  box-shadow: 0 4px 16px rgba(0,0,0,.5);
  font-size: 13px;
  animation: pop .2s ease;
}
.deck-edit-bar-actions { display: flex; gap: 6px; flex-shrink: 0; }

/* Featured decks (app.js FEATURED_DECKS), above the library's tabs */
.library-featured { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 14px; }
.library-featured:empty { display: none; }
.library-featured-title { margin: 0; font: 700 12px NunitoSans, system-ui, sans-serif; text-transform: uppercase; letter-spacing: .5px; opacity: .8; }
.library-card.is-featured { border-color: #c8a04a88; }
