:root {
  --bg: #FFF8EC;
  --ink: #3B3650;
  --muted: #8C86A0;
  --card: #FFFFFF;
  --accent: #FF8A5B;
  --good: #4CC27A;
  --theme: #FFD27A;
  --r: 28px;
  --shadow: 0 6px 0 rgba(59, 54, 80, .08), 0 12px 28px rgba(59, 54, 80, .10);
  --emoji: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
html, body { margin: 0; height: 100%; overflow: hidden; overscroll-behavior: none; }
body {
  background:
    radial-gradient(circle at 12% 8%, color-mix(in srgb, var(--theme) 45%, transparent) 0 18%, transparent 19%),
    radial-gradient(circle at 92% 96%, color-mix(in srgb, var(--theme) 40%, transparent) 0 22%, transparent 23%),
    var(--bg);
  color: var(--ink);
  font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  touch-action: manipulation;
  transition: background .4s;
}
button { font: inherit; color: inherit; border: 0; cursor: pointer; touch-action: manipulation; }
button:disabled { opacity: .3; pointer-events: none; }
small { display: block; font-weight: 600; color: var(--muted); }

#app {
  height: 100vh; height: 100dvh;
  display: flex; flex-direction: column;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* ---------- top bar ---------- */
.topbar { display: flex; align-items: center; gap: 12px; padding: 12px 16px; min-height: 88px; }
.brand { flex: 1; display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 10px; }
.brand-logo { font-family: var(--emoji); font-size: 36px; align-self: center; }
.brand-name { font-size: clamp(28px, 5vmin, 40px); font-weight: 900; letter-spacing: .5px; }
.brand small { flex-basis: 100%; font-size: clamp(12px, 2.2vmin, 16px); margin-left: 48px; }
.title { flex: 1; text-align: center; font-weight: 800; font-size: clamp(18px, 3.4vmin, 28px); line-height: 1.2; }
.title small { font-size: .62em; }

.btn-round {
  flex: none; position: relative; width: 64px; height: 64px; border-radius: 50%;
  background: var(--card); box-shadow: var(--shadow);
  display: grid; place-items: center; font-size: 30px; font-family: var(--emoji);
  transition: transform .12s;
}
.btn-round:active { transform: translateY(3px) scale(.95); }
.gear { width: 52px; height: 52px; font-size: 24px; opacity: .75; }
.gear span { position: relative; z-index: 1; }
.gear::before {
  content: ""; position: absolute; inset: -5px; border-radius: 50%;
  background: conic-gradient(var(--accent) calc(var(--p, 0) * 1%), transparent 0);
  -webkit-mask: radial-gradient(circle, transparent 58%, #000 60%); mask: radial-gradient(circle, transparent 58%, #000 60%);
}
@property --p { syntax: "<number>"; inherits: false; initial-value: 0; }
.gear.holding::before { animation: fill-ring 2s linear forwards; }
.gear.holding { opacity: 1; transform: scale(1.08); }
@keyframes fill-ring { to { --p: 100; } }

.progress { flex: none; width: 64px; height: 14px; border-radius: 99px; background: rgba(59, 54, 80, .1); overflow: hidden; }
.progress i { display: block; height: 100%; width: 0; border-radius: inherit; background: var(--good); transition: width .4s; }

/* ---------- tiles ---------- */
.grid { flex: 1; display: grid; gap: clamp(12px, 2.4vmin, 24px); padding: 8px clamp(16px, 3vmin, 32px) clamp(16px, 3vmin, 32px); overflow-y: auto; align-content: start; }
.home-grid { grid-template-columns: repeat(3, 1fr); grid-auto-rows: minmax(150px, 1fr); align-content: stretch; }
.lesson-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
@media (max-aspect-ratio: 1/1) { .home-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 380px) { .lesson-grid { grid-template-columns: repeat(2, 1fr); } }

.tile {
  position: relative; border-radius: var(--r); background: var(--c); box-shadow: var(--shadow);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: 16px 10px; text-align: center;
  animation: pop-in .45s cubic-bezier(.3, 1.5, .5, 1) both; animation-delay: var(--d, 0ms);
  transition: transform .12s;
}
.tile:active { transform: scale(.95); }
.tile-e { font-family: var(--emoji); font-size: clamp(54px, 13vmin, 120px); line-height: 1.1; filter: drop-shadow(0 4px 0 rgba(0, 0, 0, .08)); }
.tile-hanzi { font-family: "Kaiti SC", "STKaiti", "KaiTi", serif; font-weight: 700; color: #C62828; }
.tile-zh { font-weight: 900; font-size: clamp(18px, 3.4vmin, 28px); }
.tile-en { font-weight: 700; font-size: clamp(12px, 2.2vmin, 17px); opacity: .6; }
.tile-meter { width: 60%; height: 8px; margin-top: 8px; border-radius: 99px; background: rgba(255, 255, 255, .6); overflow: hidden; }
.tile-meter i { display: block; height: 100%; background: var(--good); border-radius: inherit; }

.lesson-tile { background: var(--card); border-bottom: 8px solid var(--c); min-height: 170px; }
.lesson-tile .tile-e { font-size: clamp(48px, 10vmin, 80px); }
.lesson-tile .tile-zh { font-size: clamp(16px, 2.8vmin, 22px); }
.badge { position: absolute; top: 10px; left: 12px; font-family: var(--emoji); font-size: 18px; opacity: .55; }
.star { position: absolute; top: 6px; right: 10px; font-family: var(--emoji); font-size: 26px; animation: twinkle 2.4s ease-in-out infinite; }
.lesson-tile.done { background: color-mix(in srgb, var(--c) 18%, #fff); }

.tip { margin: 0 16px; align-self: center; padding: 8px 16px; border-radius: 99px; background: rgba(255, 255, 255, .8); color: var(--muted); font-weight: 700; font-size: 14px; }

/* ---------- stage ---------- */
.stage { flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(10px, 2.5vmin, 24px); padding: 8px 16px; }
.nav { display: flex; justify-content: space-between; padding: 0 clamp(16px, 4vmin, 40px) clamp(14px, 3vmin, 28px); }
.nav:empty { display: none; }
.arrow {
  width: clamp(72px, 13vmin, 100px); height: clamp(72px, 13vmin, 100px); border-radius: 50%;
  background: var(--card); color: var(--ink); box-shadow: var(--shadow); display: grid; place-items: center; transition: transform .12s;
}
.arrow svg { width: 55%; height: 55%; }
.arrow.next { background: var(--accent); color: #fff; }
.arrow:active { transform: translateY(3px) scale(.95); }
.arrow.nudge { animation: nudge 1.1s ease-in-out infinite; }

/* visuals */
.vis { display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; }
.emo { font-family: var(--emoji); display: inline-block; transform: scale(var(--s, 1)); transition: transform .3s; }
.emo-rep { display: flex; flex-wrap: wrap; justify-content: center; max-width: 6.2em; }
.big-t { font-weight: 900; line-height: 1; color: var(--ink); }
.vis-svg svg { width: 100%; height: 100%; display: block; filter: drop-shadow(0 6px 0 rgba(0, 0, 0, .08)); }

/* flashcard */
.flash {
  position: relative; width: min(86vw, 62dvh, 560px); aspect-ratio: 1 / 1.08;
  border-radius: 40px; background: var(--card); box-shadow: var(--shadow), inset 0 -10px 0 color-mix(in srgb, var(--theme) 55%, #fff);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4%; padding: 6%;
}
.flash-vis { flex: 1; min-height: 0; width: 100%; }
.flash-vis .emo { font-size: min(34vw, 26dvh, 230px); }
.flash-vis.has-t .big-t { font-size: min(22vw, 17dvh, 150px); }
.flash-vis.has-t .emo { font-size: min(14vw, 10dvh, 90px); margin-top: 4%; }
.flash-vis .emo-rep { font-size: min(10vw, 8dvh, 64px) !important; }
.flash-vis.vis-svg { width: 72%; }
.label { text-align: center; }
.label b { display: block; font-size: clamp(26px, 5.4vmin, 48px); font-weight: 900; }
.label span { display: block; font-size: clamp(16px, 3.2vmin, 28px); font-weight: 700; color: var(--muted); }

/* story */
.story { display: flex; flex-direction: column; align-items: center; gap: clamp(10px, 2vmin, 20px); width: 100%; max-width: 900px; }
.scene {
  width: min(90vw, 680px); height: min(42dvh, 380px); border-radius: 40px; background: var(--card); box-shadow: var(--shadow);
  display: grid; place-items: center; overflow: hidden;
  background-image: radial-gradient(circle at 50% 120%, color-mix(in srgb, var(--theme) 60%, #fff) 0 45%, transparent 46%);
}
.scene-e { font-family: var(--emoji); font-size: min(19vw, 22dvh, 170px); letter-spacing: .05em; animation: float 3.5s ease-in-out infinite; }
.caption { text-align: center; padding: 0 8px; }
.caption p { margin: 0; }
.c1 { font-size: clamp(20px, 4.2vmin, 36px); font-weight: 900; line-height: 1.35; }
.c2 { margin-top: 6px !important; font-size: clamp(15px, 2.8vmin, 24px); font-weight: 600; color: var(--muted); line-height: 1.35; }

/* ask bar (choose / count / sort) */
.ask { display: flex; align-items: center; gap: 14px; max-width: 92vw; }
.ask-text { font-size: clamp(22px, 4.4vmin, 38px); font-weight: 900; line-height: 1.25; }
.ask-text small { font-size: .6em; }
.speak { color: var(--accent); }
.show { font-family: var(--emoji); font-size: min(13vw, 12dvh, 100px); letter-spacing: .06em; padding: 10px 24px; border-radius: 28px; background: rgba(255, 255, 255, .75); }

.opts { display: flex; gap: clamp(14px, 3vmin, 32px); justify-content: center; flex-wrap: wrap; }
.opt {
  --size: min(40vw, 38dvh, 300px);
  width: var(--size); height: var(--size); border-radius: 36px; background: var(--card); box-shadow: var(--shadow);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 8%;
  animation: pop-in .4s cubic-bezier(.3, 1.5, .5, 1) both; animation-delay: var(--d, 0ms);
  transition: transform .15s, opacity .3s, box-shadow .3s;
}
.opts.n3 .opt { --size: min(28vw, 34dvh, 240px); }
.opts.compact .opt { --size: min(36vw, 28dvh, 230px); }
.opts.n3.compact .opt { --size: min(28vw, 26dvh, 200px); }
.opt .vis { flex: 1; min-height: 0; width: 100%; }
.opt .emo { font-size: calc(var(--size) * .5); }
.opt .emo-rep { font-size: calc(var(--size) * .2); }
.opt .big-t { font-size: calc(var(--size) * .4); }
.opt-cap { font-size: clamp(16px, 3vmin, 24px); font-weight: 900; }
.opt:active { transform: scale(.95); }
.opt.right { box-shadow: 0 0 0 8px var(--good), var(--shadow); animation: bounce .6s; }
.opt.dim { opacity: .35; }
.wrong { animation: shake .45s; }

/* count */
.counter {
  min-width: 72px; height: 72px; padding: 0 12px; border-radius: 36px; background: var(--accent); color: #fff;
  display: grid; place-items: center; font-size: 42px; font-weight: 900; box-shadow: var(--shadow);
}
.counter.pulse { animation: pulse .35s; }
.count-field { display: flex; flex-wrap: wrap; justify-content: center; align-content: center; gap: 14px; max-width: min(94vw, 900px); }
.cnt {
  position: relative; font-family: var(--emoji); border-radius: 50%; background: rgba(255, 255, 255, .7);
  display: grid; place-items: center; animation: pop-in .4s cubic-bezier(.3, 1.5, .5, 1) both; animation-delay: var(--d, 0ms);
}
.cs .cnt { --z: min(26vw, 30dvh, 190px); }
.cm .cnt { --z: min(22vw, 22dvh, 140px); }
.cl .cnt { --z: min(17vw, 17dvh, 112px); }
.cnt { width: var(--z); height: var(--z); font-size: calc(var(--z) * .62); }
.cnt.counted { background: color-mix(in srgb, var(--good) 22%, #fff); box-shadow: 0 0 0 5px var(--good); animation: bounce .45s; }
.cnt.counted::after {
  content: attr(data-num); position: absolute; top: -6px; right: -6px; width: 38px; height: 38px; border-radius: 50%;
  background: var(--good); color: #fff; font: 900 22px/38px system-ui, sans-serif; text-align: center;
}

/* sort */
.sort-item { width: min(44vw, 30dvh, 240px); height: min(44vw, 30dvh, 240px); border-radius: 36px; background: var(--card); box-shadow: var(--shadow); display: grid; place-items: center; }
.sort-item .emo { font-size: min(28vw, 19dvh, 150px); }
.sort-item.fly { transition: transform .45s cubic-bezier(.5, -0.3, .7, 1), opacity .45s; transform: translate(var(--tx), var(--ty)) scale(.25); opacity: 0; }
.bins { display: flex; gap: clamp(16px, 5vmin, 56px); }
.bin {
  width: min(40vw, 260px); padding: 18px 10px 14px; border-radius: 30px 30px 44px 44px;
  background: color-mix(in srgb, var(--theme) 55%, #fff); box-shadow: var(--shadow); display: flex; flex-direction: column; align-items: center; gap: 4px;
  border-top: 8px dashed rgba(255, 255, 255, .9);
}
.bin-e { font-family: var(--emoji); font-size: min(15vw, 12dvh, 88px); }
.bin-cap { font-weight: 900; font-size: clamp(18px, 3.4vmin, 26px); }
.bin-cap small { font-size: .7em; }
.bin.gulp { animation: bounce .5s; }

/* ---------- overlays ---------- */
.overlay { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 16px; background: rgba(59, 54, 80, .45); animation: fade .25s; }
.sheet { position: relative; width: min(560px, 100%); max-height: 92dvh; overflow: auto; border-radius: 36px; background: var(--card); padding: 28px; text-align: center; box-shadow: var(--shadow); animation: pop-in .4s cubic-bezier(.3, 1.5, .5, 1); }
.overlay h2 { margin: 6px 0 18px; font-size: clamp(32px, 7vmin, 52px); font-weight: 900; }
.overlay h2 small { font-size: .45em; }

.win .sheet { overflow: hidden; }
.win-star { font-family: var(--emoji); font-size: 110px; animation: spin-in .8s cubic-bezier(.3, 1.6, .5, 1); }
.win-actions { display: flex; justify-content: center; gap: 18px; }
.btn-big { width: 96px; height: 96px; border-radius: 32px; background: var(--bg); box-shadow: var(--shadow); font-family: var(--emoji); font-size: 46px; transition: transform .12s; }
.btn-big.primary { background: var(--accent); animation: nudge 1.2s ease-in-out infinite; }
.btn-big:active { transform: scale(.93); }
.confetti { position: absolute; inset: 0; pointer-events: none; }
.confetti i { position: absolute; top: -40px; left: var(--x); font-style: normal; font-family: var(--emoji); font-size: 26px; animation: fall 2.2s ease-in var(--d) forwards; }

.settings .sheet { text-align: left; }
.settings h3 { margin: 0 0 8px; font-size: 26px; }
.settings h3 small { display: inline; font-size: .6em; margin-left: 6px; }
.settings label { display: block; margin: 18px 0 8px; font-weight: 800; font-size: 15px; color: var(--muted); }
.seg { display: flex; flex-wrap: wrap; gap: 8px; }
.seg button { padding: 10px 16px; border-radius: 14px; background: var(--bg); font-weight: 700; font-size: 15px; }
.seg button.on { background: var(--accent); color: #fff; }
.voices { display: flex; flex-direction: column; gap: 6px; font-size: 14px; font-weight: 600; }
.voices .btn-small { align-self: flex-start; margin-top: 4px; }
.btn-small { padding: 10px 18px; border-radius: 14px; background: var(--bg); font-weight: 800; font-size: 15px; }
.btn-small.primary { background: var(--good); color: #fff; }
.btn-small.danger { color: #D84343; }
.parent-notes { margin-top: 18px; padding: 12px 16px; border-radius: 18px; background: var(--bg); font-size: 14px; line-height: 1.6; }
.parent-notes p { margin: 6px 0; }
.sheet-actions { display: flex; justify-content: space-between; margin-top: 18px; }

.rest .sheet { padding: 36px 28px; }
.rest-e { font-family: var(--emoji); font-size: 120px; animation: float 3s ease-in-out infinite; }
.rest-p { font-size: 20px; font-weight: 700; }
.rest .gear { margin: 10px auto 4px; width: 64px; height: 64px; opacity: 1; }
.rest-hint { color: var(--muted); font-size: 13px; margin: 0; }

.toast { position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); z-index: 60; padding: 12px 20px; border-radius: 99px; background: var(--ink); color: #fff; font-weight: 700; font-size: 14px; white-space: nowrap; animation: fade .2s; }
.spark { position: fixed; z-index: 70; pointer-events: none; font-family: var(--emoji); font-size: 30px; transform: translate(-50%, -50%); animation: spark .9s ease-out forwards; }

/* ---------- motion ---------- */
.in { animation: pop-in .4s cubic-bezier(.3, 1.5, .5, 1); }
.in-r { animation: slide-r .35s ease-out; }
.in-l { animation: slide-l .35s ease-out; }
.wiggle { animation: wiggle .5s; }
@keyframes pop-in { from { opacity: 0; transform: scale(.6); } }
@keyframes slide-r { from { opacity: 0; transform: translateX(60px); } }
@keyframes slide-l { from { opacity: 0; transform: translateX(-60px); } }
@keyframes wiggle { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-4deg) scale(1.04); } 75% { transform: rotate(4deg) scale(1.04); } }
@keyframes bounce { 0%, 100% { transform: scale(1); } 40% { transform: scale(1.12); } 70% { transform: scale(.96); } }
@keyframes shake { 0%, 100% { transform: translateX(0); } 20%, 60% { transform: translateX(-10px); } 40%, 80% { transform: translateX(10px); } }
@keyframes pulse { 50% { transform: scale(1.25); } }
@keyframes nudge { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(8px); } }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
@keyframes twinkle { 50% { transform: scale(1.2) rotate(15deg); } }
@keyframes fade { from { opacity: 0; } }
@keyframes spin-in { from { transform: scale(0) rotate(-180deg); } }
@keyframes fall { to { transform: translateY(110vh) rotate(var(--r)); } }
@keyframes spark { to { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.4); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* short landscape phones */
@media (max-height: 500px) {
  .topbar { min-height: 64px; padding: 6px 12px; }
  .btn-round { width: 52px; height: 52px; }
  .label b { font-size: 24px; }
  .flash { aspect-ratio: auto; height: 100%; }
}
