/* ===== Belajar Berhitung — gaya v3 "Petualangan Kancil" =====
   Dunia langit-dan-bukit, garis tinta 2–2.5px + bayangan padat ala stiker, judul Baloo 2. */
@font-face { font-family: 'Baloo 2'; font-style: normal; font-weight: 500 800; font-display: swap; src: url('./fonts/baloo2.woff2') format('woff2'); }
@font-face { font-family: 'Fredoka'; font-style: normal; font-weight: 400 700; font-display: swap; src: url('./fonts/fredoka.woff2') format('woff2'); }
@font-face { font-family: 'Nunito'; font-style: normal; font-weight: 400 900; font-display: swap; src: url('./fonts/nunito.woff2') format('woff2'); }

:root {
  --font-head: 'Baloo 2', 'Fredoka', ui-rounded, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-body: 'Nunito', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --ink: #1F2A44;
  /* Abu-abu keterangan. Dulu #6B7A99: 4,31:1 di putih dan 4,01:1 di krem, di bawah batas
     4,5:1 untuk huruf kecil. Sedikit digelapkan jadi 5,27 dan 4,90, tampilannya nyaris sama. */
  --muted: #5E6C8A;
  --line: #E9EEF5;
  --soft: #F4F7FB;
  --cream: #FFF6E3;
  --paper: #FFFBF0;

  --sky: #3EC1F3;  --sky-dark: #1A8FC7;  --sky-soft: #E3F5FE;
  --orange: #FF9F43; --orange-dark: #E0761C; --orange-soft: #FFEFD9;
  --green: #35C96A; --green-dark: #1F9A4C; --green-soft: #E2F8EA;
  --red: #FF5C6C;  --red-soft: #FFE5E8;
  --yellow: #FFD23F; --yellow-dark: #D9A400; --yellow-soft: #FFF6CC;
  --purple: #9B7BFF; --purple-dark: #6E4FE0; --purple-soft: #EEE8FF;
  --pink: #FF6FA5;  --pink-dark: #D9407C;  --pink-soft: #FFE5EF;
  --teal: #2DD4BF;  --teal-dark: #0FA394;  --teal-soft: #DDF8F4;

  --bw: 2px;            /* tebal garis tinta */
  --bw-lg: 2.5px;
  /* Bibir tombol: garis tinta tipis (1,5-2 piksel) ditambah bayangan lembut di bawahnya.
     Dulu 2, 3, dan 4 piksel tinta pekat tanpa bayangan lembut — terbaca tebal dan berat
     di tombol besar, pita tahap, dan titik peta. */
  --lift: 0 2px 0 var(--ink), 0 6px 14px rgba(31, 42, 68, .14);
  --lift-sm: 0 1.5px 0 var(--ink), 0 3px 8px rgba(31, 42, 68, .10);
  --lift-md: 0 2px 0 var(--ink), 0 5px 12px rgba(31, 42, 68, .14);
  /* Dua jenis bayangan, dan bedanya disengaja.
     Yang BISA DITEKAN (tombol, papan angka, titik peta) memakai bibir tinta tipis: itu
     tanda "tekan aku" bagi anak, dan tombolnya turun saat ditekan.
     Yang TIDAK bisa ditekan (kartu, balon kata, kotak angka) memakai bayangan lembut.
     Dulu keduanya sama-sama bibir tinta 3-4 piksel, sehingga kartu terlihat berat dan
     ikut tampak seperti tombol. */
  --bayang-panel: 0 3px 0 rgba(31, 42, 68, .13), 0 10px 24px rgba(31, 42, 68, .10);
  --bayang-kecil: 0 2px 0 rgba(31, 42, 68, .14), 0 4px 10px rgba(31, 42, 68, .07);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-6: 28px;
}

/* warna per tahap */
/* --accent-text: warna TULISAN kecil per tahap. Warna -dark lama hanya 3,1-3,6:1 di atas
   putih untuk hijau, oranye, biru, dan toska, padahal dipakai untuk label 12 piksel. */
[data-stage="s0"] { --accent: var(--purple); --accent-dark: var(--purple-dark); --accent-soft: var(--purple-soft); --accent-text: #5B3CC9; }
[data-stage="s1"] { --accent: var(--green);  --accent-dark: var(--green-dark);  --accent-soft: var(--green-soft); --accent-text: #177A3C; }
[data-stage="s2"] { --accent: var(--orange); --accent-dark: var(--orange-dark); --accent-soft: var(--orange-soft); --accent-text: #A8520B; }
[data-stage="s3"] { --accent: var(--sky);    --accent-dark: var(--sky-dark);    --accent-soft: var(--sky-soft); --accent-text: #136E9C; }
[data-stage="s4"] { --accent: var(--pink);   --accent-dark: var(--pink-dark);   --accent-soft: var(--pink-soft); --accent-text: #B02A62; }
[data-stage="s5"] { --accent: var(--teal);   --accent-dark: var(--teal-dark);   --accent-soft: var(--teal-soft); --accent-text: #0B7A6F; }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; min-height: 100%; }
body {
  font-family: var(--font-body); color: var(--ink); font-size: 17px; line-height: 1.45;
  background: var(--cream); background-attachment: fixed;
  overscroll-behavior: none; -webkit-user-select: none; user-select: none; touch-action: manipulation; -webkit-font-smoothing: antialiased;
  transition: background .25s;
}
/* latar per layar (dipasang di body oleh app.js) */
body.bg-sky, body.bg-map { background: linear-gradient(180deg, #8FD9FF 0%, #C9ECFF 44%, #8EDC7A 44%, #67C85B 100%); background-attachment: fixed; }
/* Latar layar berlangit disusun berlapis, bukan satu gambar utuh. Pita semak, bukit,
   dan awan diulang mendatar, jadi layar selebar apa pun terisi tanpa gambarnya
   dibesarkan — itu yang dulu bikin latar pecah di desktop. Urutannya dari depan ke
   belakang: semak, bukit, alas rumput, awan, matahari, langit. */
body.bg-sky {
  background-color: #CFEFFF;
  background-image:
    url('./img/bg/semak.webp'),
    url('./img/bg/bukit.webp'),
    linear-gradient(#5CD343, #5CD343),
    url('./img/bg/awan.webp'),
    linear-gradient(180deg, #6FCBFF 0%, #A8E4FF 58%, #CFEFFF 100%);
  background-repeat: repeat-x, repeat-x, no-repeat, repeat-x, no-repeat;
  background-position:
    center bottom,
    center bottom 46px,
    center bottom,
    center top 56px,
    center top;
  background-size:
    auto 82px,
    auto 100px,
    100% 30px,
    auto 68px,
    100% 100%;
  background-attachment: fixed;
}
/* Layar lebar: lapisannya diperbesar dan dua pohon ditambahkan sebagai bingkai kiri
   kanan. Di ponsel pohonnya sengaja tidak dipakai supaya tidak berdesakan dengan isi. */
@media (min-width: 700px) {
  body.bg-sky {
    background-image:
      url('./img/bg/semak.webp'),
      url('./img/bg/pohon-kiri.webp'),
      url('./img/bg/pohon-kanan.webp'),
      url('./img/bg/bukit.webp'),
      linear-gradient(#5CD343, #5CD343),
      url('./img/bg/awan.webp'),
      url('./img/bg/matahari.webp'),
      linear-gradient(180deg, #6FCBFF 0%, #A8E4FF 58%, #CFEFFF 100%);
    background-repeat: repeat-x, no-repeat, no-repeat, repeat-x, no-repeat, repeat-x, no-repeat, no-repeat;
    background-position:
      center bottom,
      left -40px bottom,
      right -40px bottom,
      center bottom 78px,
      center bottom,
      center top 64px,
      left 13% top 84px,
      center top;
    /* Pohon dibuat sekitar tiga kali tinggi semak. Di bawah itu pohonnya terbaca
       seperti perdu, bukan pohon, dan bandingannya dengan semak jadi janggal. */
    background-size:
      auto 150px,
      auto 360px,
      auto 348px,
      auto 180px,
      100% 48px,
      auto 96px,
      104px auto,
      100% 100%;
  }
}
/* Layar sangat lebar: pohonnya dibesarkan lagi supaya tetap sebanding dengan semak.
   Di layar 700-1100 piksel ukuran ini akan menutupi terlalu banyak isi layar. */
@media (min-width: 1100px) {
  body.bg-sky {
    background-size:
      auto 170px,
      auto 480px,
      auto 464px,
      auto 200px,
      100% 54px,
      auto 108px,
      118px auto,
      100% 100%;
  }
}
body.bg-green { background: #35C96A; background-image: radial-gradient(circle at 15% 20%, rgba(255,255,255,.18) 0 50px, transparent 51px), radial-gradient(circle at 90% 60%, rgba(255,255,255,.14) 0 70px, transparent 71px); background-attachment: fixed; }
body.bg-purple { background: #9B7BFF; background-image: radial-gradient(circle at 20% 15%, rgba(255,255,255,.18) 0 40px, transparent 41px), radial-gradient(circle at 85% 30%, rgba(255,255,255,.14) 0 60px, transparent 61px); background-attachment: fixed; }
body.bg-yellow { background: #FFD23F; background-image: repeating-conic-gradient(from 0deg at 50% 30%, rgba(255,255,255,.35) 0 10deg, transparent 10deg 20deg); background-attachment: fixed; }
body.bg-race { background: linear-gradient(180deg, #8FD9FF 0%, #8FD9FF 52%, #1F2A44 52%, #1F2A44 calc(52% + 4px), #E0761C calc(52% + 4px), #E0761C 100%); background-attachment: fixed; }
body.bg-orange { background: #FF9F43; background-attachment: fixed; }
body.bg-cream { background: var(--cream); }

/* Pola coretan angka. Satu petak dipakai di semua layar berwarna polos; kekuatan dan
   warnanya diatur per layar lewat dua peubah. Petaknya diulang, jadi tetap tajam di
   lebar layar berapa pun dan tidak ikut melar seperti gambar tunggal.
   --pola-balik: layar berlatar terang (krem, kuning) memakai coretan gelap, karena
   coretan putih di atasnya tidak akan terlihat. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background-image: url('./img/bg/pola.webp');
  background-size: var(--pola-ukuran, 520px);
  background-repeat: repeat;
  opacity: var(--pola-kuat, 0);
  filter: var(--pola-balik, none);
  pointer-events: none;
  z-index: 0;
}
body.bg-purple { --pola-kuat: .16; }
body.bg-green  { --pola-kuat: .16; }
body.bg-orange { --pola-kuat: .18; }
body.bg-race   { --pola-kuat: .14; }
body.bg-yellow { --pola-kuat: .13; --pola-balik: invert(1); }
body.bg-cream  { --pola-kuat: .07; --pola-balik: invert(1); }
button { font: inherit; cursor: pointer; color: inherit; }
input, textarea, select { font: inherit; -webkit-user-select: text; user-select: text; }
h1, h2, h3 { margin: 0 0 var(--sp-2); line-height: 1.1; font-family: var(--font-head); font-weight: 800; }
h1 { font-size: 36px; } h2 { font-size: 28px; } h3 { font-size: 20px; }
p { margin: 0 0 var(--sp-3); }
b, strong { font-weight: 800; }
.muted { color: var(--muted); }
.center { text-align: center; }
.hidden { display: none !important; }
.eyebrow { font-family: var(--font-head); font-size: 13px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase; color: var(--accent-text, #177A3C); display: flex; align-items: center; gap: 6px; }
.shadow-text { text-shadow: 0 2px 0 #fff; }

#app { max-width: 480px; margin: 0 auto; min-height: 100vh; min-height: 100dvh; padding: calc(var(--sp-3) + var(--safe-top)) var(--sp-5) calc(var(--sp-6) + var(--safe-bottom)); display: flex; flex-direction: column; position: relative; }

/* dekorasi langit */
.cloud { position: absolute; background: #fff; border-radius: 999px; opacity: .7; pointer-events: none; z-index: 0; }
.sun { position: absolute; width: 60px; height: 60px; background: var(--yellow); border-radius: 50%; border: var(--bw) solid var(--ink); box-shadow: 0 0 0 10px rgba(255,210,63,.25); pointer-events: none; z-index: 0; }
#app > *:not(.cloud):not(.sun) { position: relative; z-index: 1; }

/* ---- Top bar ---- */
.topbar { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-4); min-height: 52px; }
.topbar .spacer { flex: 1; }
.topbar .title { font-family: var(--font-head); font-weight: 800; font-size: 24px; line-height: 1.2; }
.pill-title { display: inline-block; font-family: var(--font-head); font-weight: 800; font-size: 22px; line-height: 1.25; background: #fff; border: var(--bw) solid var(--ink); border-radius: 999px; padding: 4px 16px; box-shadow: var(--bayang-kecil); max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pill-title img { height: 26px; vertical-align: -6px; }
.icon-btn { width: 50px; height: 50px; border-radius: 50%; border: var(--bw) solid var(--ink); flex-shrink: 0; background: #fff; box-shadow: var(--lift-sm); font-size: 24px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; transition: transform .08s; }
.icon-btn:active { transform: translateY(2px); box-shadow: none; }
.icon-btn.small { width: 40px; height: 40px; font-size: 20px; }
.icon-btn.yellow { background: var(--yellow); }
.icon-btn:disabled { opacity: .35; }
/* flex-shrink: 0 wajib. Tanpa itu Safari menyusutkan ikon jadi nol lebar
   sehingga tombol tampak kosong. Sama seperti aturan .btn svg. */
.icon-btn svg { width: 26px; height: 26px; flex-shrink: 0; color: var(--ink); }
.icon-btn.small svg { width: 20px; height: 20px; }

/* ---- Pills & tags ---- */
.pill { display: inline-flex; align-items: center; gap: 5px; font-family: var(--font-head); font-weight: 800; font-size: 17px; background: #fff; border: var(--bw) solid var(--ink); border-radius: 999px; padding: 4px 12px; box-shadow: var(--bayang-kecil); white-space: nowrap; line-height: 1.2; }
.pill svg { width: 16px; height: 16px; }
.pill.ink { background: var(--ink); color: #fff; box-shadow: none; }
.pill.ink.gold { color: var(--yellow); }
.pill.yellow { background: var(--yellow); }
.pill.small { font-size: 13px; padding: 2px 9px; }
.tag { display: inline-block; font-family: var(--font-head); font-weight: 800; font-size: 15px; letter-spacing: 1px; text-transform: uppercase; background: var(--ink); color: #fff; border-radius: 999px; padding: 4px 16px; }
.tag.gold { color: var(--yellow); }
.ic-star svg { color: var(--yellow-dark); fill: var(--yellow); }
.ic-fire svg { color: var(--orange-dark); fill: var(--orange); }

/* ---- Cards & buttons ---- */
.card { background: #fff; border: var(--bw-lg) solid var(--ink); border-radius: 30px; padding: 18px; box-shadow: var(--bayang-panel); margin-bottom: var(--sp-4); }
.card.soft { background: rgba(255,255,255,.75); border-width: var(--bw); border-radius: 18px; box-shadow: none; padding: 10px 14px; font-size: 14px; font-weight: 700; line-height: 1.4; }
.card.tip { background: rgba(255,255,255,.78); border-width: var(--bw); border-radius: 18px; box-shadow: none; padding: 10px 14px; font-size: 14px; font-weight: 700; line-height: 1.4; }
.card.success { background: var(--green-soft); }
.card.reward { background: var(--yellow-soft); }
.card.celebrate { background: #fff; }
.card.thin { border-width: var(--bw); border-radius: 22px; padding: 16px; box-shadow: none; }

.btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; border: var(--bw-lg) solid var(--ink); border-radius: 22px; padding: 10px 18px; min-height: 54px; font-family: var(--font-head); font-weight: 800; font-size: 19px; line-height: 1.1; color: var(--ink); background: var(--sky); box-shadow: var(--lift-md); transition: transform .06s, box-shadow .06s; }
.btn:active { transform: translateY(2px); box-shadow: none; }
.btn.block { width: 100%; }
.btn.big { font-size: 26px; min-height: 74px; border-radius: 26px; }
.btn.yellow { background: var(--yellow); color: var(--ink); }
/* Semua tombol berwarna bertulisan tinta. Tulisan putih di hijau hanya 2,16:1, di merah
   muda 2,60:1, dan di biru 2,07:1; tinta di atas warna yang sama 6,60, 5,48, dan 6,88. */
.btn.green { background: var(--green); color: var(--ink); }
.btn.orange { background: var(--orange); color: var(--ink); }
.btn.pink { background: var(--pink); color: var(--ink); }
.btn.purple { background: var(--purple); color: var(--ink); }
.btn.teal { background: var(--teal); color: var(--ink); }
.btn.ghost, .btn.white { background: #fff; color: var(--ink); }
.btn.danger { background: var(--red); }
.btn.btn-small { min-height: 44px; padding: 6px 16px; font-size: 16px; border-radius: 999px; border-width: var(--bw); box-shadow: var(--lift-sm); }
.btn.btn-small:active { transform: translateY(2px); }
.btn:disabled { opacity: .5; transform: none; }
.btn .play { width: 40px; height: 40px; border-radius: 50%; background: var(--ink); color: var(--yellow); display: inline-flex; align-items: center; justify-content: center; }
.btn .play svg { width: 20px; height: 20px; fill: currentColor; stroke: none; margin-left: 3px; }
.btn svg { width: 1.1em; height: 1.1em; flex-shrink: 0; }
.link { display: inline-block; font-family: var(--font-head); font-weight: 800; font-size: 17px; text-decoration: underline; background: none; border: 0; padding: 6px 10px; color: var(--ink); }
.link svg { width: 1.1em; height: 1.1em; vertical-align: -3px; }
.card.soft svg, .card.tip svg { width: 1.1em; height: 1.1em; vertical-align: -3px; }
.row { display: flex; gap: var(--sp-3); }
.row > * { flex: 1; }
.stack { display: flex; flex-direction: column; gap: var(--sp-3); }

/* ---- Kancil ---- */
.kancil { display: flex; align-items: flex-start; gap: 0; margin: 8px 0 var(--sp-4); }
.kancil-img { flex-shrink: 0; width: 150px; height: 150px; margin-left: -18px; filter: drop-shadow(0 8px 0 rgba(31,42,68,.2)); animation: bob 3s ease-in-out infinite; }
.kancil-img img, .kancil-img svg { width: 100%; height: 100%; object-fit: contain; }
.kancil.small .kancil-img { width: 96px; height: 96px; margin-left: -12px; }
.bubble { position: relative; flex: 1; margin-top: 14px; background: #fff; border: var(--bw) solid var(--ink); border-radius: 24px; border-bottom-left-radius: 4px; padding: 14px 16px; font-family: var(--font-head); font-weight: 700; font-size: 19px; line-height: 1.25; box-shadow: var(--bayang-kecil); }
.kancil.small .bubble { font-size: 17px; margin-top: 8px; padding: 12px 14px; }
.bubble b { color: var(--orange-dark); }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }

/* ---- Beranda ---- */
.home-head { display: flex; align-items: center; gap: 10px; }
.home-head .avatar-btn { width: 54px; height: 54px; border-radius: 50%; background: var(--yellow); border: var(--bw) solid var(--ink); box-shadow: var(--lift-sm); font-size: 28px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.home-head .name { font-family: var(--font-head); font-weight: 800; font-size: 26px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mission { padding: 18px; border-radius: 32px; }
.mission-top { display: flex; align-items: center; gap: 14px; }
.mission-ico { width: 72px; height: 72px; border-radius: 22px; background: var(--accent-soft, var(--green-soft)); border: var(--bw) solid var(--ink); display: flex; align-items: center; justify-content: center; font-size: 40px; flex-shrink: 0; }
.mission h2 { font-size: 30px; margin: 0; line-height: 1.05; }
.mission .eyebrow { color: var(--accent-text, #177A3C); }
.seg { display: flex; gap: 6px; margin: 14px 0 6px; }
/* Tanpa keterangan, bilah lima ruas ini tidak bisa ditebak artinya. */
.seg-lbl { text-align: center; font-size: 14px; font-weight: 700; color: var(--muted); margin: 0 0 14px; }
.seg i { flex: 1; height: 16px; border-radius: 999px; background: #fff; border: var(--bw) solid var(--ink); }
.seg i.on { background: var(--green); }
.seg i.half { background: linear-gradient(90deg, var(--green) 50%, #fff 50%); }
.mission .link { display: block; text-align: center; margin: 10px auto 0; color: var(--sky-dark); }
.menu-row { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; margin-top: 22px; }
.menu-row button { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; background: none; border: 0; padding: 0; }
.menu-row .circ { width: 50px; height: 50px; border-radius: 50%; border: var(--bw) solid var(--ink); box-shadow: var(--lift-sm); display: flex; align-items: center; justify-content: center; transition: transform .08s; }
.menu-row button:active .circ { transform: translateY(2px); box-shadow: none; }
.menu-row .circ img { width: 30px; height: 30px; }
/* Ikon menu gambar sendiri: lingkaran warna dan garis tepinya sudah ada di gambarnya,
   jadi lingkaran latar dari CSS dimatikan supaya tidak jadi lingkaran ganda. */
.menu-row .circ.foto { background: none; border: 0; box-shadow: none; }
.menu-row .circ.foto img { width: 50px; height: 50px; filter: drop-shadow(0 3px 0 rgba(31, 42, 68, .25)); }
.menu-row button:active .circ.foto { transform: translateY(2px); }
/* Label menu berada di atas semak yang ramai, jadi perlu garis putih tipis di
   belakang hurufnya supaya tetap terbaca. */
.menu-row span { font-family: var(--font-head); font-weight: 800; font-size: 14px; line-height: 1.1; text-align: center; text-shadow: 0 1px 0 rgba(255, 255, 255, .85), 0 -1px 0 rgba(255, 255, 255, .85), 1px 0 0 rgba(255, 255, 255, .85), -1px 0 0 rgba(255, 255, 255, .85); }
/* Baris versi berada di atas ilustrasi rumput, jadi perlu garis putih tipis di
   belakang hurufnya supaya tetap terbaca. */
/* Jarak bawah menaikkan baris ini di atas pucuk semak, bukan menindihnya. */
.ver-line { text-align: center; font-size: 11px; font-weight: 700; margin: 12px 0 34px; color: var(--ink); opacity: .55; text-shadow: 0 1px 0 rgba(255, 255, 255, .9), 0 -1px 0 rgba(255, 255, 255, .9), 1px 0 0 rgba(255, 255, 255, .9), -1px 0 0 rgba(255, 255, 255, .9); }
.parent-link { display: flex; justify-content: center; margin-top: 22px; }
.parent-link button { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-head); font-weight: 700; font-size: 14px; background: rgba(255,255,255,.7); border: 0; border-radius: 999px; padding: 6px 14px; }
.parent-link svg { width: 14px; height: 14px; }
.stats { display: flex; gap: 6px; }

/* ---- Profil ---- */
.hero-kancil { height: 240px; width: auto; max-width: 100%; object-fit: contain; display: block; margin: 14px auto 0; filter: drop-shadow(0 8px 0 rgba(31,42,68,.2)); animation: bob 3s ease-in-out infinite; }
.profile-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.profile-card { background: #fff; border: var(--bw-lg) solid var(--ink); border-radius: 28px; padding: 18px 12px 14px; box-shadow: var(--lift); text-align: center; transition: transform .08s; }
.profile-card:active { transform: translateY(2px); box-shadow: var(--lift-sm); }
.profile-card .av { width: 88px; height: 88px; border-radius: 50%; background: var(--yellow); border: var(--bw) solid var(--ink); display: flex; align-items: center; justify-content: center; font-size: 50px; margin: 0 auto 10px; }
.profile-card:nth-child(2n) .av { background: var(--sky); }
.profile-card:nth-child(3n) .av { background: var(--pink); }
.profile-card .nm { font-family: var(--font-head); font-weight: 800; font-size: 24px; line-height: 1; }
.profile-card .st { display: inline-flex; gap: 10px; margin-top: 8px; font-family: var(--font-head); font-weight: 800; font-size: 15px; }
.add-card { margin-top: 16px; width: 100%; background: rgba(255,255,255,.55); border: var(--bw-lg) dashed var(--ink); border-radius: 28px; padding: 18px; display: flex; align-items: center; justify-content: center; gap: 12px; font-family: var(--font-head); font-weight: 800; font-size: 20px; }
.add-card .plus { width: 48px; height: 48px; border-radius: 50%; background: var(--yellow); border: var(--bw) solid var(--ink); display: inline-flex; align-items: center; justify-content: center; font-size: 30px; line-height: 1; }
.avatar-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--sp-2); }
.avatar-grid button { font-size: 30px; padding: 8px 0; border-radius: 16px; border: var(--bw) solid transparent; background: var(--soft); transition: transform .08s; }
.avatar-grid button:active { transform: scale(.92); }
.avatar-grid button.sel { border-color: var(--ink); background: var(--yellow-soft); box-shadow: var(--lift-sm); }
.text-input { width: 100%; padding: 12px 14px; border-radius: 16px; border: var(--bw) solid var(--ink); font-size: 20px; background: #fff; color: var(--ink); font-family: var(--font-head); font-weight: 700; }
.text-input:focus { outline: none; box-shadow: 0 0 0 4px var(--yellow-soft); }

/* ---- Peta pulau ---- */
.island { position: relative; margin: 0 -20px; padding: 30px 20px 40px; }
.island-bg { position: absolute; left: -60px; right: -60px; top: 0; bottom: 0; background: #8EDC7A; border-radius: 50% 50% 0 0 / 120px 120px 0 0; border-top: var(--bw-lg) solid var(--ink); z-index: 0; }
.island svg.path { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; }
.node { position: absolute; z-index: 2; text-align: center; background: none; border: 0; padding: 0; width: 150px; transform: translateX(-50%); }
.node .nb { width: 64px; height: 64px; border-radius: 50%; margin: 0 auto; background: #fff; border: var(--bw-lg) solid var(--ink); box-shadow: var(--lift-md); display: flex; align-items: center; justify-content: center; font-size: 30px; transition: transform .08s; }
.node:active .nb { transform: translateY(2px); box-shadow: none; }
.node.done .nb { background: var(--yellow); }
.node.locked .nb { background: #D9DEE8; box-shadow: none; }
.node.locked .nb svg { width: 26px; height: 26px; color: var(--ink); }
.node.current .nb { width: 84px; height: 84px; font-size: 40px; background: var(--green); box-shadow: var(--lift-md), 0 0 0 8px rgba(255,255,255,.6); }
/* 13,5 piksel dan boleh dua baris. Dulu 12 piksel dan dipotong dengan "...", jadi nama
   seperti "Menyimpan dan Meminjam" tidak pernah terbaca utuh. */
.node .nl { display: inline-block; margin-top: 8px; font-family: var(--font-head); font-weight: 800; font-size: 13.5px; background: #fff; border: 1.5px solid var(--ink); border-radius: 14px; padding: 1px 9px; line-height: 1.25; max-width: 168px; white-space: normal; text-wrap: balance; }
.node .nl .st { color: var(--yellow-dark); letter-spacing: 1px; }
.node .nl .st .off { color: #D9DEE8; }
.node.current .nl { font-size: 15px; border-width: var(--bw); border-radius: 14px; padding: 4px 12px; box-shadow: var(--lift-sm); white-space: normal; max-width: 150px; }
.node.locked .nl { color: var(--muted); }
.ribbon { position: absolute; z-index: 3; font-family: var(--font-head); font-weight: 800; font-size: 16px; color: var(--ink); background: var(--accent, var(--green)); border: var(--bw-lg) solid var(--ink); border-radius: 14px; padding: 6px 16px; box-shadow: var(--lift-md); transform: rotate(-4deg); white-space: nowrap; display: inline-flex; align-items: center; gap: 8px; }
/* Ikon tahap kini gambar berwarna, jadi tidak lagi diputihkan lewat filter.
   Garis putih tipis dipakai supaya tetap terpisah dari warna pita di belakangnya. */
.ribbon img { width: 26px; height: 26px; object-fit: contain; filter: drop-shadow(0 0 1.5px rgba(255, 255, 255, .9)); }
/* Hiasan peta duduk di atas rumput pulau tetapi di bawah tombol kelompok. */
/* Konfeti hasil sempurna: empat gugusan berbeda, satu menempel di tiap sudut layar.
   Bukan satu gambar yang dipaksa menutupi layar. Kalau memakai object-fit: cover, di
   layar tegak tepi konfetinya terpotong habis sehingga tidak kelihatan sama sekali, dan
   di layar lebar kepingannya jadi besar sekali. Tidak diulang dan tidak dicerminkan
   supaya tidak ada kepingan yang muncul dua kali sebagai bayangan. */
.konfeti { position: fixed; z-index: 0; pointer-events: none; width: 132px; height: auto; }
.konfeti.ka { top: 0; left: 0; }
.konfeti.kn { top: 0; right: 0; }
.konfeti.kb { bottom: 0; left: 0; }
.konfeti.knb { bottom: 0; right: 0; }
@media (min-width: 700px) { .konfeti { width: 220px; } }
.result-wrap > *:not(.konfeti) { position: relative; z-index: 1; }
.hias { position: absolute; z-index: 1; transform: translateX(-50%); pointer-events: none; filter: drop-shadow(0 3px 0 rgba(31, 42, 68, .15)); }
/* Hiasan cerita menempel ke tepi kiri atau kanan peta, jadi titik acuannya tepi gambar,
   bukan tengahnya seperti .hias biasa yang ditaburkan di sekitar satu titik. */
.hias-cerita { transform: none; }
/* Buaya di celah jembatan duduk di atas air, jadi harus di atas gambar sungainya. */
.hias-buaya { z-index: 2; }
/* Kartu cerita: teks agak lebih longgar daripada kartu biasa supaya enak dibacakan. */
.cerita { text-align: center; }
.cerita h3 { margin: 4px 0 8px; }
.cerita p { font-weight: 600; line-height: 1.55; margin: 0 0 10px; }
/* Ilustrasi bab: adegan 3:2 dengan langit dan tanahnya sendiri, jadi diberi garis
   tepi dan sudut membulat supaya menyatu dengan kartu, bukan menempel mentah. */
.cerita-adegan { width: 100%; height: auto; display: block; border-radius: 16px; border: var(--bw) solid var(--ink); margin: 0 0 10px; object-fit: cover; }
/* Di layar yang pendek, gambarnya mengalah lebih dulu supaya teks dan tombolnya tetap
   muat. Di layar sangat pendek (mendatar) gambarnya disembunyikan sama sekali. */
@media (max-height: 700px) { .cerita-adegan { max-height: 30vh; } }
@media (max-height: 480px) { .cerita-adegan { display: none; } }
.cerita-img { width: 96px; height: auto; display: block; margin: 0 auto 6px; }
/* Tanpa "font: inherit". Aturan itu ditambahkan saat pita dijadikan tombol pembuka
   cerita, dan diam-diam menimpa huruf judulnya: pita tampil dengan Nunito biasa (400,
   17 piksel), bukan Baloo 2 tebal (800, 16 piksel) seperti tertulis di atas. */
.ribbon { cursor: pointer; }
.ribbon svg { width: 15px; height: 15px; opacity: .75; }
.map-istana .label { display: block; font-family: var(--font-head); font-weight: 800; font-size: 13px; color: var(--ink); background: #fff; border: var(--bw) solid var(--ink); border-radius: 999px; padding: 2px 12px; margin: 4px auto 0; white-space: nowrap; }
/* Istana bisa disentuh untuk membaca tujuan perjalanan, jadi pointer-events dibiarkan
   aktif dan latarnya dikosongkan supaya tetap terlihat seperti gambar biasa. */
.map-istana { position: absolute; left: 50%; transform: translateX(-50%); z-index: 2; width: 200px; background: none; border: 0; padding: 0; cursor: pointer; display: flex; flex-direction: column; align-items: center; }
.map-istana img { width: 100%; height: auto; display: block; filter: drop-shadow(0 6px 0 rgba(31, 42, 68, .18)); }
.node.locked .nb img { width: 36px; height: 36px; }
.map-kancil { position: absolute; z-index: 3; width: 104px; height: 104px; object-fit: contain; filter: drop-shadow(0 6px 0 rgba(31,42,68,.2)); pointer-events: none; }
.map-head { display: flex; align-items: center; gap: 12px; }

/* ---- Pelajari ---- */
.lesson-card { text-align: center; }
.lesson-card .eq { font-family: var(--font-head); font-weight: 800; font-size: 40px; line-height: 1; margin: 4px 0 14px; }
.lesson-card .eq .q { color: var(--orange-dark); }
.visual-box { background: var(--accent-soft, var(--green-soft)); border: var(--bw) solid var(--ink); border-radius: 18px; padding: 10px; margin: 0 auto var(--sp-3); min-height: 90px; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.visual-box svg { max-width: 100%; height: auto; display: block; }
.visual-text { font-family: var(--font-head); font-size: 17px; text-align: center; margin-top: var(--sp-2); font-weight: 700; }
.steps { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; text-align: left; }
.steps li { list-style: none; display: flex; align-items: center; gap: 10px; font-family: var(--font-head); font-weight: 700; font-size: 17px; line-height: 1.3; }
.steps li::before { counter-increment: step; content: counter(step); width: 32px; height: 32px; border-radius: 50%; background: var(--yellow); border: var(--bw) solid var(--ink); display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: 16px; flex-shrink: 0; }
ol.steps { counter-reset: step; padding: 0; margin: 0; }
.lesson-step { font-size: 17px; }
.lesson-step ol { padding-left: 24px; margin: 6px 0; }
.lesson-step li { margin-bottom: 6px; }
.lesson-step li::marker { font-weight: 800; color: var(--sky-dark); }
.chip-list { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { background: var(--soft); border: var(--bw) solid var(--ink); border-radius: 999px; padding: 3px 12px; font-family: var(--font-head); font-weight: 800; font-size: 15px; }
.chip.bad { background: var(--red-soft); }
.chip.good { background: var(--green-soft); }
.dbl-img { display: block; max-width: 100%; max-height: 180px; margin: 0 auto 8px; }
.hand-img { display: block; height: 110px; margin: 0 auto 8px; }

/* ---- Latihan ---- */
.prac-top { display: flex; align-items: center; gap: 12px; min-height: 52px; margin-bottom: 16px; }
.progress { flex: 1; height: 22px; border-radius: 999px; background: #fff; border: var(--bw) solid var(--ink); overflow: hidden; }
.progress > i { display: block; height: 100%; background: var(--yellow); border-right: var(--bw) solid var(--ink); transition: width .3s; }
.qcount { font-family: var(--font-head); font-weight: 800; font-size: 16px; color: #fff; background: var(--ink); border-radius: 999px; padding: 2px 12px; white-space: nowrap; }
/* margin-top: auto berpasangan dengan margin-bottom: auto di .help-row. Sisa ruang
   dibagi rata di atas kartu dan di bawah baris Bantu, sehingga kartu soal berada di
   tengah ruang antara bilah kemajuan dan papan angka. Tanpa ini kartu menempel di atas
   dan menyisakan ruang kosong besar di tengah pada soal yang tidak bergambar. */
.q-card { background: #fff; border: var(--bw-lg) solid var(--ink); border-radius: 32px; padding: 20px 14px 16px; box-shadow: var(--bayang-panel); text-align: center; margin-top: auto; }
/* Tinggi kotak gambar di layar latihan dikunci. Tanpa ini soal dan papan angka bergeser
   naik turun tiap kali gambarnya berganti ukuran atau hilang sendiri — di Lihat Sekilas
   gambarnya memang sengaja hilang setelah 2 detik.
   Ruangnya TIDAK disediakan saat soalnya tidak bergambar: kotak kosong setinggi ini
   membuat soal terdorong jauh ke bawah dan kartunya terlihat menganga. */
.q-card .visual-box { background: var(--purple-soft); height: clamp(112px, 20vh, 168px); min-height: 0; padding: 8px; overflow: hidden; }
/* !important dipakai karena tiap SVG membawa max-height sendiri lewat atribut style,
   dan tanpa ini gambar yang tinggi akan terpotong oleh kotak yang tingginya sudah dikunci. */
.q-card .visual-box svg { max-height: 100% !important; max-width: 100%; width: auto; height: auto; }
.q-card .visual-box img { max-height: 100% !important; max-width: 100%; width: auto; height: auto; object-fit: contain; }
/* Kalau isinya lebih dari satu (gambar tangan lalu bingkai sepuluh di tombol Bantu),
   keduanya berbagi tinggi kotak, bukan masing-masing meminta tinggi penuh lalu
   terpotong. min-height: 0 diperlukan supaya isi kotak lentur boleh mengecil. */
.q-card .visual-box { gap: 6px; }
.q-card .visual-box > * { min-height: 0; flex: 0 1 auto; }
/* Foto tangan dibatasi supaya bingkai sepuluh di bawahnya, yang justru alat hitungnya,
   kebagian ruang lebih banyak. */
.q-card .visual-box > img { max-height: 46% !important; }
.question { font-family: var(--font-head); font-weight: 800; font-size: clamp(42px, 12vw, 64px); text-align: center; margin: 6px 0 0; line-height: 1.2; display: flex; justify-content: center; align-items: center; gap: 12px; flex-wrap: wrap; }
.question .blank { display: inline-flex; align-items: center; justify-content: center; min-width: 1.4em; height: 1.2em; padding: 0 .15em; border-radius: 22px; background: var(--yellow-soft); border: var(--bw-lg) solid var(--ink); color: var(--yellow-dark); box-shadow: inset 0 -6px 0 rgba(0,0,0,.08); }
.question .blank.empty::before { content: '?'; }
/* Tinggi baris ini dipatok, bukan sekadar minimum. Dengan min-height, barisnya sedikit
   memanjang begitu ada tulisan dan papan angka ikut bergeser tiap kali soal dijawab. */
/* Tinggi baris ini dipatok, bukan sekadar minimum. Dengan min-height, barisnya sedikit
   memanjang begitu ada tulisan dan papan angka ikut bergeser tiap kali soal dijawab.
   Ruangnya dibuat cukup untuk dua baris, karena keterangan tombol Bantu juga tampil
   di sini supaya kotak gambarnya tidak perlu memanjang. */
.feedback { font-family: var(--font-head); text-align: center; font-weight: 800; font-size: 24px; height: 52px; margin: 4px 0 0; color: #fff; text-shadow: 0 2px 0 var(--ink); display: flex; align-items: center; justify-content: center; padding: 0 8px; }
.feedback.hint { font-size: 16px; font-weight: 700; line-height: 1.25; }
.feedback.ok { color: var(--yellow); }
/* Benar tetapi memakai Bantu: tetap ramah, tetapi jelas berbeda dari benar sendiri. */
.feedback.ok.helped { color: #fff; font-size: 20px; }
.feedback.bad { color: #fff; }
.help-row { display: flex; align-items: center; gap: 10px; margin: 10px 0 auto; }
.help-row .mini-kancil { width: 64px; height: 64px; object-fit: contain; flex-shrink: 0; filter: drop-shadow(0 4px 0 rgba(31,42,68,.2)); }
.timer { font-family: var(--font-head); font-weight: 800; font-size: 20px; text-align: center; color: var(--ink); background: var(--yellow); border: var(--bw) solid var(--ink); border-radius: 999px; min-width: 64px; padding: 2px 12px; box-shadow: var(--bayang-kecil); }
.keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 12px; }
.keypad button { height: 62px; border-radius: 20px; background: #fff; border: var(--bw) solid var(--ink); box-shadow: var(--lift-md); font-family: var(--font-head); font-size: 32px; font-weight: 800; color: var(--ink); display: flex; align-items: center; justify-content: center; transition: transform .05s, box-shadow .05s; }
.keypad button:active { transform: translateY(2px); box-shadow: none; }
.keypad button.ok { background: var(--green); color: var(--ink); }
.keypad button.del { background: var(--pink); color: var(--ink); }
.keypad button svg { width: 30px; height: 30px; }
.keypad button.ok svg { stroke-width: 3; }

/* ---- Hasil ---- */
.result-wrap { text-align: center; }
.stars-big { display: flex; justify-content: center; align-items: flex-end; gap: 6px; margin: 16px 0 0; }
.stars-big svg { width: 64px; height: 64px; filter: drop-shadow(0 4px 0 var(--ink)) drop-shadow(0 0 10px rgba(255,255,255,.9)); }
.stars-big svg.mid { width: 88px; height: 88px; margin-bottom: 12px; }
.stars-big svg.l { transform: rotate(-14deg); } .stars-big svg.r { transform: rotate(14deg); }
.stars-big svg.off { filter: drop-shadow(0 3px 0 rgba(31,42,68,.35)); opacity: .8; }
.result-wrap h1 { font-size: 42px; text-shadow: 0 2px 0 #fff; margin: 10px 0 0; }
.result-kancil { width: 190px; height: 190px; object-fit: contain; display: block; margin: 4px auto 0; filter: drop-shadow(0 8px 0 rgba(31,42,68,.25)); }
.stat3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
.stat3 > div { padding: 2px 0; }
.stat3 > div + div { border-left: 3px dashed var(--line); }
.stat3 .n { font-family: var(--font-head); font-weight: 800; font-size: 36px; line-height: 1; }
.stat3 .n.g { color: var(--green-dark); } .stat3 .n.b { color: var(--sky-dark); } .stat3 .n.o { color: var(--orange-dark); }
.stat3 .l { font-family: var(--font-head); font-weight: 700; font-size: 14px; color: var(--muted); }
.next-box { margin-top: 14px; text-align: left; background: var(--orange-soft); border: var(--bw) solid var(--ink); border-radius: 18px; padding: 10px 14px; display: flex; align-items: center; gap: 10px; }
.next-box .em { font-size: 26px; }
.next-box .t { font-family: var(--font-head); font-weight: 800; font-size: 15px; }
.next-box .bar { height: 12px; background: #fff; border: var(--bw) solid var(--ink); border-radius: 999px; overflow: hidden; margin-top: 4px; }
.next-box .bar i { display: block; height: 100%; background: var(--orange); }
.next-box .n { font-family: var(--font-head); font-weight: 800; font-size: 18px; }
.redo { display: flex; gap: 6px; margin-top: 12px; align-items: center; justify-content: center; flex-wrap: wrap; }
.redo .lbl { font-family: var(--font-head); font-weight: 700; font-size: 14px; color: var(--muted); }
.bar { height: 12px; background: var(--soft); border: var(--bw) solid var(--ink); border-radius: 999px; overflow: hidden; margin-top: 8px; }
.bar > i { display: block; height: 100%; background: var(--green); transition: width .4s; }
.bar > i.orange { background: var(--orange); }

/* Lari 20 */
.time-box { display: inline-block; margin-top: 14px; background: #fff; border: var(--bw-lg) solid var(--ink); border-radius: 24px; padding: 4px 26px; font-family: var(--font-head); font-weight: 800; font-size: 56px; line-height: 1.1; box-shadow: var(--bayang-kecil); }
.race-kancil { width: 260px; height: 200px; object-fit: contain; display: block; margin: 0 auto -14px; position: relative; z-index: 2; filter: drop-shadow(0 8px 0 rgba(31,42,68,.3)); }
.ladder { display: flex; justify-content: space-between; align-items: flex-end; margin-top: 10px; padding: 0 4px; gap: 4px; }
.ladder > div { text-align: center; flex: 1; opacity: .45; }
.ladder > div.on { opacity: 1; }
.ladder img { height: 34px; width: auto; max-width: 100%; filter: grayscale(1); }
.ladder > div.on img { height: 46px; filter: none; }
.ladder .step { height: var(--h); background: #D9DEE8; border: var(--bw) solid var(--ink); border-radius: 6px 6px 0 0; display: flex; align-items: center; justify-content: center; font-family: var(--font-head); font-weight: 800; font-size: 12px; }
.ladder > div.on .step { background: var(--yellow); border-radius: 8px 8px 0 0; }
.rank-img { height: 120px; width: auto; max-width: 100%; }
.rank-img.small { height: 34px; }
.rank-img.tiny { height: 22px; vertical-align: middle; }
.rank-emoji { font-size: 60px; line-height: 1; }
.rank-emoji.small { font-size: 28px; } .rank-emoji.tiny { font-size: 18px; }
.rank-big { display: flex; justify-content: center; margin: 6px 0; }
.big-num { font-family: var(--font-head); font-size: 44px; font-weight: 800; text-align: center; line-height: 1.1; }

/* ---- Kebun ---- */
.garden-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; font-family: var(--font-head); font-weight: 800; font-size: 22px; }
.garden-dow { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; font-family: var(--font-head); font-weight: 800; font-size: 13px; color: var(--muted); text-align: center; margin-bottom: 6px; }
.garden-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; padding: 8px; background: #8C5A3C; border: var(--bw) solid var(--ink); border-radius: 18px; }
.gd { aspect-ratio: 1; min-width: 0; border-radius: 10px; background: #A56F4B; position: relative; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.gd.empty { background: transparent; }
.gd.future { background: #7A4E33; opacity: .55; }
.gd:not(.grown):not(.empty) { background: #7A4E33; }
.gd.grown { background: #A56F4B; }
.gd.today { outline: 4px solid var(--yellow); outline-offset: -2px; }
.gd-n { position: absolute; top: 2px; left: 4px; font-size: 11px; font-weight: 800; color: rgba(255,255,255,.85); text-shadow: 0 1px 0 rgba(31,42,68,.45); }
.gd-p { width: 82%; height: 82%; display: flex; align-items: center; justify-content: center; }
.gd-p img { width: 100%; height: 100%; object-fit: contain; }
.garden-legend { display: flex; justify-content: center; gap: 14px; margin-top: 10px; font-family: var(--font-head); font-weight: 800; font-size: 13px; color: var(--muted); align-items: center; flex-wrap: wrap; }
.garden-legend span { display: inline-flex; align-items: center; gap: 4px; }
.garden-legend img { height: 20px; }
.stat-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 4px; text-align: center; }
.stat-cards > div { background: #fff; border: var(--bw) solid var(--ink); border-radius: 20px; padding: 10px 6px; box-shadow: var(--bayang-kecil); }
.stat-cards .n { font-family: var(--font-head); font-weight: 800; font-size: 30px; line-height: 1; }
.stat-cards .l { font-family: var(--font-head); font-weight: 700; font-size: 13px; color: var(--muted); }
.stat-cards .n.g { color: var(--green-dark); } .stat-cards .n.o { color: var(--orange-dark); } .stat-cards .n.y { color: #A67C00; } /* kuning tua lama 2,27:1 di putih; ini 3,82:1 untuk angka 30 px */
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; text-align: center; }
.stat-grid > div { background: #fff; border: var(--bw) solid var(--ink); border-radius: 18px; padding: 10px 4px; }
.stat-grid .big-num { font-size: 28px; }
.stat-grid .muted { font-family: var(--font-head); font-size: 11px; font-weight: 700; }

/* ---- Album stiker ---- */
.album-head { display: flex; align-items: center; gap: 12px; min-height: 52px; margin-bottom: 26px; }
.album-head .title { font-family: var(--font-head); font-weight: 800; font-size: 26px; color: #fff; text-shadow: 0 2px 0 var(--ink); }
.album { background: var(--paper); border: var(--bw-lg) solid var(--ink); border-radius: 28px; padding: 30px 14px 22px; box-shadow: var(--bayang-panel); background-image: radial-gradient(circle, rgba(31,42,68,.08) 1.5px, transparent 2px); background-size: 22px 22px; position: relative; }
.album .page-lbl { position: absolute; top: -16px; left: 50%; transform: translateX(-50%) rotate(-2deg); background: var(--yellow); border: var(--bw) solid var(--ink); border-radius: 8px; padding: 2px 16px; font-family: var(--font-head); font-weight: 800; font-size: 15px; white-space: nowrap; }
.sticker-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px 12px; }
.sticker { text-align: center; }
.sticker .sc { width: 88px; height: 88px; margin: 0 auto; border-radius: 50%; background: var(--yellow-soft); border: 4px solid #fff; box-shadow: 0 0 0 2px var(--ink), 0 3px 0 2px rgba(31,42,68,.2); display: flex; align-items: center; justify-content: center; font-size: 46px; }
.sticker:nth-child(6n+1) { transform: rotate(-5deg); } .sticker:nth-child(6n+2) { transform: rotate(4deg); } .sticker:nth-child(6n+3) { transform: rotate(-3deg); }
.sticker:nth-child(6n+4) { transform: rotate(3deg); } .sticker:nth-child(6n+5) { transform: rotate(-4deg); } .sticker:nth-child(6n+6) { transform: rotate(2deg); }
.sticker:nth-child(5n+2) .sc { background: var(--sky-soft); } .sticker:nth-child(5n+3) .sc { background: var(--pink-soft); } .sticker:nth-child(5n+4) .sc { background: var(--green-soft); } .sticker:nth-child(5n+5) .sc { background: var(--purple-soft); }
.sticker.locked { transform: none; }
.sticker.locked .sc { background: transparent; border: var(--bw-lg) dashed var(--ink); box-shadow: none; opacity: .3; font-size: 42px; }
/* Gambar stiker mengisi lingkarannya, tetapi tidak sampai menyentuh tepi putih. */
.sticker-img { width: 78%; height: 78%; object-fit: contain; }
/* Layar cerita: titik penanda panel dan barisan tombolnya. */
/* Sebagian anak dan orang dewasa merasa pusing atau terganggu oleh gerak di layar, dan
   sistem operasinya sudah menyediakan pengaturan untuk itu. Kalau dinyalakan, seluruh
   animasi dan peralihan dihentikan — bukan dipercepat — tetapi tampilannya tetap sama. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
.bab-titik { display: flex; justify-content: center; gap: 7px; margin: 14px 0 4px; }
.bab-titik i { width: 9px; height: 9px; border-radius: 50%; background: var(--line, #D7DEE9); border: 2px solid var(--ink); opacity: .45; }
.bab-titik i.on { background: var(--yellow); opacity: 1; }
.bab-tombol { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.bab-tombol .btn.green { margin-left: auto; }
/* Di layar sempit tombolnya berbagi satu baris penuh, bukan saling mendorong keluar. */
@media (max-width: 360px) {
  .bab-tombol { gap: 6px; }
  .bab-tombol .btn { flex: 1 1 auto; min-width: 0; padding-left: 10px; padding-right: 10px; }
  .bab-tombol .btn.green { margin-left: 0; }
}
/* Pita peringatan penyimpanan. Sengaja menetap di layar, bukan toast yang lewat:
   progres yang tidak tersimpan adalah hal yang harus diketahui orang tua, bukan
   pemberitahuan sekilas yang mudah terlewat. */
.save-bar { position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 60; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 16px; background: var(--orange, #FB923C); color: #fff; border: var(--bw) solid var(--ink); box-shadow: 0 4px 0 rgba(31,42,68,.25); font-family: var(--font-head); font-weight: 800; font-size: 14px; }
.save-bar span { flex: 1; }
.save-bar .btn { flex-shrink: 0; }
@media (min-width: 560px) { .save-bar { left: auto; right: 16px; max-width: 420px; } }
/* Gambar stiker yang dipakai sebagai ikon kelompok: di dalam kotak atau lingkaran yang
   sudah ada ukurannya (tombol peta, misi hari ini, baris tantangan), jadi cukup mengisi
   kotaknya. Kalau gambarnya belum ada, isi kotak itu kembali jadi emoji seperti dulu. */
.ico-img { width: 80%; height: 80%; object-fit: contain; }
/* Ikon yang berdiri sebaris dengan tulisan: tingginya mengikuti besar huruf di
   sekitarnya supaya tidak mendorong barisnya. */
.ico-baris { height: 1.25em; width: auto; vertical-align: -0.22em; }
.reward-stickers { display: flex; justify-content: center; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0 8px; }
.reward-stickers .sticker-img { width: 76px; height: 76px; }
.reward-stickers:not(:has(.sticker-img)) { font-size: 56px; }
.sticker small { display: block; font-family: var(--font-head); font-weight: 800; font-size: 14px; margin-top: 10px; line-height: 1.2; }
.sticker.locked small { color: var(--muted); }
.album .sec { margin: 28px 0 14px; font-family: var(--font-head); font-weight: 800; font-size: 14px; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); text-align: center; }
.dots { display: flex; justify-content: center; align-items: center; gap: 16px; margin-top: 20px; }
/* Titiknya tetap 14 piksel, tetapi bidang sentuhnya 38 piksel lewat elemen semu yang
   melebar ke segala arah — 14 piksel terlalu kecil untuk jari anak. (Garis transparan
   lewat outline tidak bisa: outline tidak ikut dihitung sebagai bidang sentuh.) */
.dots button { width: 14px; height: 14px; border-radius: 50%; background: #fff; border: var(--bw) solid var(--ink); padding: 0; position: relative; }
.dots button::before { content: ''; position: absolute; inset: -12px; }
.dots button.on { background: var(--ink); }

/* ---- Dasbor orang tua ---- */
.tabs { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 6px; margin-bottom: var(--sp-4); padding: 5px; background: #fff; border: var(--bw) solid var(--ink); border-radius: 999px; }
.tabs button { min-height: 40px; border: 0; border-radius: 999px; background: transparent; font-family: var(--font-head); font-weight: 800; font-size: 15px; white-space: nowrap; padding: 0 6px; overflow: hidden; text-overflow: ellipsis; color: var(--muted); display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
.tabs button.sel { background: var(--ink); color: var(--yellow); }
.tabs button svg { width: 16px; height: 16px; flex-shrink: 0; }
.tabs.isi { grid-auto-columns: auto; }            /* menu Orang tua: lebar ikut tulisan, supaya "Di Rumah" tidak terpotong */
.heat { display: grid; gap: 3px; }
.heat .h { aspect-ratio: 1; border-radius: 6px; font-size: 10px; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 800; }
.heat .h.lbl { color: var(--muted); background: transparent; font-size: 11px; }
.h0 { background: #E9EEF5; color: #A2ADC2 !important; }
/* Perkiraan: dilewati lewat tes awal, soalnya belum pernah muncul di layar.
   Warnanya sengaja beda dari "bisa" supaya tidak terbaca sebagai sudah dikuasai. */
.hp { background: #DED2FB; color: #4B3A86 !important; }
.h1 { background: #FFB1B9; }
.h2 { background: #FFC58A; }
.h3 { background: #FFE066; color: #7A5A00 !important; }
.h4 { background: #9EE7B6; color: #1F5A32 !important; }
.h5 { background: var(--green); }
.legend { display: flex; flex-wrap: wrap; gap: 12px; font-family: var(--font-head); font-size: 12px; margin-top: 12px; color: var(--muted); font-weight: 700; }
.legend span { display: inline-flex; align-items: center; gap: 5px; }
.legend i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; border: 1.5px solid var(--ink); }
.chart { display: flex; align-items: flex-end; gap: 5px; height: 110px; padding-bottom: 4px; border-bottom: var(--bw) solid var(--ink); }
.chart .c { flex: 1; background: var(--sky); border: var(--bw) solid var(--ink); border-bottom: 0; border-radius: 6px 6px 0 0; min-height: 3px; position: relative; }
.chart .c.none { background: var(--line); border: 0; }
.chart .c.last { background: var(--yellow); }
.chart .c span { position: absolute; bottom: 100%; left: 0; right: 0; text-align: center; font-size: 10px; color: var(--muted); font-weight: 700; }
.chart-lbl { display: flex; justify-content: space-between; font-family: var(--font-head); font-weight: 700; font-size: 11px; color: var(--muted); margin-top: 4px; }
.stage-bars { display: flex; flex-direction: column; gap: 10px; }
.stage-bars .hd { display: flex; justify-content: space-between; font-family: var(--font-head); font-weight: 700; font-size: 14px; }
.stage-bars .sb { display: flex; height: 14px; border: var(--bw) solid var(--ink); border-radius: 999px; overflow: hidden; margin-top: 4px; background: var(--soft); }
.stage-bars .sb i { display: block; height: 100%; }
table.tbl { width: 100%; border-collapse: collapse; font-size: 15px; }
table.tbl td, table.tbl th { padding: 8px 4px; border-bottom: 1px solid var(--line); text-align: left; }
table.tbl th { font-size: 13px; color: var(--muted); }
.pin-dots { font-size: 36px; letter-spacing: 12px; text-align: center; margin: 10px 0; min-height: 50px; color: var(--ink); }
textarea.code { width: 100%; min-height: 110px; border-radius: 14px; border: var(--bw) solid var(--ink); padding: 10px; font-size: 13px; font-family: ui-monospace, Consolas, monospace; }
select.sel-input { width: 100%; padding: 10px 12px; border-radius: 14px; border: var(--bw) solid var(--ink); font-size: 17px; background: #fff; color: var(--ink); font-weight: 700; }
label.opt { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--line); font-weight: 700; }
.switch { width: 54px; height: 32px; border-radius: 16px; background: #CBD5E1; position: relative; border: var(--bw) solid var(--ink); flex-shrink: 0; transition: background .15s; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 24px; height: 24px; border-radius: 50%; background: #fff; border: var(--bw) solid var(--ink); box-sizing: border-box; transition: left .15s; }
.switch.on { background: var(--green); }
.switch.on::after { left: 24px; }
.notice { margin-top: 10px; padding: 12px; border-radius: 14px; background: var(--yellow-soft); border: var(--bw) solid var(--ink); font-size: 14px; }
.choice-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); margin-top: var(--sp-3); }
.choice-grid .btn { padding: 8px 6px; min-height: 52px; font-size: 20px; }
.choice-grid .btn.teal { grid-column: 1 / -1; font-size: 18px; }
.group { display: flex; align-items: center; gap: var(--sp-3); background: #fff; border: var(--bw) solid var(--ink); border-radius: 20px; padding: 12px 14px; margin-bottom: var(--sp-2); box-shadow: var(--lift-md); width: 100%; text-align: left; transition: transform .08s; }
.group:active { transform: translateY(2px); box-shadow: none; }
.group .g-emoji { width: 48px; height: 48px; border-radius: 50%; flex-shrink: 0; font-size: 26px; display: inline-flex; align-items: center; justify-content: center; background: var(--accent-soft, var(--yellow-soft)); border: var(--bw) solid var(--ink); }
.group .g-body { flex: 1; min-width: 0; display: block; }
.group .g-title { display: block; font-family: var(--font-head); font-weight: 800; font-size: 18px; line-height: 1.2; }
.group .g-sub { display: block; font-size: 14px; color: var(--muted); margin-top: 2px; line-height: 1.3; }
.group .g-state { font-size: 22px; flex-shrink: 0; }
.mini-stars, .gstars { color: var(--yellow-dark); letter-spacing: 1px; }
.gstars .off { color: #D9DEE8; }
.stage-ico { width: 20px; height: 20px; object-fit: contain; vertical-align: -4px; }
.legend-line { font-size: 13px; color: var(--muted); text-align: center; }
.garden-legend img, .stat-cards img { height: 20px; }

/* ---- Toast, update bar, overlay ---- */
.toast { position: fixed; left: 50%; bottom: calc(24px + var(--safe-bottom)); transform: translateX(-50%); background: var(--ink); color: #fff; padding: 12px 20px; border-radius: 16px; font-weight: 800; z-index: 50; max-width: 90vw; text-align: center; box-shadow: 0 10px 24px rgba(0,0,0,.2); }
.update-bar { position: fixed; top: var(--safe-top); left: 0; right: 0; z-index: 60; background: var(--yellow); border-bottom: var(--bw) solid var(--ink); padding: 8px 14px; display: flex; align-items: center; justify-content: center; gap: 12px; font-weight: 800; }
/* display:flex pada aturan di atas mengalahkan [hidden] bawaan browser, jadi tiap
   pita yang disembunyikan lewat atribut hidden harus disebut di sini. */
.update-bar[hidden], .toast[hidden], .save-bar[hidden] { display: none; }
.overlay { position: fixed; inset: 0; background: rgba(31,42,68,.55); z-index: 40; display: flex; align-items: center; justify-content: center; padding: var(--sp-4); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
.overlay .card { width: 100%; max-width: 440px; max-height: min(90vh, 90dvh); overflow: auto; margin: 0; }
/* Layar cerita di layar pendek (iPhone SE, ponsel lama, atau layar dibalik mendatar).
   Isinya digulung di dalam kartu, sedangkan barisan tombol menempel di bawah dan selalu
   terlihat. Tanpa ini tombol Lanjut terdorong keluar layar, dan anak kembali kehilangan
   jalan untuk meneruskan — persis masalah yang mau diperbaiki. */
.overlay .card:has(.cerita) { display: flex; flex-direction: column; overflow: hidden; }
.overlay .cerita { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.overlay .cerita > :not(.bab-tombol):not(.bab-titik) { flex-shrink: 0; }
.overlay .cerita #bab-teks { overflow: auto; min-height: 0; flex: 1 1 auto; }
.overlay .cerita .bab-titik, .overlay .cerita .bab-tombol { flex-shrink: 0; }
.overlay .visual-box { background: var(--yellow-soft); }

/* ---- Animasi ---- */
@keyframes pop { 0% { transform: scale(.6); opacity: 0; } 70% { transform: scale(1.08); } 100% { transform: scale(1); opacity: 1; } }
.pop { animation: pop .35s ease-out; }
@keyframes shake { 0%,100% { transform: translateX(0);} 25% { transform: translateX(-8px);} 75% { transform: translateX(8px);} }
.shake { animation: shake .3s; }

/* Layar latihan harus MUAT dalam satu layar, tanpa digulung.

   Diukur sebelum aturan ini ada: pada 375x667 (iPhone SE) enam tombol angka berada di
   bawah garis lipat, dan pada 390x844 (iPhone 12-15) tiga tombol. Anak harus menggulung
   layar dulu untuk menekan angka — di tengah soal, dengan penghitung waktu berjalan pada
   mode Lari dan Tantangan. Aturan lama hanya memampatkan tampilan di bawah 660 piksel,
   padahal ponsel yang paling banyak dipakai justru sedikit di atasnya.

   Sekarang layar latihan dikunci setinggi layar, kartu soalnya yang mengalah, dan papan
   angkanya tidak pernah ikut menyusut. dvh dipakai supaya bilah alamat browser ponsel
   yang muncul-hilang tidak menggeser tata letaknya. */
body[data-layar="practice"] #app { height: 100vh; height: 100dvh; min-height: 0; overflow: auto; }
/* SATUAN HARUS SAMA DENGAN WADAHNYA. Wadahnya dikunci dengan dvh, jadi seluruh isinya
   juga dvh — bukan vh. Di Safari iPhone kedua satuan itu berbeda: vh selalu mengacu ke
   layar penuh (bilah alamat tersembunyi), sedangkan dvh mengikuti tinggi yang benar-benar
   terlihat saat itu. Ketika bilah alamatnya tampil, isi yang diukur dengan vh menuntut
   ruang lebih besar daripada wadah yang diukur dengan dvh, kartu soalnya terjepit, dan
   isinya tumpang tindih: umpan balik menimpa gambar dan soal sekaligus.

   Terukur pada 375x667 dengan wadah 87% (persis keadaan Safari saat bilah alamat tampil):
   kartu soal setinggi 146 piksel diisi 242 piksel, tulisan umpan balik jatuh di 230-266
   sementara soalnya di 254-317 — keduanya bertumpuk 12 piksel.

   Pasangan vh lalu dvh ditulis berurutan dengan sengaja: iOS di bawah 15.4 tidak mengenal
   dvh, membuang baris keduanya, lalu memakai vh untuk wadah DAN isinya — tetap sama. */
/* INI SEBAB TUMPUKANNYA. Kartu soal adalah salah satu kotak flex di dalam #app, dan
   bawaannya boleh menyusut. Begitu ruangnya kurang, kartunya mengecil sendiri sedangkan
   isinya — gambar dan soal, yang tingginya dipatok — tidak ikut mengecil, lalu tumpah
   melewati batas bawah kartu dan mendarat tepat di atas tulisan umpan balik yang berada
   di bawahnya. Terukur pada 375x667 dengan wadah 580 piksel (Safari saat bilah alamat
   tampil): kartu terjepit jadi 162 piksel padahal isinya 200 piksel, soal berada di
   216-266 sementara umpan balik di 246-290 — bertumpuk 20 piksel.

   flex-shrink: 0 membuat kartunya tidak pernah dijepit. Kalau suatu saat ruangnya benar-
   benar kurang, #app yang menggulung (overflow: auto) — anak bisa menggulung sedikit,
   jauh lebih baik daripada tulisan bertumpuk yang tidak terbaca sama sekali. Sengaja
   TIDAK memakai overflow: hidden di sini: memotong soal diam-diam sama buruknya. */
body[data-layar="practice"] .q-card { min-height: 0; flex-shrink: 0; }
/* Kotak gambar soal tidak boleh terlalu kecil, karena di sinilah alat peraga Bantu
   ditampilkan. Diukur pada 375x667 dengan nilai yang terlalu ketat: bingkai sepuluh
   tampil 58x20 piksel — mustahil dihitung. Sedikit dikecilkan dari sebelumnya untuk
   memberi ruang kotak umpan balik yang kini muat tiga baris petunjuk. */
body[data-layar="practice"] .q-card { padding: clamp(12px, 2.4vh, 20px) 12px clamp(10px, 2vh, 16px); padding: clamp(12px, 2.4dvh, 20px) 12px clamp(10px, 2dvh, 16px); }
body[data-layar="practice"] .q-card .visual-box { height: clamp(80px, 15vh, 168px); height: clamp(80px, 15dvh, 168px); }
body[data-layar="practice"] .question { font-size: clamp(28px, 6.4vh, 64px); font-size: clamp(28px, 6.4dvh, 64px); }
/* Tinggi kotak umpan balik dikunci supaya papan angka tidak naik-turun saat petunjuk
   muncul dan hilang. Sebelumnya tingginya 30-52 piksel, padahal 343 dari 589 petunjuk
   Bantu lebih tinggi dari itu di layar 375 piksel — yang terpanjang 70 piksel di kotak
   36 piksel, jadi tulisannya jatuh menimpa papan angka. Ukuran hurufnya sekarang ikut
   LEBAR layar (vw), bukan tingginya: yang menentukan berapa baris adalah lebar, dan
   ponsel yang tinggi tapi sempit justru membuat hurufnya paling besar sekaligus paling
   banyak barisnya. Pada 15 piksel seluruh 486 petunjuk muat dua baris di layar 375
   piksel; pada 16 piksel sebagian menjadi tiga baris dan butuh 59 piksel.

   flex-shrink: 0 sama pentingnya dengan tingginya. Kotak ini juga kotak flex di dalam
   #app: tanpa itu, tinggi yang diminta 48 piksel dijepit menjadi 43 dan petunjuknya
   meluber lagi, persis masalah yang sedang diperbaiki. */
body[data-layar="practice"] .feedback { flex-shrink: 0; height: clamp(40px, 7.2vh, 60px); height: clamp(40px, 7.2dvh, 60px); font-size: clamp(18px, 3vh, 24px); font-size: clamp(18px, 3dvh, 24px); }
body[data-layar="practice"] .feedback.hint { font-size: clamp(12.5px, 4vw, 15px); line-height: 1.25; }
body[data-layar="practice"] .help-row { flex-shrink: 0; margin-top: clamp(6px, 1.4vh, 10px); margin-top: clamp(6px, 1.4dvh, 10px); }
body[data-layar="practice"] .keypad { flex-shrink: 0; margin-top: clamp(6px, 1.4vh, 12px); margin-top: clamp(6px, 1.4dvh, 12px); gap: clamp(7px, 1.4vh, 12px); gap: clamp(7px, 1.4dvh, 12px); }
body[data-layar="practice"] .keypad button { height: clamp(44px, 7.2vh, 62px); height: clamp(44px, 7.2dvh, 62px); font-size: clamp(22px, 3.8vh, 32px); font-size: clamp(22px, 3.8dvh, 32px); }
body[data-layar="practice"] .help-row .mini-kancil { width: clamp(38px, 7vh, 62px); width: clamp(38px, 7dvh, 62px); height: clamp(38px, 7vh, 62px); height: clamp(38px, 7dvh, 62px); }

@media (min-width: 700px) { #app { padding-top: calc(var(--sp-6) + var(--safe-top)); } }
@media (max-height: 660px) {
  .question { font-size: 44px; }
  .keypad button { height: 52px; font-size: 26px; }
  .q-card { padding: 12px 10px 10px; }
  .visual-box { min-height: 60px; padding: 6px; }
  .help-row .mini-kancil { width: 48px; height: 48px; }
}

/* Menu yang belum terbuka: ikonnya dipudarkan dan diberi gembok kecil, supaya anak tahu
   sebelum menyentuhnya. Tetap bisa disentuh untuk membaca syaratnya. */
.menu-row button.kunci .circ.foto img { filter: grayscale(.7) opacity(.6) drop-shadow(0 3px 0 rgba(31, 42, 68, .15)); }
.menu-row .circ { position: relative; }
.menu-row .gembok { position: absolute; right: -4px; bottom: -4px; font-style: normal; font-size: 16px; line-height: 1; background: #fff; border: var(--bw) solid var(--ink); border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }

/* Jawaban yang benar di dialog salah jawab. Dulu seluruh judulnya merah, dan merah pada
   kesalahan anak terasa seperti dimarahi; sekarang judulnya tinta biasa dan yang disorot
   hanya jawabannya, dengan warna yang sama seperti bingkai jawaban di layar soal. */
.jawab-benar { display: inline-block; min-width: 1.4em; padding: 0 .3em; border-radius: 10px; background: var(--yellow-soft); border: var(--bw) solid var(--ink); color: var(--ink); text-align: center; }

/* Kartu laporan mingguan dari Claude (menu Orang tua). */
.laporan p { font-size: 15px; line-height: 1.5; }
.laporan .lap-tgl { font-size: 12px; font-weight: 800; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; margin: 0 0 4px; }
.laporan .lap-sub { font-family: var(--font-head); font-weight: 800; font-size: 15px; margin: 10px 0 2px; }
.laporan .lap-ul { margin: 0; padding-left: 20px; font-size: 15px; line-height: 1.5; }
.laporan .lap-ul li { margin-bottom: 4px; }

/* Saran dan masukan (menu Orang tua → Atur) */
textarea.text-area { width: 100%; margin-top: 8px; min-height: 110px; border-radius: 14px; border: var(--bw) solid var(--ink); padding: 10px 12px; font-size: 15px; line-height: 1.4; background: #fff; color: var(--ink); resize: vertical; }
textarea.text-area:focus { outline: none; box-shadow: 0 0 0 4px var(--yellow-soft); }
input.cek { width: 24px; height: 24px; flex-shrink: 0; accent-color: var(--green-dark); }
