* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  height: 100%;
  font-family: "Segoe UI", Roboto, Arial, sans-serif;
  background: #FDF9F2;
  user-select: none;
  -webkit-user-select: none;
  overflow: hidden;
}

.screen {
  display: none;
  height: 100%;
  flex-direction: column;
  align-items: center;
  padding: 4vh 5vw;
  overflow-y: auto;
}
.screen.active { display: flex; }

/* ---------- HOME ---------- */
.hero-img {
  width: clamp(110px, 20vh, 170px);
  border-radius: 24px;
  margin-bottom: 1.5vh;
  animation: bob 2.6s ease-in-out infinite;
}
.title {
  font-size: clamp(28px, 6vw, 44px);
  font-weight: 800;
  color: #3C3489;
  text-align: center;
}
.subtitle {
  font-size: clamp(16px, 3vw, 22px);
  color: #8a867c;
  margin: 8px 0 4vh;
  text-align: center;
}
.char-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: center;
  max-width: 900px;
}
.char-card {
  width: clamp(130px, 26vw, 170px);
  border: 4px solid transparent;
  border-radius: 24px;
  padding: 14px 10px;
  text-align: center;
  background: #fff;
  box-shadow: 0 4px 14px rgba(60, 52, 137, 0.10);
  cursor: pointer;
  transition: transform 0.15s;
}
.char-card:active { transform: scale(0.94); }
.char-card.selected { border-color: #7F77DD; transform: scale(1.04); }
.char-card svg, .char-card .char-img { width: 100%; height: auto; }

/* ---------- PAINTED BUDDY ART ---------- */
.char-img {
  display: block;
  width: 100%;
  height: auto;
  user-select: none;
  -webkit-user-drag: none;
}
.char-holder .char-img {
  /* the art is a bust that fills the frame, so the name needs its own gap
     or it sits directly on the buddy shoulders */
  margin-bottom: 8px;
  /* the idle bob comes from .bobbing on the holder -- do not add a second
     idle animation here or the two stack and the buddy looks jittery */
  transform-origin: 50% 100%;
}
/* While the buddy is speaking the bob quickens and gains a slight squash,
   which reads as talking without needing a separate mouth drawing. */
.char-holder.speaking .char-img {
  animation: buddy-talk 0.42s ease-in-out infinite;
}
@keyframes buddy-talk {
  0%, 100% { transform: scale(1, 1) translateY(0); }
  50%      { transform: scale(1.012, 0.978) translateY(1.4%); }
}
@media (prefers-reduced-motion: reduce) {
  .char-holder .char-img, .char-holder.speaking .char-img { animation: none; }
}
.char-card p {
  font-size: clamp(14px, 2.6vw, 18px);
  font-weight: 700;
  margin-top: 6px;
  color: #444;
}
.big-btn {
  margin-top: 4vh;
  font-size: clamp(20px, 4vw, 28px);
  font-weight: 800;
  color: #fff;
  background: #7F77DD;
  border: none;
  border-radius: 999px;
  padding: 16px 54px;
  cursor: pointer;
  box-shadow: 0 6px 0 #534AB7;
  transition: transform 0.1s, box-shadow 0.1s;
}
.big-btn:active { transform: translateY(4px); box-shadow: 0 2px 0 #534AB7; }
.big-btn:disabled { opacity: 0.4; }

/* ---------- VOICE PICKER ---------- */
.voices-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(92vw, 560px);
}
.voice-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 16px;
  padding: 10px 14px;
}
.voice-row .vr-name {
  font-size: clamp(13px, 2.4vw, 16px);
  font-weight: 800;
  color: #2c2a24;
  width: 92px;
  flex-shrink: 0;
}
.voice-row select {
  flex: 1;
  min-width: 0;
  font-size: clamp(12px, 2.2vw, 14px);
  padding: 8px;
  border: 2px solid #e3ddd0;
  border-radius: 10px;
  background: #FDF9F2;
  color: #2c2a24;
}
.voice-row .vr-test {
  flex-shrink: 0;
  font-size: clamp(12px, 2.2vw, 14px);
  font-weight: 700;
  color: #534AB7;
  background: #EEEDFE;
  border: 2px solid #CECBF6;
  border-radius: 999px;
  padding: 8px 14px;
  cursor: pointer;
}
.voice-row .vr-test:active { transform: scale(0.95); }
.voices-note {
  font-size: clamp(12px, 2.2vw, 14px);
  color: #8a867c;
  text-align: center;
  max-width: 480px;
  line-height: 1.5;
}

/* ---------- LESSON PICKER ---------- */
.toggle-row {
  display: flex;
  gap: 10px;
  width: min(92vw, 520px);
  margin-bottom: 14px;
}
.toggle-btn {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 16px;
  padding: 10px 8px;
  cursor: pointer;
  font-size: clamp(14px, 2.6vw, 18px);
  font-weight: 800;
  color: #8a867c;
}
.toggle-btn span {
  font-size: clamp(11px, 2vw, 13px);
  font-weight: 600;
}
.toggle-btn.selected {
  border-color: #7F77DD;
  background: #EEEDFE;
  color: #3C3489;
}

.lesson-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: min(92vw, 520px);
}
.lesson-btn {
  display: flex;
  flex-direction: column;
  gap: 3px;
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 18px;
  padding: 14px 20px;
  cursor: pointer;
  text-align: left;
  transition: transform 0.12s, border-color 0.12s;
}
.lesson-btn:active { transform: scale(0.97); border-color: #7F77DD; }
.lesson-title {
  font-size: clamp(16px, 3vw, 21px);
  font-weight: 800;
  color: #2c2a24;
}
.lesson-sub {
  font-size: clamp(12px, 2.2vw, 15px);
  color: #8a867c;
  font-weight: 600;
}

/* ---------- PARENTAL GATE ---------- */
.gate-question {
  font-size: clamp(26px, 6vw, 40px);
  font-weight: 800;
  color: #2c2a24;
  margin: 2vh 0 1vh;
}
.gate-input {
  width: 140px;
  font-size: clamp(22px, 5vw, 32px);
  font-weight: 800;
  text-align: center;
  border: 3px solid #CECBF6;
  border-radius: 14px;
  padding: 10px;
  background: #fff;
  color: #2c2a24;
}
.gate-error {
  color: #A32D2D;
  font-weight: 700;
  font-size: clamp(13px, 2.4vw, 16px);
  margin-top: 8px;
}

/* ---------- PAYWALL ---------- */
.plan-cards {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 1vh;
}
.plan-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: clamp(150px, 38vw, 210px);
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 20px;
  padding: 22px 14px 16px;
  cursor: pointer;
}
.plan-card.best { border-color: #7F77DD; background: #EEEDFE; }
.plan-card:disabled { opacity: 0.55; }
.plan-badge {
  position: absolute;
  top: -12px;
  background: #7F77DD;
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  padding: 4px 12px;
  border-radius: 999px;
}
.plan-name { font-size: clamp(15px, 2.8vw, 18px); font-weight: 800; color: #3C3489; }
.plan-price { font-size: clamp(17px, 3.2vw, 22px); font-weight: 800; color: #2c2a24; }
.plan-sub { font-size: clamp(11px, 2vw, 13px); color: #8a867c; font-weight: 600; }
.pw-note {
  margin-top: 2vh;
  font-size: clamp(12px, 2.2vw, 14px);
  color: #8a867c;
  text-align: center;
  max-width: 460px;
  line-height: 1.5;
}

/* ---------- CREDITS ---------- */
/* The balance and the way to top it up sit side by side: tapping the
   balance was the only route to buying credits, which nobody guessed. */
/* Sits under the balance on the upload screen. Deliberately quiet -- it is
   for the parent, not the child -- but always visible, because the moment it
   is needed is the moment a balance looks wrong. */
.code-link {
  background: none;
  border: none;
  font-family: inherit;
  font-size: clamp(12px, 2.3vw, 14px);
  font-weight: 700;
  color: #6C63FF;
  text-decoration: underline;
  cursor: pointer;
  margin-bottom: 12px;
  padding: 4px 8px;
}
.code-link:active { opacity: 0.6; }
.rec-warn {
  background: #FFF6E5;
  border: 2px solid #F5D48A;
  border-radius: 14px;
  padding: 10px 14px;
}

.credit-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: nowrap;
  margin-bottom: 14px;
}
.credit-badge {
  font-size: clamp(15px, 3vw, 19px);
  font-weight: 800;
  color: #854F0B;
  background: #FAEEDA;
  border: 3px solid #FAC775;
  border-radius: 999px;
  padding: 7px 20px;
  cursor: pointer;
}
.credit-buy {
  font-size: clamp(13px, 2.5vw, 16px);
  font-weight: 800;
  color: #fff;
  background: #6C63FF;
  border: 3px solid #5A51F0;
  border-radius: 999px;
  padding: 7px 18px;
  cursor: pointer;
}
.credit-buy:active { transform: translateY(1px); }

/* Install prompt on the home screen. Hidden by default and revealed by JS
   only in a browser that can actually install it -- the Play/App Store
   builds are already installed, so the button never appears there. */
.install-btn {
  font-size: clamp(13px, 2.5vw, 16px);
  font-weight: 800;
  color: #3B357A;
  background: #EDEBFF;
  border: 3px solid #C9C4FF;
  border-radius: 999px;
  padding: 8px 22px;
  margin-bottom: 10px;
  cursor: pointer;
}
.install-btn:active { transform: translateY(1px); }
.credit-badge.credit-low { color: #A32D2D; background: #FCEBEB; border-color: #F7C1C1; }
.confirm-file {
  font-size: clamp(15px, 2.8vw, 19px);
  font-weight: 800;
  color: #2c2a24;
  margin-bottom: 2vh;
  text-align: center;
  max-width: 92vw;
}
.cost-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: #FAEEDA;
  border: 3px solid #FAC775;
  border-radius: 20px;
  padding: 18px 32px;
  margin-bottom: 2vh;
}
.cost-label { font-size: clamp(12px, 2.2vw, 15px); font-weight: 700; color: #854F0B; }
.cost-amount { font-size: clamp(28px, 6vw, 40px); font-weight: 800; color: #633806; }
.cost-balance { font-size: clamp(12px, 2.2vw, 14px); font-weight: 600; color: #8a867c; }
.pw-credits-note {
  font-size: clamp(12px, 2.3vw, 15px);
  font-weight: 700;
  color: #854F0B;
  text-align: center;
  margin-top: 1.5vh;
  max-width: 460px;
}

/* ---------- UPLOAD ---------- */
.file-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: min(92vw, 460px);
  border: 3px dashed #CECBF6;
  border-radius: 20px;
  background: #fff;
  padding: 30px 20px;
  cursor: pointer;
}
.file-drop:active { transform: scale(0.98); border-color: #7F77DD; }
.fd-icon { font-size: 42px; }
.fd-main { font-size: clamp(16px, 3vw, 20px); font-weight: 800; color: #3C3489; }
.fd-sub { font-size: clamp(12px, 2.2vw, 14px); color: #8a867c; }
.upload-status {
  margin-top: 2vh;
  font-size: clamp(14px, 2.6vw, 17px);
  font-weight: 600;
  color: #5F5E5A;
  text-align: center;
  max-width: 520px;
  line-height: 1.5;
  min-height: 44px;
}

/* ---------- PREVIEW ---------- */
.preview-title-input {
  width: min(92vw, 520px);
  font-size: clamp(16px, 3vw, 20px);
  font-weight: 800;
  color: #2c2a24;
  border: 3px solid #e3ddd0;
  border-radius: 14px;
  padding: 10px 14px;
  margin-bottom: 12px;
  background: #fff;
  text-align: center;
}
.preview-list {
  width: min(92vw, 560px);
  max-height: 52vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 12px;
}
.preview-item {
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 16px;
  padding: 12px 16px;
  text-align: left;
}
.pv-q { font-size: clamp(14px, 2.6vw, 17px); font-weight: 800; color: #2c2a24; margin-bottom: 6px; line-height: 1.35; }
.pv-choices { display: flex; flex-direction: column; gap: 3px; margin-bottom: 6px; }
.pv-choice { font-size: clamp(13px, 2.4vw, 15px); color: #5F5E5A; }
.pv-correct { font-size: clamp(13px, 2.4vw, 15px); font-weight: 700; color: #0F6E56; }
.pv-explain { font-size: clamp(12px, 2.2vw, 14px); color: #8a867c; margin-bottom: 6px; }
.pv-remove {
  font-size: clamp(11px, 2vw, 13px);
  font-weight: 700;
  color: #A32D2D;
  background: #FCEBEB;
  border: 2px solid #F7C1C1;
  border-radius: 999px;
  padding: 5px 12px;
  cursor: pointer;
}

/* custom lesson delete */
.lesson-btn { position: relative; }
.lesson-del {
  position: absolute;
  top: 8px;
  right: 12px;
  font-size: 15px;
  font-weight: 800;
  color: #A32D2D;
  padding: 4px 8px;
}

/* ---------- QUIZ ---------- */
#quiz-screen { padding-top: 2vh; }
.quiz-top {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;          /* four controls do not fit one phone line */
  width: min(92vw, 640px);
  margin-bottom: 1vh;
  gap: 8px;
}
.quiz-top .progress { margin-bottom: 0; }
.tiny-btn {
  font-size: clamp(12px, 2.2vw, 15px);
  font-weight: 700;
  color: #8a867c;
  background: #fff;
  border: 2px solid #e3ddd0;
  border-radius: 999px;
  padding: 7px 14px;
  cursor: pointer;
  white-space: nowrap;
}
.tiny-btn:active { transform: scale(0.95); border-color: #CECBF6; color: #534AB7; }
/* ---------- mode picker ---------- */
.mode-cards {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
  max-width: 560px;
  margin: 1vh 0 2vh;
}
@media (min-width: 720px) {
  .mode-cards { flex-direction: row; max-width: 900px; }
  .mode-card { flex: 1; }
}
.mode-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  text-align: left;
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 22px;
  padding: 14px 14px 12px;
  cursor: pointer;
  font-family: inherit;
  transition: transform 0.12s ease, border-color 0.12s ease;
}
.mode-card:active { transform: scale(0.98); border-color: #CECBF6; }
.mc-name {
  font-size: clamp(19px, 4.4vw, 24px);
  font-weight: 800;
  color: #534AB7;
}
.mc-desc {
  font-size: clamp(12px, 2.6vw, 15px);
  font-weight: 600;
  color: #6b6862;
  line-height: 1.35;
}
.mc-shot {
  width: 100%;
  height: auto;
  border-radius: 14px;
  border: 2px solid #efeada;
  margin-top: 6px;
  display: block;
}
.upload-cta { margin-top: 1.4vh; }
.small-btn.muted, .tiny-btn.muted {
  background: #f1efe8;
  color: #a09a8c;
  border-color: #ddd6c6;
}
.small-btn:disabled, .tiny-btn:disabled { opacity: 0.4; cursor: default; }

.cost-basis {
  display: block; margin-top: 6px;
  font-size: clamp(11px, 2.1vw, 13px); font-weight: 600; color: #8a867c;
}

/* ---------- AI loading ----------
   A conversion takes 15-60s. Without visible motion a parent assumes the app
   has frozen and taps away, which loses the quiz they just paid credits for. */
.ai-loader {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  margin: 2.5vh 0 1vh;
}
.ail-ring {
  width: 54px; height: 54px; border-radius: 50%;
  border: 6px solid #EDEBFC;
  border-top-color: #534AB7;
  animation: ailSpin 0.9s linear infinite;
}
@keyframes ailSpin { to { transform: rotate(360deg); } }
.ail-step {
  font-size: clamp(14px, 3vw, 17px); font-weight: 800; color: #534AB7;
  margin: 0; text-align: center; min-height: 1.3em;
  animation: ailFade 0.4s ease;
}
@keyframes ailFade { from { opacity: 0; } to { opacity: 1; } }
.ail-note {
  font-size: clamp(11px, 2.2vw, 13px); font-weight: 600; color: #8a867c;
  margin: 0; text-align: center; max-width: 320px;
}
@media (prefers-reduced-motion: reduce) {
  .ail-ring { animation-duration: 3s; }
}

/* ---------- manual payment ---------- */
.pay-methods { display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 420px; margin: 2vh 0; }
.pay-method {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  background: #fff; border: 3px solid #e3ddd0; border-radius: 18px;
  padding: 14px 18px; cursor: pointer; font-family: inherit; text-align: left;
}
.pay-method:active { transform: scale(0.98); border-color: #CECBF6; }
.pm-name { font-size: clamp(18px, 4vw, 22px); font-weight: 800; color: #534AB7; }
.pm-sub { font-size: clamp(12px, 2.4vw, 14px); font-weight: 600; color: #6b6862; }
.pi-amount { font-size: clamp(18px, 4vw, 22px); font-weight: 800; color: #2f7d3a; margin: 0 0 1.4vh; }
.pi-qr {
  width: min(230px, 62vw); height: auto; border-radius: 14px;
  border: 3px solid #e3ddd0; background: #fff; display: block;
}
.pi-or { font-size: clamp(11px, 2.2vw, 13px); font-weight: 700; color: #8a867c; margin: 1.4vh 0 0.4vh; }
.pi-number {
  font-family: ui-monospace, Consolas, monospace;
  font-size: clamp(19px, 5vw, 26px); font-weight: 800; letter-spacing: 1px;
  color: #2c2a24; margin: 0; cursor: pointer; user-select: text;
}
.pi-name { font-size: clamp(12px, 2.4vw, 14px); font-weight: 700; color: #6b6862; margin: 2px 0 0; }
.pi-ref {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: #fff; border: 3px dashed #CECBF6; border-radius: 16px;
  padding: 10px 16px; margin: 2vh 0 1vh;
}
.pi-must {
  font-size: clamp(12px, 2.5vw, 15px); font-weight: 700; color: #854F0B;
  background: #FAEEDA; border: 2px solid #FAC775; border-radius: 14px;
  padding: 10px 16px; margin: 1.6vh 0 0.6vh;
  text-align: center; max-width: 440px; line-height: 1.45;
}
.msg-text {
  width: min(92vw, 480px); min-height: 130px;
  font-family: inherit; font-size: clamp(14px, 2.8vw, 16px);
  border: 3px solid #e3ddd0; border-radius: 16px; padding: 12px 14px;
  background: #fff; color: #2c2a24; resize: vertical;
  margin-top: 1.5vh; user-select: text;
}
.pi-ref-label { font-size: clamp(11px, 2.2vw, 13px); font-weight: 700; color: #6b6862; }
.pi-ref-code {
  font-family: ui-monospace, Consolas, monospace;
  font-size: clamp(18px, 4.6vw, 24px); font-weight: 800; letter-spacing: 2px;
  color: #534AB7; cursor: pointer; user-select: text;
}

.rec-code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: clamp(22px, 6vw, 34px);
  font-weight: 800;
  letter-spacing: 2px;
  color: #2c2a24;
  background: #fff;
  border: 3px dashed #CECBF6;
  border-radius: 16px;
  padding: 14px 18px;
  margin: 2vh 0;
  cursor: pointer;
  user-select: text;
}
.rec-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 2.5vh 0 1vh;
  color: #8a867c;
  font-size: clamp(11px, 2vw, 13px);
  font-weight: 700;
}
.rec-divider::before, .rec-divider::after {
  content: "";
  flex: 1;
  height: 2px;
  background: #e3ddd0;
}
.rec-input {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  text-transform: uppercase;
  letter-spacing: 2px;
}
.rec-status {
  font-size: clamp(12px, 2.4vw, 15px);
  font-weight: 700;
  color: #534AB7;
  min-height: 1.4em;
  margin-top: 1vh;
}
.app-id-line {
  font-size: clamp(10px, 1.8vw, 12px);
  color: #b3ada0;
  margin-top: 8px;
  cursor: pointer;
  user-select: text;
}
.progress {
  font-size: clamp(14px, 2.5vw, 18px);
  color: #8a867c;
  font-weight: 700;
  margin-bottom: 1vh;
}
.stage {
  border-radius: 28px;
  padding: 14px 20px 10px;
  text-align: center;
  width: min(92vw, 460px);
}
.char-holder { width: clamp(110px, 22vh, 160px); margin: 0 auto; transition: transform 0.3s; }
.char-holder.celebrate { animation: jump 0.5s ease 2; }
@keyframes jump {
  0%, 100% { transform: translateY(0); }
  40% { transform: translateY(-22px) rotate(-4deg); }
}
.char-name { font-weight: 800; font-size: clamp(15px, 2.6vw, 19px); color: #444; }
.speech-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: rgba(255,255,255,0.7);
  border-radius: 999px;
  padding: 6px 16px;
  font-size: clamp(13px, 2.3vw, 16px);
  color: #555;
  margin-top: 6px;
  min-height: 32px;
}
.speech-pill .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #7F77DD;
  animation: pulse 0.9s infinite;
}
.speech-pill .dot:nth-child(2) { animation-delay: 0.15s; }
.speech-pill .dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes pulse { 0%,100% { opacity: 0.25; } 50% { opacity: 1; } }

.question-text {
  font-size: clamp(20px, 3.6vw, 28px);
  font-weight: 800;
  color: #2c2a24;
  margin: 2vh 0;
  text-align: center;
  max-width: 640px;
  line-height: 1.35;
}
.choices {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: min(92vw, 520px);
}
.choice-btn {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: clamp(17px, 3vw, 23px);
  font-weight: 700;
  color: #2c2a24;
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 18px;
  padding: 14px 18px;
  cursor: pointer;
  text-align: left;
  transition: transform 0.12s, border-color 0.12s, background 0.2s;
}
.choice-btn:active { transform: scale(0.97); }
.choice-btn .letter {
  flex-shrink: 0;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: #EEEDFE;
  color: #534AB7;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
}
.choice-btn.correct { border-color: #1D9E75; background: #E1F5EE; }
.choice-btn.correct .letter { background: #1D9E75; color: #fff; }
.choice-btn.wrong { border-color: #E24B4A; background: #FCEBEB; opacity: 0.85; }
.choice-btn.wrong .letter { background: #E24B4A; color: #fff; }
.choice-btn.dim { opacity: 0.45; }
.choice-btn:disabled { cursor: default; }

.quiz-controls { display: flex; gap: 12px; margin-top: 2.5vh; }
.small-btn {
  font-size: clamp(15px, 2.6vw, 19px);
  font-weight: 700;
  color: #534AB7;
  background: #fff;
  border: 3px solid #CECBF6;
  border-radius: 999px;
  padding: 10px 26px;
  cursor: pointer;
}
.small-btn:active { transform: scale(0.95); }
.small-btn.primary { background: #7F77DD; border-color: #7F77DD; color: #fff; }

/* ---------- RESULTS ---------- */
.stars { display: flex; gap: 14px; margin: 3vh 0; }
.star { font-size: clamp(44px, 10vw, 72px); filter: grayscale(1) opacity(0.3); transform: scale(0.7); transition: all 0.4s; }
.star.lit { filter: none; transform: scale(1); animation: starPop 0.5s ease; }
@keyframes starPop {
  0% { transform: scale(0.3) rotate(-30deg); }
  70% { transform: scale(1.25) rotate(8deg); }
  100% { transform: scale(1); }
}
.score-line { font-size: clamp(20px, 4vw, 30px); font-weight: 800; color: #2c2a24; }

/* ---------- RESULTS REVIEW LIST ---------- */
.review-box {
  width: min(92vw, 560px);
  margin-top: 2vh;
}
.review-title {
  font-size: clamp(16px, 3vw, 20px);
  font-weight: 800;
  color: #3C3489;
  margin-bottom: 10px;
  text-align: center;
}
.review-item {
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 16px;
  padding: 12px 16px;
  margin-bottom: 10px;
  text-align: left;
}
.ri-q {
  font-size: clamp(14px, 2.6vw, 17px);
  font-weight: 800;
  color: #2c2a24;
  margin-bottom: 6px;
  line-height: 1.35;
}
.ri-wrong {
  font-size: clamp(13px, 2.4vw, 15px);
  font-weight: 700;
  color: #A32D2D;
  margin-bottom: 3px;
}
.ri-skip {
  font-size: clamp(13px, 2.4vw, 15px);
  font-weight: 700;
  color: #8a867c;
  margin-bottom: 3px;
}
.ri-right {
  font-size: clamp(13px, 2.4vw, 15px);
  font-weight: 700;
  color: #0F6E56;
}

/* ---------- CONFETTI ---------- */
.confetti {
  position: fixed;
  top: -20px;
  width: 12px; height: 12px;
  border-radius: 3px;
  pointer-events: none;
  z-index: 50;
  animation: fall linear forwards;
}
@keyframes fall {
  to { transform: translateY(110vh) rotate(720deg); }
}

/* ---------- QUESTS ---------- */
.qm-note {
  font-size: clamp(13px, 2.4vw, 16px);
  font-weight: 800;
  color: #854F0B;
  background: #FAEEDA;
  border: 2px solid #FAC775;
  border-radius: 12px;
  padding: 8px 16px;
  margin-bottom: 10px;
  text-align: center;
  max-width: 92vw;
}

/* milestone path: start flag -> mini bosses -> final boss */
.qm-milestone { width: min(94vw, 640px); margin-bottom: 8px; }
.ms-track {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  position: relative;
  padding: 6px 10px 12px;
}
.ms-track::before {
  content: "";
  position: absolute;
  left: 4%;
  right: 4%;
  bottom: 10px;
  height: 8px;
  border-radius: 999px;
  background: linear-gradient(90deg, #97C459, #9FE1CB, #FAC775, #AFA9EC, #7F77DD);
}
.ms-node {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.ms-startflag { font-size: clamp(18px, 4vw, 26px); padding-bottom: 4px; }
.ms-img {
  width: clamp(38px, 9vw, 62px);
  height: auto;
  display: block;
  opacity: 0.6;
}
.ms-emoji { font-size: clamp(24px, 6vw, 40px); opacity: 0.6; }
.ms-done .ms-img, .ms-done .ms-emoji { filter: grayscale(1); opacity: 0.55; }
.ms-active .ms-img, .ms-active .ms-emoji { filter: none; opacity: 1; animation: msBounce 0.9s ease infinite; }
@keyframes msBounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}
.ms-final .ms-img { width: clamp(54px, 13vw, 88px); }
.ms-final .ms-emoji { font-size: clamp(34px, 8vw, 56px); }
.ms-check {
  position: absolute;
  top: -10px;
  right: -6px;
  font-size: clamp(13px, 2.6vw, 18px);
}
.ms-battle { margin-bottom: 4px; }
.ms-battle .ms-img { width: clamp(26px, 6vw, 40px); }
.ms-battle .ms-emoji { font-size: clamp(18px, 4vw, 26px); }
.ms-battle .ms-final .ms-img { width: clamp(36px, 8vw, 56px); }
.ms-battle .ms-track { padding: 2px 8px 8px; }
.ms-battle .ms-track::before { height: 5px; bottom: 7px; }

/* the final boss towers over minis in the arena */
.boss-final .sprite-holder { width: clamp(130px, 36vw, 210px); }
.boss-final .fighter-name { color: #A32D2D; }

.qe-potions-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(92vw, 520px);
  margin-bottom: 10px;
  font-size: clamp(13px, 2.4vw, 16px);
  font-weight: 800;
  color: #2c2a24;
  justify-content: center;
}
.qe-title { flex: 1; min-width: 0; }
.qe-boss-select {
  flex-shrink: 0;
  font-size: clamp(11px, 2vw, 13px);
  font-weight: 700;
  border: 2px solid #CECBF6;
  border-radius: 10px;
  padding: 5px 6px;
  background: #EEEDFE;
  color: #3C3489;
}
.qb-done { color: #0F6E56 !important; }
.qb-progress { color: #BA7517 !important; }
.qb-new { color: #534AB7 !important; }

.qm-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(92vw, 560px);
  max-height: 56vh;
  overflow-y: auto;
}
.qm-row {
  display: flex;
  align-items: center;
  gap: 12px;
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 16px;
  padding: 10px 14px;
  text-align: left;
  cursor: pointer;
}
.qm-row:disabled { cursor: default; }
.qm-emoji { font-size: clamp(26px, 6vw, 38px); flex-shrink: 0; }
.qm-info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.qm-boss { font-size: clamp(14px, 2.6vw, 17px); font-weight: 800; color: #2c2a24; }
.qm-lesson { font-size: clamp(11px, 2vw, 13px); color: #8a867c; font-weight: 600; }
.qm-state { font-size: clamp(12px, 2.2vw, 15px); font-weight: 800; flex-shrink: 0; }
.qm-done { border-color: #9FE1CB; background: #E1F5EE; }
.qm-done .qm-state { color: #0F6E56; }
.qm-done .qm-emoji { filter: grayscale(1); opacity: 0.6; }
.qm-done .qm-boss { color: #8a867c; }
.qm-next { border-color: #7F77DD; background: #EEEDFE; }
.qm-next .qm-state { color: #534AB7; }
.qm-next:active { transform: scale(0.97); }
.qm-final { border-width: 4px; border-color: #E24B4A; background: #FCEBEB; }
.qm-final .qm-state { color: #A32D2D; }
.qm-locked { opacity: 0.55; }
.qm-locked .qm-state { color: #8a867c; }

/* Step-by-step guidance on the quest builder. Parents were left to guess
   what the reviewer list and the Upload button were for, so each control
   now says what to do with it. Same width as the controls so it lines up. */
.qe-hint {
  width: min(92vw, 520px);
  text-align: left;
  font-size: clamp(12px, 2.3vw, 15px);
  font-weight: 700;
  color: #5F58A8;
  line-height: 1.4;
  margin-bottom: 6px;
}
.qe-hint strong { color: #4A4290; }

.qe-lessons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: min(92vw, 520px);
  /* without this the surrounding flex column squeezes the list down to a
     single row on a short screen; it must scroll internally, not collapse */
  flex-shrink: 0;
  max-height: 46vh;
  overflow-y: auto;
  margin-bottom: 12px;
}
.qe-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #fff;
  border: 3px solid #e3ddd0;
  border-radius: 14px;
  padding: 10px 14px;
  font-size: clamp(13px, 2.4vw, 16px);
  font-weight: 700;
  color: #2c2a24;
  cursor: pointer;
}
.qe-row input { width: 20px; height: 20px; flex-shrink: 0; }
/* .lesson-del is absolutely positioned for the lesson list, whose rows are
   position:relative. A quest row is a flex line and is NOT positioned, so an
   absolute ✕ escapes all the way to the screen corner. Force it back into the
   flow so it sits next to the boss picker. */
.qe-del {
  position: static;
  flex-shrink: 0;
  margin-left: 2px;
  padding: 4px 6px;
  font-size: 17px;
}

/* ---------- BATTLE MODE ---------- */
#battle-screen { padding-top: 2vh; position: relative; }
.arena {
  display: flex;
  /* stretch, not flex-end: the whole column used to sink with the sprite, which
     left the names and HP bars floating in the middle of the sky once the arena
     got taller */
  align-items: stretch;
  justify-content: center;
  gap: 4vw;
  width: min(94vw, 640px);
  /* a little taller, and only a hair of bottom padding: the background art
     draws its ground near the very bottom, so a deep pad left the characters
     hovering above it */
  min-height: clamp(200px, 34vh, 300px);
  /* The screen is a flex column, so when the question and choices render the
     arena was being squeezed from its natural height down to min-height. The
     sprites do not shrink with it, so the fighters slid below the drawn ledge
     the moment the countdown ended -- "the characters moved down". Holding the
     arena at its own height keeps the ledge and the fighters in step; if the
     screen is too short the page scrolls, which it already does. */
  flex-shrink: 0;
  background: linear-gradient(#EEF4FF 60%, #DCEBD2 60%);
  border: 3px solid #e3ddd0;
  border-radius: 20px;
  padding: 14px 12px 6px;
}
.arena-img {
  background-size: cover;
  background-position: center bottom;
}
.arena-img .fighter-name,
.arena-img .vs-label {
  text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.fighter {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: clamp(110px, 34vw, 180px);
}
.fighter-name {
  font-size: clamp(12px, 2.2vw, 15px);
  font-weight: 800;
  color: #2c2a24;
  white-space: nowrap;
  /* see .hp-bar below -- the fighter column squeezes whatever it can */
  flex-shrink: 0;
}
.vs-label {
  font-size: clamp(18px, 4vw, 28px);
  font-weight: 800;
  color: #A32D2D;
  /* the arena stretches its children now, so VS has to centre itself or it
     rides up between the two fighter names */
  align-self: center;
}
.sprite-holder {
  width: clamp(90px, 26vw, 150px);
  margin-top: auto;      /* pushes the fighter down towards the ground */
  /* ...but not all the way: every arena background draws a raised ledge, and
     the fighters should stand ON it rather than on the arena's bottom edge */
  /* A flat offset, deliberately: the background uses cover+bottom, so on a
     narrow screen it scales by height and on a wide one by width. A vh-based
     value therefore moves the fighters the WRONG way between the two. ~52px
     lands on the ledge at both sizes. */
  margin-bottom: 52px;
}
.sprite-holder svg, .sprite-img { width: 100%; height: auto; display: block; }
.hp-bar {
  width: 100%;
  height: 14px;
  /* WITHOUT flex-shrink:0 the fighter column squashes this bar down to ~4px
     on a short screen. The 2px borders then eat the whole box, the green fill
     is left with zero height, and the bar reads as a dead grey line -- which
     is exactly what "the HP is grayed out" turned out to be. */
  flex-shrink: 0;
  min-height: 14px;
  background: #fff;
  border: 2px solid #c9c4b6;
  border-radius: 999px;
  overflow: hidden;
}
.hp-fill {
  height: 100%;
  width: 100%;
  background: #1D9E75;
  border-radius: 999px;
  transition: width 0.4s ease;
}
.hp-fill.hp-mid { background: #EF9F27; }
.hp-fill.hp-low { background: #E24B4A; }
.flash-layer {
  position: absolute;
  inset: 0;
  border-radius: 16px;
  background: #E24B4A;
  opacity: 0;
  pointer-events: none;
}
.flash-red { animation: redFlicker 0.5s ease; }
.flash-green { background: #1D9E75 !important; animation: redFlicker 0.6s ease; }
.float-heal {
  position: absolute;
  top: 20%;
  left: 50%;
  transform: translateX(-50%);
  font-size: clamp(15px, 3vw, 20px);
  font-weight: 800;
  color: #0F6E56;
  text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
  pointer-events: none;
  z-index: 5;
  animation: floatUp 0.9s ease forwards;
}
@keyframes floatUp {
  0% { opacity: 0; transform: translate(-50%, 10px); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -34px); }
}
/* The potion lives BELOW the arena now. Inside the player's column it either
   pushed that fighter up (breaking the alignment with the boss) or, once
   absolutely positioned, sat on top of the buddy. Out here it does neither. */
.potion-row { display: flex; justify-content: center; margin-top: 8px; }
.potion-btn {
  white-space: nowrap;
  font-size: clamp(13px, 2.4vw, 16px);
  font-weight: 800;
  color: #3C3489;
  background: #EEEDFE;
  border: 2px solid #CECBF6;
  border-radius: 999px;
  padding: 5px 14px;
  cursor: pointer;
}
.potion-btn:active { transform: scale(0.93); }
.potion-btn:disabled { opacity: 0.4; }
@keyframes redFlicker {
  0%, 100% { opacity: 0; }
  20% { opacity: 0.55; }
  40% { opacity: 0.1; }
  60% { opacity: 0.45; }
  80% { opacity: 0.1; }
}
.lunge-right { animation: lungeR 0.5s ease; }
@keyframes lungeR {
  0%, 100% { transform: translateX(0); }
  40% { transform: translateX(clamp(30px, 8vw, 60px)) scale(1.06); }
}
.lunge-left { animation: lungeL 0.5s ease; }
@keyframes lungeL {
  0%, 100% { transform: translateX(0); }
  40% { transform: translateX(calc(-1 * clamp(30px, 8vw, 60px))) scale(1.06); }
}
.shake { animation: shakeX 0.45s ease; }
@keyframes shakeX {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px) rotate(-2deg); }
  40% { transform: translateX(6px) rotate(2deg); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(4px); }
}
.boss-down .sprite-holder { transform: rotate(80deg) translateY(14px); opacity: 0.75; transition: all 0.9s ease; }
.celebrate { animation: heroJump 0.55s ease 4; }
@keyframes heroJump {
  0%, 100% { transform: translateY(0); }
  45% { transform: translateY(-26px) rotate(-3deg); }
}
.battle-question { margin: 1.6vh 0 1vh; }
.battle-choice { padding: 11px 16px; }

.countdown-overlay {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(60, 52, 137, 0.55);
  border-radius: 0;
  z-index: 20;
}
.countdown-num {
  font-size: clamp(70px, 18vw, 130px);
  font-weight: 800;
  color: #fff;
  text-shadow: 0 6px 0 rgba(0,0,0,0.25);
}
.cd-pop { animation: cdPop 0.75s ease; }
@keyframes cdPop {
  0% { transform: scale(0.2); opacity: 0; }
  35% { transform: scale(1.25); opacity: 1; }
  70% { transform: scale(1); }
  100% { transform: scale(1); opacity: 0.9; }
}

.battle-result {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: rgba(253, 249, 242, 0.94);
  z-index: 15;
  padding: 20px;
  text-align: center;
}
.br-title { font-size: clamp(28px, 7vw, 46px); font-weight: 800; color: #3C3489; }
.br-time { font-size: clamp(17px, 3.4vw, 24px); font-weight: 800; color: #2c2a24; }
.br-record { font-size: clamp(14px, 2.6vw, 18px); font-weight: 700; color: #0F6E56; max-width: 480px; line-height: 1.5; }

/* ---------- character animation ---------- */
.char-svg { display: block; }
.spark { opacity: 0; }
.speaking .spark.s1 { animation: twinkle 1.1s infinite; }
.speaking .spark.s2 { animation: twinkle 1.4s 0.4s infinite; }
@keyframes twinkle { 0%,100% { opacity: 0; } 50% { opacity: 1; } }
/* ---------- idle breathing ----------
   Sits on .sprite-img, the innermost element, so it composes with the
   transforms its ancestors already use: .fighter carries lunge/shake/
   celebrate and .sprite-holder carries the boss-down fall. Nesting them
   instead of stacking them on one element means nothing overrides
   anything, and every one of them stays a compositor-only transform --
   no layout, no repaint, so the cost is effectively nil.
   The origin is the feet, so characters stay planted while they breathe. */
.arena .sprite-img {
  transform-origin: 50% 100%;
  animation: breathe 2.6s ease-in-out infinite;
}
/* a different period for the boss, so the two never pulse in lockstep */
.arena .boss .sprite-img { animation-duration: 3.1s; }
@keyframes breathe {
  0%, 100% { transform: scaleY(1) scaleX(1); }
  50%      { transform: scaleY(1.025) scaleX(0.994); }
}
/* a defeated boss lies still */
.boss-down .sprite-img { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .arena .sprite-img { animation: none; }
}

.bobbing { animation: bob 2.2s ease-in-out infinite; }
@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}

/* ---------- feedback ---------- */
.fb-stars { display: flex; gap: 6px; margin: 2vh 0 0.5vh; }
.fb-star {
  font-size: clamp(34px, 9vw, 50px);
  line-height: 1;
  background: none;
  border: none;
  cursor: pointer;
  color: #E8B84B;
  padding: 0 2px;
  font-family: inherit;
  transition: transform 0.1s;
}
.fb-star:active { transform: scale(0.88); }
.fb-label {
  font-size: clamp(13px, 2.6vw, 16px);
  font-weight: 700;
  color: #8a867c;
  min-height: 1.4em;
  margin: 0;
}

/* ---------- paypal ---------- */
.pp-buttons { width: min(92vw, 380px); min-height: 60px; margin: 2vh 0 1vh; }
