/* Typing Kid — "Felt Quilt": stitched felt patches on cream linen. */
:root {
  --linen: #F3EADA;
  --cream: #FFF8EC;
  --ink: #3A2E28;
  --ink-soft: #75645A;
  --thread: #C8553D;
  --shadow: rgba(70, 50, 35, .18);
  --kid: 'Andika', 'Trebuchet MS', 'Avenir Next', system-ui, sans-serif;
  --head: 'Fredoka', 'Avenir Next Rounded', 'Andika', system-ui, sans-serif;
  --felt-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.25 0 0 0 0 0.18 0 0 0 0 0.12 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  color: var(--ink);
  font-family: var(--kid);
  background-color: var(--linen);
  background-image:
    repeating-linear-gradient(0deg, rgba(120, 90, 60, .045) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(90deg, rgba(120, 90, 60, .045) 0 1px, transparent 1px 4px);
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none; user-select: none;
  overflow-x: hidden;
}
button { font: inherit; color: inherit; cursor: pointer; }
#keycatch { position: fixed; left: 0; bottom: 0; width: 1px; height: 1px; opacity: 0; font-size: 16px; border: 0; padding: 0; resize: none; pointer-events: none; }
.screen { display: none; min-height: 100vh; min-height: 100dvh; }
.screen.on { display: flex; flex-direction: column; }
.hidden { display: none !important; }
.small { font-size: 14px; color: var(--ink-soft); }
kbd { font-family: var(--head); font-size: .62em; font-weight: 500; padding: 2px 7px; border-radius: 6px; background: rgba(255, 255, 255, .28); margin-left: 6px; vertical-align: middle; }

/* ---------- felt + stitching ---------- */
.felt { position: relative; border: 0; border-radius: 16px; box-shadow: 0 2px 0 rgba(70, 50, 35, .10), 0 6px 14px var(--shadow); isolation: isolate; }
.felt::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background-image: url(felt-grain.png); background-size: 128px; opacity: .3; pointer-events: none; z-index: 1; }
.stitch::before { content: ''; position: absolute; inset: 6px; border: 2px dashed rgba(255, 255, 255, .75); border-radius: 11px; pointer-events: none; z-index: 2; }
.felt > * { position: relative; z-index: 3; }

.btn { background: var(--cream); padding: 12px 22px; font-family: var(--head); font-weight: 600; font-size: 20px; border-radius: 14px; transition: transform .12s; }
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--thread); color: #fff; }
.btn.primary::before { content: ''; position: absolute; inset: 4px; border: 2px dashed rgba(255, 255, 255, .6); border-radius: 10px; pointer-events: none; z-index: 2; }
.btn.ghost { background: transparent; box-shadow: none; text-decoration: underline; text-underline-offset: 4px; }
.btn.ghost::after { display: none; }
.pill { background: var(--cream); padding: 6px 14px; border-radius: 999px; font-family: var(--head); font-weight: 600; font-size: 17px; white-space: nowrap; }
.linkish { background: none; border: 0; text-decoration: underline; color: var(--ink-soft); font-size: 15px; padding: 8px; }

/* ---------- top bar ---------- */
.topbar { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px; padding: 12px 18px 6px; }
.back { background: var(--cream); padding: 8px 16px; font-family: var(--head); font-weight: 600; font-size: 17px; border-radius: 12px; }
.ltitle { font-family: var(--head); font-weight: 600; font-size: 22px; text-align: center; }
.lnum { color: var(--ink-soft); font-weight: 500; margin-right: 4px; }
.stitches { display: flex; gap: 6px; }
.stitches i { width: 22px; height: 6px; border-radius: 3px; background: rgba(58, 46, 40, .14); }
.stitches i.done { background: var(--land, var(--thread)); }

/* ---------- Bobbin ---------- */
.bobbin { display: block; width: 100%; height: 100%; overflow: visible; }
.bobbin .eyes { animation: blink 5s infinite; transform-origin: 40px 42px; }
@keyframes blink { 0%, 94%, 100% { transform: scaleY(1); } 96% { transform: scaleY(.1); } }
.bobbin.cheer { animation: hop .6s ease-out; }
.bobbin.oops { animation: tilt .5s ease-out; }
@keyframes hop { 30% { transform: translateY(-8px); } 60% { transform: translateY(0); } }
@keyframes tilt { 30% { transform: rotate(-8deg); } 70% { transform: rotate(4deg); } }
.bubble { background: var(--cream); padding: 10px 16px; border-radius: 16px; font-size: 19px; line-height: 1.35; }
.bubble::before { content: ''; position: absolute; left: -9px; top: 50%; margin-top: -9px; border: 9px solid transparent; border-right-color: var(--cream); border-left: 0; z-index: 4; }

/* ---------- keyboard ---------- */
.kbhost { --u: min(58px, calc((100vw - 40px) / 14.8), calc((100dvh - 300px) / 8.3)); display: flex; justify-content: center; padding: 4px 0; }
.kbhost.small { --u: min(46px, calc((100vw - 40px) / 14.8)); }
.kb { background: #D9CBB4; padding: calc(var(--u) * .14); border-radius: calc(var(--u) * .3); box-shadow: inset 0 2px 0 rgba(255, 255, 255, .5), 0 6px 16px var(--shadow); }
.kb-row { display: flex; }
.key {
  --g: calc(var(--u) * .1);
  width: calc(var(--u) * var(--w, 1) - var(--g)); height: calc(var(--u) - var(--g)); margin: calc(var(--g) / 2);
  background: var(--ft, #EFE5D4); border-radius: calc(var(--u) * .2);
  display: flex; align-items: center; justify-content: center; position: relative;
  font-family: var(--kid); font-weight: 700; font-size: calc(var(--u) * .42); color: var(--ink);
  box-shadow: 0 calc(var(--u) * .06) 0 rgba(70, 50, 35, .22);
  transition: transform .12s, background .15s, opacity .2s;
}
.key::before { content: ''; position: absolute; inset: calc(var(--u) * .07); border: 1.5px dashed rgba(255, 255, 255, .8); border-radius: calc(var(--u) * .14); pointer-events: none; }
.key::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background-image: url(felt-grain.png); background-size: 128px; opacity: .25; pointer-events: none; }
.key.mod { background: #E6DCCB; color: #9A8B7E; }
.key.word { font-size: calc(var(--u) * .24); font-family: var(--head); font-weight: 500; }
.key.space { color: transparent; }
.key.bump .lbl::after { content: ''; position: absolute; left: 50%; bottom: calc(var(--u) * .12); width: calc(var(--u) * .26); height: 3px; margin-left: calc(var(--u) * -.13); border-radius: 2px; background: rgba(58, 46, 40, .45); }
.key .sub { position: absolute; bottom: 2px; font-style: normal; font-size: calc(var(--u) * .2); font-family: var(--head); }
.kb.focus .key:not(.next) { opacity: .62; }
.key.next { background: var(--fc); color: #fff; transform: translateY(calc(var(--u) * -.08)); box-shadow: 0 0 0 3px #fff, 0 0 0 6px var(--fc), 0 8px 14px var(--shadow); z-index: 5; opacity: 1; animation: glow 1.1s ease-in-out infinite; }
.key.next.word { color: #fff; }
@keyframes glow { 50% { transform: translateY(calc(var(--u) * -.14)); } }
.key.hit { animation: pressdown .18s; }
@keyframes pressdown { 50% { transform: translateY(calc(var(--u) * .06)) scale(.95); } }
.key.nope { animation: nope .4s; }
@keyframes nope { 0%, 100% { filter: none; } 30% { filter: brightness(.82); transform: translateX(-2px); } 60% { transform: translateX(2px); } }
.key.sleep { opacity: .35; }
.key.heat { color: var(--ink); }
.key.heat.nodata { background: #E9E0D1; color: #A89A8C; }
.key.heat .lbl { transform: translateY(-15%); }
.key.big { --u: 74px; width: 74px; height: 74px; background: var(--fc); color: #fff; font-size: 34px; }
.key.big.word { width: 128px; font-size: 22px; }

/* ---------- hands ---------- */
.handhost { display: flex; justify-content: center; gap: calc(var(--u) * 1.6); --u: min(58px, calc((100vw - 40px) / 14.8), calc((100dvh - 300px) / 8.3)); margin-top: calc(var(--u) * -.1); }
.hand { height: calc(var(--u) * 3); width: auto; overflow: visible; }
.hand .stitchline { fill: none; stroke: rgba(255, 255, 255, .7); stroke-width: 1.8; stroke-dasharray: 5 4; }
.hand .stitchline.dark { stroke: rgba(160, 120, 90, .5); }
.finger { transition: transform .18s, opacity .2s; transform-box: fill-box; transform-origin: 50% 100%; }
.hands.focus .finger:not(.on) { opacity: .42; }
.finger.on { transform: translateY(-9px) scale(1.05); filter: drop-shadow(0 0 6px rgba(255, 255, 255, .9)); }
.finger.tap { animation: tap .2s; }
@keyframes tap { 50% { transform: translateY(4px); } }

/* ---------- lesson ---------- */
#scr-lesson { gap: 6px; }
.strip-wrap { display: flex; justify-content: center; padding: 6px 18px 0; }
.strip {
  background: var(--cream); padding: 16px 28px 20px; border-radius: 18px; width: min(100%, 1100px);
  font-size: min(64px, calc((100vw - 110px) / var(--n) * 1.75)); font-weight: 400; line-height: 1.25;
  display: flex; flex-wrap: nowrap; justify-content: center; white-space: pre; min-height: 1.9em; align-items: center;
}
.strip .ch { position: relative; color: #B3A496; padding: 0 .02em; transition: color .1s; }
.strip .ch.typed { color: var(--ink); }
.strip .ch.cur { color: var(--fc); font-weight: 700; }
.strip .ch.cur::after { content: ''; position: absolute; left: 0; right: 0; bottom: -.08em; height: .1em; border-radius: .05em; background: var(--fc); animation: blinkline 1s infinite; }
@keyframes blinkline { 50% { opacity: .35; } }
.strip .ch.sp { min-width: .45em; }
.strip .ch.sp.cur { background: color-mix(in srgb, var(--fc) 16%, transparent); border-radius: .12em; }
.strip .ch.chip { font-size: .6em; align-self: center; background: #EFE5D4; border-radius: .25em; padding: 0 .25em; margin: 0 .12em; }
.strip .ch.chip.cur { background: var(--fc); color: #fff; }
.strip .ch.oopsch { color: #E59CB7; }
.strip .ch.oopsch.typed { color: #D2557F; text-decoration: line-through 4px; }
.strip .ch.gone { opacity: 0; width: 0; padding: 0; overflow: hidden; transition: all .25s; display: inline-block; }
.strip .ch.wobble { animation: wob .38s; }
@keyframes wob { 20% { transform: translateX(-5px) rotate(-4deg); } 50% { transform: translateX(5px) rotate(4deg); } 80% { transform: translateX(-2px); } }
.strip.sewn { animation: sewn .5s; }
@keyframes sewn { 40% { transform: scale(1.02); box-shadow: 0 0 0 4px var(--land), 0 6px 14px var(--shadow); } }
.coach { display: flex; align-items: center; justify-content: center; gap: 16px; padding: 2px 18px; min-height: 66px; }
.coach .bob { width: 56px; height: 64px; flex: none; }
.coach .bubble { max-width: 640px; font-size: 18px; }

/* ---------- overlays / cards ---------- */
.overlay { position: fixed; inset: 0; background: rgba(243, 234, 218, .78); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); display: flex; align-items: center; justify-content: center; padding: 16px; z-index: 50; }
.card { background: var(--cream); padding: 30px 34px 26px; border-radius: 22px; max-width: 560px; width: 100%; text-align: center; }
.card::before { border-color: rgba(200, 85, 61, .35); }
.card h2 { font-family: var(--head); font-weight: 600; font-size: 30px; margin: 4px 0 12px; }
.card p { font-size: 20px; line-height: 1.45; margin: 8px 0 16px; }
.card .card-bob { width: 74px; height: 84px; margin: -66px auto 0; }
.newkeys { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; margin: 8px 0 6px; }
.nk { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.nk small { font-size: 14px; color: var(--ink-soft); max-width: 120px; }
.bigstars .stars { font-size: 56px; }
.stars { letter-spacing: 2px; white-space: nowrap; }
.star { color: rgba(58, 46, 40, .16); }
.star.on { color: #F2B43A; text-shadow: 0 2px 0 #D48F1E; }
.acc { font-size: 20px; margin: 6px 0 14px; }
.acc b { font-family: var(--head); font-size: 34px; }
.btns { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; margin-top: 10px; }
.newsticker { display: flex; align-items: center; justify-content: center; gap: 12px; font-family: var(--head); font-size: 20px; margin: 4px 0 10px; }
.sticker { display: inline-flex; align-items: center; justify-content: center; width: 72px; height: 72px; border-radius: 50%; background: #fff; font-size: 40px; }
.sticker.felt::before { content: ''; position: absolute; inset: 4px; border-radius: 50%; border: 2px dashed rgba(200, 85, 61, .4); }
.pop-in { animation: popin .7s cubic-bezier(.3, 1.6, .5, 1) both .3s; }
@keyframes popin { from { transform: scale(0) rotate(-30deg); } }

/* ---------- map ---------- */
#scr-map { padding: 14px clamp(14px, 3vw, 36px) 20px; gap: 14px; max-width: 1180px; margin: 0 auto; width: 100%; }
.maptop { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.brand { background: var(--thread); color: #fff; padding: 10px 24px 12px; border-radius: 16px; font-family: var(--head); font-weight: 700; font-size: 32px; transform: rotate(-2deg); }
.brand .b2 { color: #FFE3A6; }
.tally { display: flex; gap: 10px; }
.hero { display: flex; align-items: center; gap: 18px 40px; flex-wrap: wrap; justify-content: center; }
.hero-bob { width: 78px; height: 90px; }
.hero .bubble { max-width: 420px; }
.btn.big { font-size: 22px; padding: 16px 28px; }
.quilt { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr)); gap: 16px; }
.patch { background: var(--pt); text-align: left; padding: 18px 18px 16px; border-radius: 18px; display: flex; flex-direction: column; gap: 12px; }
.patch:nth-child(odd) { transform: rotate(-.6deg); }
.patch:nth-child(even) { transform: rotate(.5deg); }
.patch-head { display: flex; gap: 12px; align-items: center; }
.picon { width: 52px; height: 52px; flex: none; border-radius: 50%; background: var(--pc); display: flex; align-items: center; justify-content: center; font-size: 28px; box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .12); }
.patch h2 { font-family: var(--head); font-weight: 600; font-size: 23px; margin: 0; }
.patch-head small { color: var(--ink-soft); font-size: 15px; letter-spacing: .5px; }
.patch.locked { background: #EDE4D4; box-shadow: none; outline: 2px dashed rgba(120, 100, 80, .35); outline-offset: -2px; }
.patch.locked .picon { filter: grayscale(1); opacity: .5; }
.patch.locked h2, .patch.locked .patch-head small { opacity: .6; }
.pinned { font-size: 15px; color: var(--ink-soft); }
.lbtns { display: flex; flex-wrap: wrap; gap: 10px 6px; }
.lbtn { background: none; border: 0; padding: 0; display: flex; flex-direction: column; align-items: center; gap: 3px; width: 82px; }
.lbtn em { font-style: normal; font-size: 13px; line-height: 1.15; text-align: center; color: var(--ink); min-height: 2.3em; }
.lbtn .stars { font-size: 14px; letter-spacing: 0; }
.sew {
  width: 58px; height: 58px; border-radius: 50%; background: var(--pc); color: #fff; display: flex; align-items: center; justify-content: center;
  font-family: var(--head); font-weight: 700; font-size: 24px; position: relative;
  box-shadow: inset 0 -4px 0 rgba(0, 0, 0, .15), 0 3px 6px var(--shadow);
}
.sew::before { content: ''; position: absolute; inset: 5px; border-radius: 50%; border: 2px dashed rgba(255, 255, 255, .7); }
.lbtn.open .sew { background: var(--cream); color: var(--pc); box-shadow: inset 0 0 0 3px var(--pc), 0 3px 6px var(--shadow); }
.lbtn.open .sew::before { border-color: var(--pc); opacity: .5; }
.lbtn.next .sew { background: var(--cream); color: var(--ink); box-shadow: 0 0 0 4px var(--thread), 0 4px 10px var(--shadow); animation: bounce 1.4s ease-in-out infinite; }
.lbtn.next .sew::before { border-color: var(--thread); }
@keyframes bounce { 50% { transform: translateY(-5px); } }
.lbtn.shut { cursor: default; }
.lbtn.shut .sew { background: #DDD3C3; color: #B3A696; box-shadow: none; }
.lbtn.shut .sew::before { border-color: #B9AD9D; }
.lbtn.shut em { opacity: .55; }
.lbtn:not(.shut):hover .sew { transform: translateY(-3px); }
button.patch { border: 0; font: inherit; cursor: pointer; }
.play .rain-demo { display: flex; gap: 16px; padding-left: 8px; height: 56px; align-items: flex-start; }
.rain-demo i { width: 40px; height: 40px; border-radius: 50%; background: var(--c); color: #fff; font-style: normal; font-size: 22px; font-weight: 700; display: flex; align-items: center; justify-content: center; box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .15); animation: drift 2.4s ease-in-out infinite; }
.rain-demo i:nth-child(2) { animation-delay: -.8s; } .rain-demo i:nth-child(3) { animation-delay: -1.6s; }
@keyframes drift { 50% { transform: translateY(14px) rotate(8deg); } }
.best { margin: 0; font-family: var(--head); font-size: 17px; }
.mini-stickers { display: flex; gap: 6px; font-size: 32px; flex-wrap: wrap; }
.mini-stickers .empty { width: 46px; height: 46px; border-radius: 50%; border: 2px dashed rgba(120, 100, 80, .4); display: flex; align-items: center; justify-content: center; font-size: 20px; color: var(--ink-soft); }
.mapfoot { text-align: center; margin-top: 6px; }

/* ---------- stickers ---------- */
.book { background: #F7E1EA; margin: 10px clamp(14px, 3vw, 36px) 24px; padding: 30px; border-radius: 22px; }
.sgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 18px; }
.slot { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; }
.slot small { color: var(--ink-soft); font-size: 13px; }
.sticker.ghost { background: transparent; border: 2px dashed rgba(120, 100, 80, .4); color: rgba(120, 100, 80, .5); font-size: 28px; font-family: var(--head); }
.slot.got .sticker { transform: rotate(-4deg); }
.slot.got:nth-child(even) .sticker { transform: rotate(5deg); }

/* ---------- game ---------- */
#scr-game { gap: 8px; padding-bottom: 8px; }
.gstat { display: flex; gap: 8px; }
.field { flex: 1; min-height: 260px; margin: 0 18px; border-radius: 22px; overflow: hidden; background: linear-gradient(#CFE6F2, #EAF3EC 75%); }
.field::after { opacity: .12; }
.grass { position: absolute; left: 0; right: 0; bottom: 0; height: 34px; background: #8CC063; z-index: 2; border-top: 3px dashed rgba(255, 255, 255, .6); }
.drop { position: absolute; left: 0; top: 0; z-index: 4; will-change: transform; font-weight: 700; color: #fff; }
.drop.button { width: 64px; height: 64px; border-radius: 50%; background: var(--c); display: flex; align-items: center; justify-content: center; font-size: 34px; box-shadow: inset 0 -5px 0 rgba(0, 0, 0, .15), 0 5px 10px var(--shadow); }
.drop.button::before { content: ''; position: absolute; inset: 6px; border-radius: 50%; border: 2px dashed rgba(255, 255, 255, .7); }
.drop.ribbon { background: var(--cream); color: #B3A496; padding: 8px 16px; border-radius: 12px; font-size: 32px; border-left: 10px solid var(--c); box-shadow: 0 5px 10px var(--shadow); }
.drop.ribbon span.got { color: var(--ink); }
.drop.locked { box-shadow: 0 0 0 4px #fff, 0 0 0 7px var(--c), 0 5px 10px var(--shadow); }
.drop.popping { animation: popgone .38s forwards; }
@keyframes popgone { to { opacity: 0; scale: 1.6; } }
.drop.landed { opacity: .35; transition: opacity .6s; }
.drop.wobble span { display: inline-block; animation: wob .35s; }
.fluff { position: absolute; width: 12px; height: 12px; border-radius: 50%; z-index: 5; animation: fluff .55s ease-out forwards; }
@keyframes fluff { to { transform: translate(var(--dx), var(--dy)) scale(.3); opacity: 0; } }
.cheerpop { position: absolute; left: 50%; top: 30%; transform: translateX(-50%); background: var(--cream); padding: 8px 18px; border-radius: 14px; font-family: var(--head); font-weight: 600; font-size: 24px; z-index: 6; animation: cheerup 1.1s forwards; }
@keyframes cheerup { from { opacity: 0; } 20% { opacity: 1; } 80% { opacity: 1; } to { opacity: 0; translate: 0 -20px; } }

/* ---------- parent ---------- */
#scr-parent { padding-bottom: 30px; -webkit-user-select: text; user-select: text; }
.gate { margin: 60px auto; max-width: 380px; }
.gate input { font-size: 28px; width: 140px; text-align: center; padding: 8px; border-radius: 12px; border: 2px solid #D9CBB4; background: #fff; font-family: var(--head); margin: 0 8px 12px 0; }
.pwrap { max-width: 1100px; margin: 0 auto; padding: 8px 18px; display: flex; flex-direction: column; gap: 16px; width: 100%; }
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px; }
.tile { background: var(--cream); padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; }
.tile small { color: var(--ink-soft); font-size: 14px; }
.tile b { font-family: var(--head); font-size: 26px; font-weight: 600; }
.tile b small { font-size: 13px; font-weight: 400; }
.panel { background: var(--cream); padding: 16px 20px; border-radius: 18px; }
.panel h3 { font-family: var(--head); font-weight: 600; font-size: 21px; margin: 0 0 4px; }
.heatkb { --u: min(52px, calc((100vw - 90px) / 14.8)); display: flex; justify-content: center; margin-top: 10px; overflow-x: auto; }
.heatkb .kbhost, .heatkb { padding: 0; }
.two { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 16px; }
.tricky { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.tricky li { display: grid; grid-template-columns: 70px 50px 1fr; align-items: center; gap: 10px; }
.kcap { background: #EE8360; color: #fff; font-weight: 700; border-radius: 8px; padding: 6px 0; text-align: center; font-size: 15px; }
.bars { display: flex; align-items: flex-end; gap: 6px; height: 130px; margin: 10px 0 6px; }
.bar { flex: 1; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 4px; }
.bar i { width: 100%; min-height: 2px; background: #86BC57; border-radius: 5px 5px 2px 2px; }
.bar small { font-size: 12px; color: var(--ink-soft); }
.hist { width: 100%; border-collapse: collapse; font-size: 15px; margin-top: 8px; }
.hist th { text-align: left; color: var(--ink-soft); font-weight: 400; font-size: 13px; padding: 4px 6px; }
.hist td { padding: 6px; border-top: 1px dashed #DCCFBC; }
.hist .stars { font-size: 15px; }
.settings label { display: flex; align-items: center; gap: 10px; font-size: 17px; margin: 8px 0; }
.settings input[type=checkbox] { width: 22px; height: 22px; accent-color: var(--thread); }
.settings select { font-size: 16px; padding: 4px 8px; border-radius: 8px; }
.settings .btn { font-size: 15px; padding: 6px 0; color: #A8442F; }

/* ---------- smaller screens ---------- */
@media (max-width: 700px) {
  .ltitle { font-size: 18px; }
  .stitches i { width: 12px; }
  .brand { font-size: 26px; }
  .card { padding: 26px 20px 20px; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* Tall screens (iPad portrait): keep the lesson block centred instead of stuck to the top. */
#scr-lesson .strip-wrap { margin-top: auto; }
#scr-lesson .handhost { margin-bottom: auto; }

/* ================= fun layer ================= */
/* sound / music / voice switches */
.toggles { display: flex; gap: 6px; }
.tog { width: 40px; height: 40px; border-radius: 50%; background: var(--cream); font-size: 19px; line-height: 1; padding: 0; display: flex; align-items: center; justify-content: center; }
.tog.off { opacity: .45; filter: grayscale(1); }
.tog.off::before { content: ''; position: absolute; left: 8px; right: 8px; top: 50%; height: 3px; background: #A8442F; transform: rotate(-35deg); border-radius: 2px; z-index: 4; }
.tright { display: flex; align-items: center; gap: 12px; justify-content: flex-end; }
.tally { align-items: center; }
.gstat { align-items: center; }

/* streak flame */
.streak { background: #FFE9C2; padding: 5px 12px; border-radius: 999px; font-family: var(--head); font-weight: 700; font-size: 18px; color: #B4541F; }
.streak.boom { animation: boom .6s cubic-bezier(.3, 1.8, .5, 1); }
@keyframes boom { 0% { transform: scale(1); } 40% { transform: scale(1.6) rotate(-6deg); } 100% { transform: scale(1); } }

/* sparkle ring when a key is pressed right */
.key .ring { position: absolute; inset: -4px; border-radius: calc(var(--u) * .26); border: 3px solid var(--fc, #fff); pointer-events: none; animation: ring .42s ease-out forwards; }
@keyframes ring { from { opacity: .9; transform: scale(.9); } to { opacity: 0; transform: scale(1.45); } }

/* confetti + floating points */
#fx { position: fixed; inset: 0; pointer-events: none; z-index: 100; overflow: hidden; }
.confetto { position: absolute; width: 11px; height: 11px; border-radius: 2px; margin: -5px 0 0 -5px; box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .12); }
.confetto.round { border-radius: 50%; }
.confetto.long { width: 6px; height: 16px; }
.floater { position: absolute; transform: translate(-50%, -50%); font-family: var(--head); font-weight: 700; font-size: 30px; text-shadow: 0 2px 0 #fff, 0 0 8px #fff; animation: floatup .9s ease-out forwards; }
@keyframes floatup { to { transform: translate(-50%, -150%); opacity: 0; } }

/* Bobbin is alive: a little bob when idle, a dance when cheering */
.bobbin.happy { animation: idle 2.4s ease-in-out infinite; }
@keyframes idle { 50% { transform: translateY(-3px) rotate(1.5deg); } }
.bobbin.cheer { animation: dance .9s ease-in-out 2; }
@keyframes dance { 0%, 100% { transform: none; } 20% { transform: translateY(-12px) rotate(-10deg); } 45% { transform: translateY(0) rotate(0); } 65% { transform: translateY(-10px) rotate(10deg); } }

/* results: stars land one by one */
.bigstars.reveal .star.on { color: rgba(58, 46, 40, .16); text-shadow: none; display: inline-block; }
.bigstars.reveal .star.on.in { color: #F2B43A; text-shadow: 0 2px 0 #D48F1E; animation: starin .55s cubic-bezier(.3, 1.8, .5, 1); }
@keyframes starin { from { transform: scale(2.4) rotate(-40deg); opacity: 0; } }

/* game extras */
.pill.bump { animation: boom .35s; }
.countdown { position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%); z-index: 8; font-family: var(--head); font-weight: 700; font-size: 110px; color: var(--thread); text-shadow: 0 5px 0 #fff, 0 8px 18px var(--shadow); }
.countdown.beat { animation: beat .6s ease-out; }
@keyframes beat { from { transform: translate(-50%, -50%) scale(1.8); opacity: 0; } 30% { opacity: 1; } }
.drop.gold { background: radial-gradient(circle at 35% 30%, #FFF2B8, #F2C440 45%, #D9A21B); color: #7A4E0A; box-shadow: 0 0 0 3px #fff, 0 0 18px 4px rgba(255, 210, 80, .8), inset 0 -5px 0 rgba(0, 0, 0, .12); animation: shimmer 1s ease-in-out infinite; }
@keyframes shimmer { 50% { box-shadow: 0 0 0 3px #fff, 0 0 26px 9px rgba(255, 210, 80, .95), inset 0 -5px 0 rgba(0, 0, 0, .12); } }
.flower { position: absolute; bottom: 10px; font-size: 26px; transform-origin: 50% 100%; transform: rotate(var(--r)); animation: grow .5s cubic-bezier(.3, 1.6, .5, 1); z-index: 3; }
@keyframes grow { from { transform: scale(0) rotate(var(--r)); } }
.grass { z-index: 3; }

/* ---------------- Voice-first guide (for children who can't read yet) ---------------- */
/* Map: a hand points at the button to press. */
.gobox { display: flex; align-items: center; gap: 8px; }
.pointer { font-size: 44px; animation: point 1.1s ease-in-out infinite; }
@keyframes point { 50% { transform: translateX(10px); } }
/* Tap Bobbin to hear it again. */
.hero-bob, .coach .bob, .card-bob, .stage-bob { cursor: pointer; }
.hop svg { animation: hop .45s; }
/* House button instead of the word "Map". */
.back, .btn.ghost[data-act=map] { font-size: 26px; line-height: 1; padding: 6px 14px; }
.lbtn.wobble { animation: wob .4s; }
/* Meet the keys: the new key shown big in Bobbin's bubble, in its finger's colour. */
.meetcap { display: inline-block; min-width: 1.6em; padding: 2px 10px; margin-right: 4px; border-radius: 10px; text-align: center;
  font-family: var(--head); font-weight: 700; font-size: 1.5em; color: #fff; background: var(--fc, #97A1AB); box-shadow: 0 3px 0 rgba(0,0,0,.18); vertical-align: middle; }
#scr-lesson.meeting .strip-wrap { visibility: hidden; }

/* ---------------- Bobbin is alive: breathes, talks, waves, sleeps ---------------- */
.bobbin .body, .bobbin .arm-l, .bobbin .arm-r, .bobbin .mouth-talk { transform-box: view-box; }
.bobbin .body { transform-origin: 40px 84px; animation: breathe-b 2.6s ease-in-out infinite; }
@keyframes breathe-b { 50% { transform: scale(1.025, .975); } }
.bobbin .arm-l { transform-origin: 15px 48px; }
.bobbin .arm-r { transform-origin: 65px 48px; }
.bobbin .mouth-talk { display: none; transform-origin: 40px 54px; }
/* talking: the open mouth flaps, the body bounces, the arms move like he explains */
.bob-talking .bobbin .mouth { display: none; }
.bob-talking .bobbin .mouth-talk { display: inline; transition: transform .05s linear;
  transform: scale(calc(.7 + .3 * var(--mo, 0)), calc(.1 + 1 * var(--mo, 0))); }
/* the body follows the voice too: up and a little taller on loud sounds, still in the pauses */
.bob-talking .bobbin .body { animation: none; transition: transform .07s linear;
  transform: translateY(calc(var(--mo, 0) * -3px)) scale(calc(1 - .03 * var(--mo, 0)), calc(1 + .045 * var(--mo, 0))); }
.bob-talking .bobbin .arm-l { animation: armL .84s ease-in-out infinite; }
.bob-talking .bobbin .arm-r { animation: armR .84s ease-in-out infinite .2s; }
@keyframes armL { 50% { transform: rotate(28deg); } }
@keyframes armR { 50% { transform: rotate(-34deg); } }
/* waving hello */
.bobbin.wave .arm-r { animation: wave .5s ease-in-out 4 !important; }
@keyframes wave { 0%, 100% { transform: rotate(-95deg); } 50% { transform: rotate(-135deg); } }
/* asleep: slow deep breaths */
.bobbin.sleep .body { animation: snore 3s ease-in-out infinite; }
@keyframes snore { 50% { transform: scale(1.05, .95); } }
/* bigger Bobbin where he talks to the child */
.hero-bob { width: 124px; height: 140px; }
.coach .bob { width: 78px; height: 88px; }

/* ---------------- Opening stage: Bobbin asleep at night; tap him and morning comes ---------------- */
.stage { position: fixed; inset: 0; z-index: 50; overflow: hidden; display: flex; align-items: center; justify-content: center;
  transition: opacity .45s, transform .45s; }
.stage.gone { opacity: 0; transform: scale(1.05); pointer-events: none; }
.stage .sky { position: absolute; inset: 0; background: linear-gradient(#26345E, #475A8F 70%, #5D6FA0); }
.stage .sky::before { content: ''; position: absolute; inset: 0; background: linear-gradient(#A9DCF0, #FFF3D6 75%); opacity: 0; transition: opacity 1.6s; }
.stage .sky::after { content: ''; position: absolute; inset: 0; background-image: url(felt-grain.png); background-size: 128px; opacity: .35; }
.stage.awake .sky::before { opacity: 1; }
.stage .moon { position: absolute; right: 12%; top: 12%; width: 86px; height: 86px; border-radius: 50%; background: #F6E7B0;
  box-shadow: inset -16px -6px 0 #E3CF8C, 0 0 40px rgba(246, 231, 176, .5); transition: transform 1.4s, opacity 1.2s; }
.stage.awake .moon { transform: translateY(-180px); opacity: 0; }
.stage .sun { position: absolute; left: 10%; top: 10%; width: 110px; height: 110px; border-radius: 50%; background: #F7C548;
  box-shadow: 0 0 0 14px rgba(247, 197, 72, .35), 0 0 0 30px rgba(247, 197, 72, .15); transform: translateY(260px); opacity: 0;
  transition: transform 1.6s cubic-bezier(.2, .9, .3, 1.2), opacity 1s; }
.stage.awake .sun { transform: none; opacity: 1; animation: sunspin 8s linear infinite 1.6s; }
@keyframes sunspin { 50% { box-shadow: 0 0 0 20px rgba(247, 197, 72, .3), 0 0 0 40px rgba(247, 197, 72, .12); } }
.stage .twinkle { position: absolute; color: #FCE9A8; font-style: normal; font-size: 26px; animation: twinkle 1.8s ease-in-out infinite; transition: opacity 1s; }
@keyframes twinkle { 50% { transform: scale(.6); opacity: .5; } }
.stage.awake .twinkle { opacity: 0; }
.stage .bunting { position: absolute; top: 0; left: -2%; right: -2%; display: flex; justify-content: space-between; }
.stage .bunting::before { content: ''; position: absolute; left: 0; right: 0; top: 6px; border-top: 3px dashed #F3EADA; opacity: .8; }
.stage .bunting i { width: 5.5%; height: 64px; margin-top: 6px; background: var(--c); clip-path: polygon(0 0, 100% 0, 50% 100%);
  animation: flutter 2.4s ease-in-out infinite; transform-origin: top center; }
.stage .bunting i:nth-child(odd) { animation-delay: -1.2s; }
@keyframes flutter { 50% { transform: rotate(4deg) scaleY(.94); } }

.stage .hill { position: absolute; border-radius: 50%; }
.stage .hill.h1 { left: -20%; right: 30%; bottom: -28vh; height: 52vh; background: #86B865; }
.stage .hill.h2 { left: 35%; right: -25%; bottom: -32vh; height: 54vh; background: #6DA352; }
.stage .hill::after { content: ''; position: absolute; inset: 14px; border-radius: 50%; border: 3px dashed rgba(255, 255, 255, .45); }

.stage-main { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 22px; margin-top: 4vh; }
.stage-bob { position: relative; width: min(46vw, 230px); height: min(52vw, 262px); transition: transform .6s cubic-bezier(.3, 1.6, .5, 1); }
.stage.awake .stage-bob { transform: scale(.82); }
.stage-bob .bobwrap { position: relative; z-index: 2; width: 100%; height: 100%; }
.stage-bob .cushion { position: absolute; z-index: 1; left: -12%; right: -12%; bottom: -4%; height: 26%; border-radius: 50%;
  background: radial-gradient(ellipse at 50% 35%, #E9837A, #C8553D 70%); box-shadow: 0 10px 20px rgba(0, 0, 0, .25); }
.stage-bob .cushion::after { content: ''; position: absolute; inset: 10% 8%; border-radius: 50%; border: 2.5px dashed rgba(255, 240, 220, .7); }
.stage-bob .zzz { position: absolute; z-index: 3; right: -18%; top: -6%; }
.stage-bob .zzz b { position: absolute; font-family: var(--head); font-weight: 700; color: #fff; text-shadow: 0 2px 0 rgba(0, 0, 0, .2);
  animation: zfloat 3s ease-in infinite; opacity: 0; }
.stage-bob .zzz b:nth-child(1) { font-size: 48px; }
.stage-bob .zzz b:nth-child(2) { font-size: 36px; animation-delay: 1s; }
.stage-bob .zzz b:nth-child(3) { font-size: 28px; animation-delay: 2s; }
@keyframes zfloat { 0% { transform: translate(0, 40px) rotate(-10deg); opacity: 0; } 20% { opacity: 1; } 100% { transform: translate(40px, -70px) rotate(12deg); opacity: 0; } }
.stage-bob .ring { position: absolute; z-index: 0; inset: -8% -14%; border-radius: 50%; border: 5px dashed rgba(255, 255, 255, .7); animation: ring 1.6s ease-in-out infinite; }
@keyframes ring { 50% { transform: scale(1.08); opacity: .5; } }
.stage-bob .wakehand { position: absolute; z-index: 4; right: -46%; bottom: -8%; font-size: min(18vw, 88px); animation: wakepoke 1.2s ease-in-out infinite;
  filter: drop-shadow(0 4px 4px rgba(0, 0, 0, .25)); }
@keyframes wakepoke { 0%, 100% { transform: translate(0, 0) rotate(-30deg); } 50% { transform: translate(-26px, -22px) rotate(-30deg); } }
.stage.awake .zzz, .stage.awake .ring, .stage.awake .wakehand { display: none; }
.stage-go { display: flex; flex-direction: column; align-items: center; gap: 20px; margin-top: 64px; opacity: 0; transform: translateY(40px); pointer-events: none;
  transition: opacity .6s 1.4s, transform .6s cubic-bezier(.3, 1.5, .5, 1) 1.4s; }
.stage.awake .stage-go { opacity: 1; transform: none; pointer-events: auto; }
.spacebar { position: relative; width: min(82vw, 520px); height: 92px; border: 0; border-radius: 22px; background: #FFF8EC;
  box-shadow: 0 9px 0 #CDBBA2, 0 14px 22px rgba(0, 0, 0, .2); animation: keypress 1.4s ease-in-out infinite; }
/* the glow is a separate ring, so it never fights the press */
.spacebar::before { content: ''; position: absolute; inset: -6px; border-radius: 26px; border: 5px solid rgba(109, 181, 71, .75); animation: keyglow 1.4s ease-out infinite; pointer-events: none; }
/* a real key press, timed with the hand: the face sinks into the key's base (the base stays put), darkens a
   little and the shadow shrinks; then it springs back up */
@keyframes keypress {
  0%, 38%, 72%, 100% { transform: none; box-shadow: 0 9px 0 #CDBBA2, 0 14px 22px rgba(0, 0, 0, .2); background: #FFF8EC; }
  46%, 62% { transform: translateY(7px); box-shadow: 0 2px 0 #CDBBA2, 0 4px 8px rgba(0, 0, 0, .18); background: #F1E5D0; }
}
@keyframes keyglow { 0%, 40% { opacity: 0; transform: none; } 50% { opacity: 1; transform: none; } 100% { opacity: 0; transform: scale(1.06, 1.25); } }
.spacebar .sb-word { font-family: var(--head); font-weight: 600; font-size: 34px; color: #8C939B; letter-spacing: .04em; }
/* the finger comes down onto the key exactly when the key goes down */
.spacebar .press { position: absolute; left: 50%; top: -66px; margin-left: -32px; font-size: 64px; animation: presshand 1.4s ease-in-out infinite;
  filter: drop-shadow(0 4px 4px rgba(0, 0, 0, .25)); }
@keyframes presshand { 0%, 100% { transform: translateY(-16px); } 38% { transform: translateY(0); } 46%, 62% { transform: translateY(7px); } 72% { transform: translateY(0); } }
/* when the child really presses space (or taps it) */
.spacebar.down { animation: none; transform: translateY(7px); box-shadow: 0 2px 0 #CDBBA2, 0 4px 8px rgba(0, 0, 0, .18); background: #E9F5E0; }
.sb-label { font-family: var(--head); font-weight: 600; font-size: 20px; color: var(--ink); background: rgba(255, 248, 236, .85); padding: 4px 14px; border-radius: 999px; }
.stage-more { display: flex; gap: 14px; margin-top: 6px; }
.stage-more button { width: 64px; height: 64px; border-radius: 50%; border: 0; background: #FFF8EC; font-size: 30px; box-shadow: 0 5px 0 #CDBBA2; }
/* the map's start button is the same glowing space bar, a bit smaller */
.gobox { flex-direction: column; gap: 18px; padding: 72px 0 6px; }
.spacebar.small { width: min(78vw, 340px); height: 70px; border-radius: 18px; }
.spacebar.small .sb-word { font-size: 26px; }
.spacebar.small .press { top: -52px; font-size: 48px; margin-left: -24px; }
.spacebar.small::before { border-radius: 22px; }

/* ---------------- Felt icons (js/icons.js) instead of phone emoji ---------------- */
.ficon { width: 1.25em; height: 1.25em; vertical-align: -0.28em; display: inline-block; overflow: visible; }
.ficon.down { transform: rotate(180deg); }
.tog .ficon { width: 26px; height: 26px; vertical-align: middle; }
.tog.off .ficon { filter: grayscale(.9) opacity(.55); }
.back .ficon, .btn.ghost[data-act=map] .ficon { width: 30px; height: 30px; vertical-align: middle; }
.picon .ficon { width: 34px; height: 34px; vertical-align: middle; }
.pill .ficon { width: 22px; height: 22px; }
.star .ficon { width: 1em; height: 1em; vertical-align: -0.12em; }
.star:not(.on) .ficon, .bigstars.reveal .star.on:not(.in) .ficon { filter: grayscale(1) opacity(.28); }
.wakehand .ficon { width: min(18vw, 92px); height: min(18vw, 92px); }
.spacebar .press .ficon { width: 64px; height: 64px; }
.spacebar.small .press .ficon { width: 50px; height: 50px; }
.flower .ficon { width: 30px; height: 30px; filter: hue-rotate(var(--hue, 0deg)); }
.pinned .ficon { width: 20px; height: 20px; }
.streak .ficon { width: 20px; height: 20px; }

/* ---------------- Button Rain: Bobbin in the field instead of a card ---------------- */
.gscene { position: absolute; inset: 0; z-index: 7; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px; padding: 16px 16px 50px; }
.gs-talk { display: flex; align-items: center; gap: 16px; }
.gs-bob { width: 110px; height: 124px; flex: none; }
.gscene .bubble { position: relative; font-size: 21px; max-width: 420px; }
.gscene .gbig { font-family: var(--head); font-size: 38px; color: var(--thread); }
.gscene .gbig .ficon { width: 38px; height: 38px; }
.gscene .spacebar.small { margin-top: 48px; }
.gscene .newsticker .sticker { font-size: 52px; }
.gdemo { display: flex; gap: 18px; }
.gdemo .drop { position: relative; transform: none; animation: demobob 1.8s ease-in-out infinite; }
.gdemo .drop:nth-child(2) { animation-delay: -.45s; } .gdemo .drop:nth-child(3) { animation-delay: -.9s; } .gdemo .drop:nth-child(4) { animation-delay: -1.35s; }
@keyframes demobob { 50% { transform: translateY(-10px) rotate(6deg); } }
/* header pills: icon and text on one line, centred */
.pill { display: inline-flex; align-items: center; gap: 6px; }
.pill .ficon { vertical-align: 0; }
/* game and sticker badges: a cream felt circle, so the red button and the pink book stand out */
.patch.play .picon, .patch.book .picon { background: #FFF6E6; box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .08), 0 0 0 3px var(--pc); }
.picon .ficon { display: block; }

/* speed: falling things get their own layer; the game field doesn't repaint under them */
.drop { will-change: transform; contain: layout paint; }
.field { contain: layout paint; }

/* night is a dark veil over the hills and flags that fades away (a filter on each part was slow to animate) */
.stage .nightveil { position: absolute; inset: 0; background: rgba(22, 28, 64, .5); transition: opacity 1.4s; pointer-events: none; }
.stage.awake .nightveil { opacity: 0; }
.stage-main { z-index: 3; }
.stage .nightveil { z-index: 1; }
.stage .moon, .stage .twinkle, .stage .sun { z-index: 2; }
