/* ==========================================================================
   FIEZEL — Design System v5
   Calm, minimal, intentional. Generous space, quiet motion.
   ========================================================================== */

:root{
  /* F17 (audit UI/UX 2026-09): SATU-SATUNYA sumber token. Dulu empat blok :root di berkas
     ini + satu di fiezel-2.css saling menimpa (radius 28 vs 34, bayangan, --fz-display). Nilai
     di bawah adalah pemenang cascade lama, jadi tampilan tidak berubah; ubah token DI SINI saja.
     Rujukan: docs/DESIGN-SYSTEM.md. */
  --cream:#FBF7F3;
  --cream-deep:#F6F1EA;
  --ink:#2E2724;
  --yellow:#F7EACB;
  --yellow-deep:#EFDFB8;
  --yellow-soft:#FBF3E2;
  --gold:#C9A24B;
  --sky-top:#F4EDE6;
  --sky-bottom:#FBF7F3;
  --scene-light:rgba(255,224,126,.42);
  --orbit-x:50%;
  --orbit-y:10%;
  --ambient-text:#2E2724;
  --ambient-muted:#6E635C;
  --chrome-bg:rgba(251,247,243,.94);
  --launcher-start:#FBF3E2;
  --launcher-end:#F7EACB;
  --bg:#FBF7F3;
  --panel:#FFFFFF;
  --panel-soft:#F6F1EA;
  --line:#EFE7DE;
  --line-soft:#F5F0E9;
  --line-strong:#E2D6C8;
  --text:#2E2724;
  --muted:#6E635C;
  --muted-soft:#786D64;
  --accent:#9B3A4A;
  --accent-strong:#7E2D3B;
  --accent-soft:#F6E9EB;
  --accent-on-glass:var(--accent-strong);
  --black:#2E2724;
  --green:#2E8B69;
  --green-soft:#E9F7F0;
  --red:#B8432D;
  --red-soft:#FDE3DE;
  --radius-xl:34px;
  --radius-lg:28px;
  --radius-md:22px;
  --radius-sm:18px;
  --radius-pill:999px;
  --shadow-sm:0 6px 16px rgba(46,39,36,.06);
  --shadow-md:0 14px 32px rgba(46,39,36,.07);
  --shadow-lg:0 20px 44px rgba(46,39,36,.10);
  --ease:cubic-bezier(.22,.8,.28,1);
  --ease-spring:cubic-bezier(.34,1.4,.4,1);
  --fz-spring:var(--ease-spring);
  --fz-out:var(--ease);
  --dur-s:.18s;
  --dur-m:.32s;
  --dur-l:.5s;
  --fz-topbar-h:65px;
  --glass-thin:rgba(255,253,248,.58);
  --glass-regular:rgba(255,253,248,.72);
  --glass-thick:rgba(255,253,248,.82);
  --glass-solid:rgba(255,253,248,.98);
  --glass-edge:rgba(255,255,255,.90);
  --glass-blur:blur(28px) saturate(180%);
  --glass-blur-heavy:blur(40px) saturate(180%);
  --wordmark-ink-hi:#2E2724;
  --wordmark-ink-lo:#4A382A;
  --wordmark-accent-hi:#B8485C;
  --wordmark-accent-lo:#9B3A4A;
  --sun:#F7EACB;
  --sun-deep:#EFDFB8;
  --sun-press:#E3CE9E;
  --sun-soft:#FBF3E2;
  --sun-grad:linear-gradient(180deg,#F7EACB,#EFDFB8);
  --core:#1B1418;
  --core-soft:#2A2126;
  --core-line:#3A3038;
  --on-core:#FDFAF3;
  --on-core-muted:rgba(253,250,243,.68);
  --good:#1F6B4E;
  --good-bright:#2E8B69;
  --good-soft:#E9F7F0;
  --bad:#AC3E2A;
  --bad-soft:#FDE3DE;
  --info:#7A5512;
  --info-soft:#FBF3E2;
  --focus-ring:#2E2724;
  --text-disabled:#75654C;
  --ink-hover:#3A2B1C;
  --ink-press:#120C07;
  --bad-bright:#B8432D;
  --scrim:rgba(36,26,17,.45);
  --scrim-soft:rgba(36,26,17,.28);
  --surface-rgb:255,253,248;
  --surface-pure-rgb:255,255,255;
  --bg-rgb:255,249,238;
  --surface-solid:#ffffff;
  --surface-tint:#fffbf4;
  --surface-warm:#fdf4e6;
  --surface-cool:#f7f7f1;
  --surface-edge:#f2e2cb;
  --surface-mute:#f0e8dc;
  --surface-edge-strong:#e8d3b2;
  --ink-soft:#4E4130;
  --ink-danger:#A63A24;
  --glass-text:#2E2724;
  --glass-muted:#6E635C;
  --glass-line:rgba(27,20,24,.08);
  --fz-display:'FZ Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --fz-display-round:'FZ Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --fz-heading:'FZ Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --fz-body:'FZ Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --sp-1:4px;
  --sp-2:8px;
  --sp-3:12px;
  --sp-4:16px;
  --sp-5:20px;
  --sp-6:24px;
  --sp-7:32px;
  --sp-8:40px;
  --fs-display:clamp(1.75rem,4vw,2.125rem);
  --fs-h1:1.5rem;
  --fs-h2:1.125rem;
  --fs-body:1rem;
  --fs-small:.875rem;
  --fs-caption:.75rem;
  --lh-tight:1.2;
  --lh-body:1.55;
  --radius-xs:14px;
  --lift-sun:0 8px 18px rgba(155,58,74,.18);
  --lift-sun-press:0 1px 0 var(--sun-deep);
  --lift-edge:0 3px 0 var(--surface-edge);
  --lift-edge-press:0 1px 0 var(--surface-edge);
  --dur-xs:.12s;
  --dur-xl:.6s;
  --focus-ring-on-core:#FDFAF3;
  --pz-yellow:#F7EACB;
  --pz-yellow-line:#EFDFB8;
  --pz-yellow-ink:#7A5512;
  --pz-pink:#F8DDE3;
  --pz-pink-line:#F0CBD4;
  --pz-pink-ink:#963C54;
  --pz-mint:#D5EBE5;
  --pz-mint-line:#BEDFD6;
  --pz-mint-ink:#1D5C52;
  --pz-lilac:#E5DDF3;
  --pz-lilac-line:#D3C7E9;
  --pz-lilac-ink:#523E86;
  --pz-sky:#D8E8F4;
  --pz-sky-line:#C7DCEC;
  --pz-sky-ink:#2A566F;
  --pz-peach:#F8E2D2;
  --pz-peach-line:#EFCEB5;
  --pz-peach-ink:#8C4C1D;
  --maroon:#9B3A4A;
  --maroon-deep:#7E2D3B;
  --maroon-soft:#F6E9EB;
  --lift-ink:0 10px 24px rgba(46,39,36,.16);
  --lift-line:0 4px 12px rgba(46,39,36,.06);
}

*{box-sizing:border-box}
/* m025-42: one scale, always. The viewport tag alone is ignored by iOS Safari, so the
   layout is pinned here as well and the gestures are refused in fiezel-zoom-lock.js.
   touch-action:manipulation is what removes the double-tap-to-zoom delay and action. */
html{scroll-behavior:auto;touch-action:manipulation;-webkit-text-size-adjust:100%;text-size-adjust:100%;overflow-x:clip;overscroll-behavior-x:none;overscroll-behavior-y:auto}
html,body{touch-action:manipulation;overscroll-behavior-x:none;overscroll-behavior-y:auto}
/* m025-43 OWNER: a long press anywhere popped the iOS selection/copy callout on top
   of the lesson. Selection is off app-wide; real text fields keep it, because a
   field you cannot select text in is broken. */
html,body,button,a,.card,section,article,div,p,span,h1,h2,h3,h4,b,strong,em,small,li{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
input,textarea,select,[contenteditable="true"]{-webkit-user-select:text;user-select:text;-webkit-touch-callout:default}
/* PAGAR ANTI-ZOOM-OTOMATIS iOS (m025-186) - satu aturan, bukan tambalan per komponen.
   iOS Safari memperbesar SELURUH halaman saat kontrol teks ber-font-size < 16px difokus,
   dan tidak mengembalikannya. Itu gejala "terasa seperti website" yang paling sering
   terlihat, dan akarnya fokus - bukan pinch. 16px adalah ambang perilaku Safari: 15,9px
   tetap memicu. Deklarasi ini didahulukan sebagai LANTAI; komponen boleh menaikkan, tidak
   boleh menurunkan. Ukuran visual yang ringkas dicapai lewat padding/tinggi, bukan huruf
   kecil. Ditegakkan `tests/app-interaction-policy-test.js` di peramban sungguhan, bukan di teks
   CSS - jadi override dari berkas mana pun tetap tertangkap. */
input,textarea,select{font-size:16px}
::selection{background:var(--accent);color:#fff}

body{
  margin:0;
  min-height:100vh;
  background:var(--sky-bottom);
  color:var(--ambient-text);
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text",Inter,ui-sans-serif,"Segoe UI",sans-serif;
  -webkit-font-smoothing:antialiased;
  overflow-x:clip;
  overflow-y:visible;
  transition:color 1.2s var(--ease),background 1.2s var(--ease);
}

.global-sky{
  position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;
  background:linear-gradient(180deg,var(--sky-top) 0%,var(--sky-bottom) 100%);
  transition:background 1.2s var(--ease);
}
.sky-light{position:absolute;inset:-12%;background:radial-gradient(circle at var(--orbit-x) var(--orbit-y),var(--scene-light) 0%,transparent 42%);transition:background 1.2s var(--ease)}
/* i15 2026-08-29 (audit 12-004): drift matahari/bulan dulu transisi left/top 30s — layout
   ulang di main thread selama 30 detik tiap ganti adegan. Kini elemen jadi lapisan seukuran
   viewport (pointer-events sudah none via .global-sky) dan drift pindah ke transform:
   translate(%) relatif ke box sendiri = viewport, jadi var(--orbit-x/y) (persen dari app.js)
   tetap berarti sama. Ikon + kilau diposisikan absolut di titik origin lapisan; drop-shadow
   pindah ke svg supaya region filter tidak membengkak seukuran layar. Visual identik. */
.global-celestial{
  --celestial-size:clamp(52px,6vw,76px);
  position:fixed;left:0;top:0;width:100%;height:100%;display:block;
  transform:translate(var(--orbit-x),var(--orbit-y));
  transition:transform 30s linear,color .9s var(--ease)
}
.global-celestial::before{content:"";position:absolute;left:0;top:0;width:calc(var(--celestial-size)*4.2);height:calc(var(--celestial-size)*4.2);transform:translate(-50%,-50%);border-radius:50%;background:radial-gradient(circle,var(--scene-light) 0%,transparent 68%);filter:blur(8px)}
.global-celestial svg{position:absolute;left:0;top:0;width:var(--celestial-size);height:var(--celestial-size);transform:translate(-50%,-50%);stroke-width:1.45;transition:filter .9s var(--ease)}
.global-celestial.sun{color:#fff0b3}.global-celestial.sun svg{filter:drop-shadow(0 0 14px rgba(255,222,145,.78))}
.global-celestial.moon{color:#edf2ff}.global-celestial.moon svg{filter:drop-shadow(0 0 15px rgba(202,218,255,.72))}
/* Glass has to invert with the sky, or a white pane at midnight is a lamp in the face.
   Each phase carries its own material weights; every surface below reads them. */
/* m029 "Lembut": fase langit dipertahankan — ia membedakan pagi, sore, dan malam, dan
   night-theme-test menjaganya — tetapi amplitudonya diredam habis. Sebelum ini langitnya
   kuning #FFE9B8 dan itulah yang membuat seluruh aplikasi terbaca "ceria terang".
   Arah Lembut minta latar yang tenang, jadi tiap fase sekarang hanya berbisik: satu
   langkah dari --bg, bukan satu warna sendiri. */
.scene-day,.scene-dawn{--sky-top:#F4EDE6;--sky-bottom:#FBF7F3;--scene-light:rgba(155,58,74,.06)}
.scene-dusk{--sky-top:#F3E7E6;--sky-bottom:#FBF7F3;--scene-light:rgba(155,58,74,.08)}
.scene-night{--sky-top:#EDE8E6;--sky-bottom:#FBF7F3;--scene-light:rgba(46,39,36,.06)}
/* m025-115: penimpaan "kembalikan material gelap untuk fase terang" milik m025-85
   dihapus bersama sebab keberadaannya. Fase langit tidak lagi memasang satu pun token
   material, jadi tidak ada lagi yang perlu dikembalikan. */

button{
  font:inherit;
  color:var(--text);
  border:1px solid var(--line);
  background:var(--surface-solid);
  padding:13px 18px;
  border-radius:var(--radius-sm);
  cursor:pointer;
  transition:transform var(--dur-s) var(--ease-spring),
             box-shadow var(--dur-s) var(--ease),
             border-color var(--dur-s) var(--ease),
             background var(--dur-s) var(--ease),
             opacity var(--dur-s) var(--ease);
  -webkit-tap-highlight-color:transparent;
}
button:hover{transform:translateY(-1px);border-color:var(--surface-edge-strong);box-shadow:var(--shadow-sm)}
button:active{transform:translateY(0) scale(.97);transition-duration:.08s}
/* Disabled bukan lagi "teks yang sama, tapi pudar" (opacity .42 = 2,0:1, gagal AA).
   Yang mati adalah PERMUKAANNYA: panel-soft + tinta --text-disabled 4,6:1. */
button:disabled{background:var(--panel-soft);color:var(--text-disabled);border-color:var(--line);opacity:1;cursor:not-allowed;transform:none;box-shadow:none}
/* m028: satu cincin fokus untuk seluruh aplikasi. Cincin lama rgba(184,69,47,.32)
   menghasilkan 1,4:1 terhadap cream - terlihat kalau dicari, tidak terlihat kalau dipakai.
   --focus-ring #A67A00 = 3,4:1 terhadap cream, di atas ambang 3:1 untuk komponen non-teks. */
button:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
/* m025-63 accessibility pass. Sebelumnya hanya tombol yang punya cincin fokus, sehingga
   pengguna keyboard kehilangan jejak begitu berpindah ke tautan atau kolom isian. */
/* i10 2026-08-28 (O5 §8): [tabindex] dipersempit ke :not([tabindex="-1"]) — setApp
   memindahkan fokus PROGRAMATIK ke judul/stem (tabindex=-1) demi pembaca layar, dan
   sebagian browser tetap menganggapnya :focus-visible sehingga stem soal dicat kotak emas
   seolah bisa diklik. Tab keyboard sungguhan tidak pernah mendarat di elemen tabindex=-1,
   jadi cincin fokus keyboard (tautan, isian, summary, tabindex="0") tetap utuh; tidak ada
   outline:none baru — cincinnya memang tidak pernah berlaku untuk target programatik. */
a:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:not([tabindex="-1"]):focus-visible,summary:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
/* i10 2026-08-28 (O5 §8, lanjutan): tanpa aturan sendiri, target programatik jatuh ke cincin
   fokus BAWAAN browser (kotak hitam di stem soal). Outline transparan — bukan none — adalah
   idiom yang tetap terlihat di forced-colors/high-contrast (transparent dipaksa jadi warna
   sistem), jadi pengguna mode kontras tinggi tidak kehilangan jejak fokus. */
[tabindex="-1"]:focus-visible{outline:2px solid transparent;outline-offset:2px}
/* Ukuran sentuh minimum ditegaskan, bukan hanya kebetulan hasil padding: satu perubahan
   ukuran huruf tidak boleh diam-diam menyusutkan sasaran sentuh di bawah 44px. */
button,.nav,input[type="url"],input[type="text"],input[type="password"],input[type="email"],input[type="number"],select{min-height:44px}
input[type="checkbox"],input[type="radio"]{min-width:24px;min-height:24px}

.app{max-width:800px;margin:auto;padding:20px 18px calc(118px + env(safe-area-inset-bottom));position:relative;z-index:2}

/* ---------- topbar ---------- */
.topbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:22px;padding-top:2px}
/* m025-91: wordmark topbar kini SVG, bukan teks. Lebar menggantikan ukuran huruf, dan
   warnanya datang dari gradien di dalam SVG - bukan dari --ambient-text - sehingga ia tidak
   lagi ikut menggelap/menerang mengikuti jam seperti teks di sekitarnya. */
.brand{display:block;width:104px}
.fiezel-wordmark{display:block;width:100%;height:auto}
.version{font-size:.68rem;color:var(--muted-soft);font-variant-numeric:tabular-nums}

/* ---------- section head ---------- */
.section-head{display:flex;justify-content:space-between;gap:var(--sp-4);margin:var(--sp-1) 0 var(--sp-5)}
.section-head h1{font-size:1.65rem;margin:0 0 4px;letter-spacing:-.03em;font-weight:700;color:var(--ambient-text)}
.section-head p{color:var(--ambient-muted)}.muted{color:var(--muted)}.section-head p,.muted{font-size:.86rem;line-height:1.55}

/* ---------- cards ---------- */
.card{
  background:var(--panel);
  color:var(--text);
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  padding:var(--sp-5);
  margin-bottom:var(--sp-3);
  box-shadow:var(--shadow-sm);
  animation:riseIn var(--dur-m) var(--ease) both;
  transition:box-shadow var(--dur-m) var(--ease),transform var(--dur-m) var(--ease);
}
.fade .card:nth-of-type(1){animation-delay:.02s}
.fade .card:nth-of-type(2){animation-delay:.07s}
.fade .card:nth-of-type(3){animation-delay:.12s}
.fade .card:nth-of-type(4){animation-delay:.17s}
.fade .card:nth-of-type(5){animation-delay:.22s}
.fade .card:nth-of-type(n+6){animation-delay:.26s}

.hero{padding:var(--sp-6);background:linear-gradient(150deg,var(--surface-solid) 0%,var(--sun-soft) 130%);border-color:var(--line)}
.hero h2{font-size:clamp(1.5rem,3vw,1.85rem);line-height:1.12;letter-spacing:-.035em;margin:8px 0 8px;font-weight:700}
.hero p{color:var(--muted);line-height:1.6;font-size:.92rem;margin:0 0 16px}
.eyebrow{font-size:var(--fs-caption);letter-spacing:.1em;color:var(--info);font-weight:700;text-transform:uppercase}

.status-pill{
  display:inline-flex;align-items:center;gap:6px;margin-top:14px;
  font-size:var(--fs-caption);font-weight:700;color:var(--accent-strong);
  background:rgba(var(--surface-pure-rgb),.7);border:1px solid var(--surface-edge);
  padding:6px 12px;border-radius:var(--radius-pill);
}

.actions,.toolbar,.three{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}
.primary{background:var(--sun);color:var(--text);border-color:var(--sun-deep)}
.primary:hover{background:var(--sun-deep);box-shadow:var(--shadow-md)}
.danger{color:var(--bad);border-color:var(--bad-soft)}
.primary.danger{background:var(--bad);color:var(--on-core);border-color:var(--bad)}

/* ---------- stats ---------- */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:var(--sp-3);margin-bottom:var(--sp-3)} /* i12/Peta: 5 butir stat (Gem turun ke sini) — auto-fit supaya tak ada butir yatim */
.stats>div{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-md);
  padding:16px;animation:riseIn var(--dur-m) var(--ease) both;
}
.stats>div:nth-child(1){animation-delay:.02s}
.stats>div:nth-child(2){animation-delay:.06s}
.stats>div:nth-child(3){animation-delay:.10s}
.stats>div:nth-child(4){animation-delay:.14s}
/* v6.1 (O4 §5): .66rem≈10,6px ada di bawah lantai 12px — naik ke --fs-caption. */
.stats small{display:block;color:var(--muted-soft);font-size:var(--fs-caption);text-transform:uppercase;letter-spacing:.09em;font-weight:700}
.stats strong{display:block;font-size:1.4rem;margin-top:6px;letter-spacing:-.02em}

.grid{display:grid;gap:12px}
.grid .card{margin:0}
.row{display:flex;justify-content:space-between;align-items:center;gap:12px}
.row span{color:var(--muted);font-size:var(--fs-caption)}
.row b{font-weight:700}

.library{display:flex;flex-wrap:wrap;gap:9px;color:var(--ink-soft);font-size:.78rem;margin-top:12px}
.library span{background:var(--panel-soft);padding:6px 11px;border-radius:var(--radius-pill)}

.pill,.notice{display:inline-block;border:1px solid var(--surface-edge);border-radius:var(--radius-pill);padding:5px 11px;color:var(--accent-strong);background:var(--accent-soft);font-size:var(--fs-caption);min-height:24px;font-weight:600}

/* m025-85: Peta Belajar tab switcher - keeps the 17 sections that used to be one
   long scroll grouped and reachable without turning this into a separate route. */
/* Segmented control, bukan deretan tombol lepas: kapsulnya SATU bidang --panel-soft
   dan tab-nya kehilangan garisnya sendiri, jadi yang terbaca adalah satu kontrol
   dengan satu bagian terpilih. Tab aktif = bidang tinta (resep components.css §6). */
/* Audit UI/UX 2026-08-30 - SETENGAH PETA BELAJAR TIDAK PERNAH DITEMUKAN.
   Strip ini overflow-x:auto sejak m025-85, tetapi tidak pernah MENGATAKAN bahwa ia bisa
   digeser. Terukur di 320px: lebar isi 482px dalam kotak 294px - hanya 2 dari 4 tab yang
   terlihat ("Ringkasan", "Analisis"), 188px tersembunyi tanpa satu pun petunjuk, jadi
   "Adaptive Engine" dan "Kesiapan & Skills" praktis tidak ada bagi murid di ponsel kecil.
   Obatnya bayangan-gulir CSS murni (background-attachment: local vs scroll): dua lapis
   penutup sewarna kapsul di kedua tepi, dua lapis bayangan di belakangnya. Bayangan hanya
   MUNCUL kalau memang ada yang tersembunyi di sisi itu, dan menghilang sendiri begitu tepi
   tercapai - tanpa JS, tanpa listener scroll, dan tanpa memakan ruang saat keempat tab muat. */
.progress-tabs{display:flex;gap:6px;overflow-x:auto;margin:14px 0 18px;padding:4px;background-color:var(--panel-soft);border-radius:var(--radius-pill);-webkit-overflow-scrolling:touch;
  background-image:linear-gradient(to right,var(--panel-soft),var(--panel-soft)),linear-gradient(to left,var(--panel-soft),var(--panel-soft)),linear-gradient(to right,rgba(36,26,17,.22),rgba(36,26,17,0)),linear-gradient(to left,rgba(36,26,17,.22),rgba(36,26,17,0));
  background-position:left center,right center,left center,right center;
  background-repeat:no-repeat;
  background-size:26px 100%,26px 100%,15px 100%,15px 100%;
  background-attachment:local,local,scroll,scroll;
  scroll-snap-type:x proximity}
.progress-tabs .progress-tab{scroll-snap-align:center}
.progress-tab{flex:0 0 auto;padding:9px 16px;border-radius:var(--radius-pill);border:0;background:transparent;color:var(--muted);font-size:.82rem;font-weight:600;min-height:44px;white-space:nowrap}
.progress-tab.active{background:var(--text);border-color:var(--text);color:var(--on-core)}

.topline{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}
.word{font-size:2.6rem;margin:6px 0;font-weight:700;letter-spacing:-.03em}
.phonetic{color:var(--muted-soft)}
.card hr{border:0;border-top:1px solid var(--line);margin:18px 0}

/* ---------- quiz ---------- */
/* i10 2026-08-28 (O5 §1.5): soal = teks terbesar di layar sesi — clamp naik ke 1.6rem di
   layar lebar supaya hierarki soal > pilihan > pembahasan terbaca tanpa membaca. */
/* v6.1 (O4 §5): soal = teks TERBESAR di pelajaran aktif (24–28px, di atas .lesson-title
   24px dan h1 halaman yang didemosi ke h2). Menggantikan nilai interim i10 2026-08-28. */
.question{font-size:clamp(var(--fs-h1),1.1rem + 1.8vw,1.75rem);line-height:1.4;margin:8px 0 18px;font-weight:700;letter-spacing:-.01em;white-space:pre-line;word-break:break-word}
.question-instruction{display:inline-block;font-size:0.75rem;font-weight:700;color:var(--muted);letter-spacing:0.07em;text-transform:uppercase;margin-bottom:10px;line-height:1.35;padding:3px 8px;border-radius:6px;background:rgba(148,163,184,0.12)}
.question-main{display:block;font-size:clamp(1.15rem, 1.1rem + 1.2vw, 1.45rem);font-weight:700;color:var(--text);line-height:1.45}
.target-word{display:inline-block;background:rgba(245,158,11,0.28);color:#B45309;font-style:italic;text-decoration:underline;text-decoration-color:#FBBF24;text-decoration-thickness:2.5px;text-underline-offset:4px;border-bottom:2px solid #F59E0B;border-radius:4px;padding:1px 6px;font-weight:700}
/* i10 2026-08-28 (O5 §3a): banner kata target soal vocab — KATA-nya memimpin layar dengan
   serif display (sekeluarga dengan .word di flashcard), pelafalan menumpang di baseline. */
.vocab-focus{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin:2px 0 0}
.vocab-focus-word{font-family:"Instrument Serif",serif;font-size:2rem;line-height:1.1;letter-spacing:-.01em}
.options{display:grid;gap:var(--sp-2)}
.option{
  display:flex;align-items:center;gap:12px;
  text-align:left;background:var(--panel);border:1.5px solid var(--line);
  min-height:52px;padding:var(--sp-4);border-radius:var(--radius-md);
  position:relative;transition:transform var(--dur-s) var(--ease-spring),
  background var(--dur-s) var(--ease),border-color var(--dur-s) var(--ease),
  box-shadow var(--dur-s) var(--ease);
  text-transform:none !important;font-variant:normal !important;
}
.option .option-badge{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:26px;height:26px;border-radius:6px;
  font-size:0.78rem;font-weight:800;
  background:var(--panel-soft);color:var(--muted);
  border:1px solid var(--line);flex-shrink:0;text-transform:uppercase;
}
.option:not(:disabled):hover .option-badge{
  background:var(--sun-soft);color:var(--sun-deep);border-color:var(--sun-deep);
}
.option.correct .option-badge{
  background:var(--good-bright);color:#fff;border-color:var(--good-bright);
}
.option.wrong .option-badge{
  background:var(--bad);color:#fff;border-color:var(--bad);
}
.option .option-text{
  flex:1 1 auto;font-size:0.98rem;font-weight:600;color:var(--text);
  text-transform:none !important;font-variant:normal !important;font-variant-numeric:normal !important;
  line-height:1.4;
}
/* i10 2026-08-28 (O5 §2): pilihan jawaban = baris pilihan yang tenang, bukan kartu chunky
   (resep tebal v6 di bawah kini mengecualikan .option); umpan hover cukup bayangan lembut. */
.option{font-size:1rem}
.option:not(:disabled):hover{background:var(--panel-soft);border-color:var(--sun-deep);box-shadow:var(--shadow-sm)}
.option:not(:disabled):active{transform:scale(0.98)}
.option.correct{border-color:var(--good-bright);background:var(--good-soft);animation:pop var(--dur-m) var(--ease-spring)}
.option.wrong{border-color:var(--bad);background:var(--bad-soft);animation:shake var(--dur-m) var(--ease)}
/* Mode review mematikan tombol pilihan. Resep disabled global mengubah permukaan +
   tinta - untuk pilihan jawaban itu SALAH: jawabannya masih harus dibaca. Di sini
   disabled hanya melepas interaksi, warna state benar/salah tetap. */
.option:disabled{background:var(--panel);color:var(--text);border-color:var(--line);opacity:1;cursor:default}
.option.correct:disabled{border-color:var(--good-bright);background:var(--good-soft)}
.option.wrong:disabled{border-color:var(--bad);background:var(--bad-soft)}
.feedback{
  /* v6.1 (O4 §3): border dilepas — ia duduk DI DALAM kartu; tint + stripe status cukup. */
  margin-top:var(--sp-3);padding:var(--sp-4);border-radius:var(--radius-md);
  background:var(--surface-cool);line-height:1.6;font-size:var(--fs-small);
  animation:riseIn var(--dur-m) var(--ease) both;
}
.feedback.hidden{display:none}
.feedback b{font-size:var(--fs-body)}
.feedback p{margin:9px 0}
.distractor-breakdown{margin-top:6px;padding-top:6px;border-top:1px dashed var(--line)}
.distractor-breakdown p{font-size:.83rem;margin:6px 0}

.passage{font-size:.89rem;line-height:1.75;color:var(--ink-soft)}
.center{text-align:center}
.emoji{font-size:2.6rem}
.score{font-size:3.4rem;font-weight:700;color:var(--green);margin:10px 0;letter-spacing:-.03em;animation:pop .5s var(--ease-spring)}
.meter{margin:var(--sp-3) 0}
/* Track = --line-soft (garis, bukan bidang biru dingin #e9eef5 yang tidak ada di
   palet sama sekali). Isi = keluarga sun, gelap ke arah kanan supaya arah majunya
   terbaca tanpa membaca angkanya. */
.bar{height:8px;background:var(--line-soft);border-radius:var(--radius-pill);overflow:hidden;margin-top:7px}
.bar i{display:block;height:100%;background:linear-gradient(90deg,var(--sun),var(--sun-deep));border-radius:var(--radius-pill);transition:width var(--dur-xl) var(--ease)}

/* ---------- toast ---------- */
.toast{
  position:fixed;left:50%;bottom:96px;transform:translate(-50%,16px) scale(.96);opacity:0;pointer-events:none;
  /* m028: toast dulu koral dengan tinta coklat di atasnya - 3,1:1, di bawah ambang teks,
     dan itu satu-satunya cara aplikasi mengabarkan kesalahan. Sekarang permukaan core
     dengan krem di atasnya: 14,7:1, dan sekeluarga dengan panggung splash. */
  background:var(--core);color:var(--on-core);padding:13px 20px;border-radius:var(--radius-pill);font-weight:700;font-size:.86rem;
  transition:opacity var(--dur-m) var(--ease),transform var(--dur-m) var(--ease-spring);
  z-index:80;box-shadow:var(--shadow-lg);max-width:88%;text-align:center
}
.toast.show{opacity:1;transform:translate(-50%,0) scale(1)}

/* ---------- kartu pembaruan (m025-212) ----------
   Duduk di atas tab bar, bukan menutupi layar: murid boleh menunda dan terus belajar.
   Bukan .toast karena kartu ini menunggu keputusan - ia tidak boleh pergi sendiri. */
.update-banner{
  position:fixed;left:0;right:0;bottom:calc(76px + env(safe-area-inset-bottom,0px));
  z-index:10050;display:flex;justify-content:center;padding:0 14px;pointer-events:none;
  opacity:0;transform:translateY(14px);
  transition:opacity var(--dur-m) var(--ease),transform var(--dur-m) var(--ease-spring)
}
.update-banner.show{opacity:1;transform:translateY(0)}
.update-banner.hidden{display:none}
.update-banner-card{
  pointer-events:auto;width:100%;max-width:420px;
  background:var(--core);color:var(--on-core);border-radius:20px;
  box-shadow:var(--shadow-lg);padding:15px 17px;
  display:grid;grid-template-columns:auto 1fr;gap:6px 12px;align-items:start
}
.update-banner-icon{color:var(--sun);display:flex;align-items:center;justify-content:center;padding-top:2px}
.update-banner-text{min-width:0}
.update-banner-title{margin:0;font-weight:800;font-size:.95rem}
.update-banner-body{margin:5px 0 0;font-size:.8rem;line-height:1.45;opacity:.86}
.update-banner-body b{font-weight:800;opacity:1}
.update-banner-version{margin:6px 0 0;font-size:.72rem;opacity:.6;letter-spacing:.02em}
.update-banner-version:empty{display:none}
.update-banner-actions{grid-column:1 / -1;display:flex;gap:9px;margin-top:11px}
.update-banner-apply,.update-banner-later{
  flex:1;min-height:44px;border:0;border-radius:var(--radius-pill);
  font-weight:800;font-size:.85rem;cursor:pointer
}
.update-banner-apply{background:var(--sun);color:var(--text)}
.update-banner-later{background:transparent;color:var(--on-core);border:1.5px solid rgba(255,255,255,.28)}
@media (prefers-reduced-motion:reduce){
  .update-banner{transition:opacity var(--dur-m) linear;transform:none}
  .update-banner.show{transform:none}
}

/* i10 2026-08-28 (O5 §6.1): kilas jawaban dulu panel 330px di tengah layar — tepat menutup
   soal + pilihan yang sedang dibicarakan oleh panel pembahasan. Kini pil status ringkas di
   tepi atas (aman dari soal), pointer-events tetap none, ritme .show/1500ms tak berubah. */
.answer-burst{
  position:fixed;left:50%;top:max(8px,env(safe-area-inset-top,0px));z-index:130;pointer-events:none;
  width:auto;max-width:min(280px,calc(100% - 32px));display:flex;align-items:center;justify-content:center;gap:6px;padding:4px 14px;height:32px;box-sizing:border-box;
  border-radius:var(--radius-pill);
  box-shadow:0 8px 24px rgba(0,0,0,0.3);opacity:0;transform:translate(-50%,-18px) scale(.9);
  transition:opacity var(--dur-m) var(--ease),transform var(--dur-m) var(--ease-spring);backdrop-filter:blur(16px)
}
.answer-burst.hidden{display:none}.answer-burst.show{opacity:1;transform:translate(-50%,0) scale(1)}
.answer-burst-icon{width:18px;height:18px;display:grid;place-items:center;border-radius:var(--radius-xs)}.answer-burst-icon svg{width:14px;height:14px}
.answer-burst strong{font-size:.82rem;letter-spacing:-.01em;white-space:nowrap;line-height:1}.answer-burst small{color:var(--muted);font-size:.76rem;text-align:center}
.answer-burst.success{background:#064E3B;border:1px solid #10B981;color:#ECFDF5}
.answer-burst.success strong{color:#ECFDF5}
.answer-burst.success .answer-burst-icon{color:#10B981;background:rgba(16,185,129,.2)}
.answer-burst.error{background:#7F1D1D;border:1px solid #EF4444;color:#FEF2F2}
.answer-burst.error strong{color:#FEF2F2}
.answer-burst.error .answer-burst-icon{color:#EF4444;background:rgba(239,68,68,.2)}

/* ---------- bottom nav ---------- */
.bottomnav{
  position:fixed;bottom:max(12px,env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);width:min(560px,calc(100% - 24px));
  padding:7px;background:rgba(var(--surface-pure-rgb),.86);
  border:1px solid rgba(239,231,232,.9);border-radius:var(--radius-lg);
  display:grid;grid-template-columns:repeat(6,1fr);gap:4px;z-index:40;
  /* v6.1 (O4 §2): bayangan pill pindah ke satu definisi v6 di bawah — tiga def lama bersaing. */
}
.nav{
  /* m028: lantai 12px. Label navigasi 10,4px adalah teks yang harus dibaca setiap hari;
     di bawah 12px ia berhenti terbaca sebagai kata dan hanya jadi bentuk. */
  border:0;background:transparent;padding:9px 4px;font-size:var(--fs-caption);font-weight:600;color:var(--muted);
  border-radius:var(--radius-md);line-height:1.5;transition:color var(--dur-s) var(--ease),background var(--dur-m) var(--ease),transform var(--dur-s) var(--ease-spring)
}
.nav:hover{transform:none;box-shadow:none;border-color:transparent}
.nav.active{color:var(--black);background:var(--panel-soft);transform:translateY(-2px)}

.fade{animation:pageIn var(--dur-l) var(--ease)}
.is-repaint,
.is-repaint *,
.is-repaint .fade,
.is-repaint .fade > *,
.fade.is-repaint,
.fade.is-repaint > *,
.is-repaint .card,
.fade.is-repaint .card,
#app.is-repaint .fade,
#app.is-repaint .fade > *{animation:none !important}
@keyframes pageIn{from{opacity:0;transform:translateY(14px) scale(.99)}to{opacity:1;transform:none}}
@keyframes riseIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@keyframes pop{0%{transform:scale(.94)}55%{transform:scale(1.015)}100%{transform:scale(1)}}
@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}

.error{margin-top:26px;padding:20px;border:1px solid #f3c3cf;background:var(--red-soft);border-radius:var(--radius-md);color:var(--ink-danger)}

/* ---------- flashcards ---------- */
/* ---------- flashcards ---------- */
.card-flashcard,
.card.card-flashcard,
html body:not(.fz-teacher-mode) .card.card-flashcard,
body.fz-lux .card.card-flashcard{
  background:transparent !important;border:none !important;box-shadow:none !important;padding:0 !important;
  max-width:min(520px,100%) !important;margin:0 auto !important;
  display:flex !important;flex-direction:column !important;justify-content:space-between !important;
  gap:16px !important;min-height:calc(100vh - 145px) !important;box-sizing:border-box !important;
  position:relative !important;
}
.flashcard{
  flex:1 1 auto !important;width:100% !important;height:clamp(380px,56vh,540px) !important;min-height:360px !important;
  cursor:pointer;perspective:1400px;-webkit-perspective:1400px;
  transform-style:preserve-3d;-webkit-transform-style:preserve-3d;
  border:none !important;border-radius:28px !important;background:transparent !important;
  color:inherit;outline:none;
  box-shadow:none !important;position:relative !important;
  z-index:2 !important;
  animation: fzCardSpringIn 0.34s cubic-bezier(0.16, 1, 0.3, 1) both;
  will-change: transform, opacity;
  user-select: none;
  -webkit-user-select: none;
}
.flashcard::before,
.flashcard::after{
  display:none !important;
  content:none !important;
}
@keyframes fzCardSpringIn {
  0% { opacity: 0; transform: scale(0.93) translateY(16px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
.flash-inner{
  position:relative;width:100%;height:100%;
  transition:transform .52s cubic-bezier(0.34, 1.3, 0.64, 1);
  transform-style:preserve-3d;-webkit-transform-style:preserve-3d;
  will-change: transform;
}
.flashcard.flipped .flash-inner{transform:rotateY(180deg);-webkit-transform:rotateY(180deg)}
.flash-face{
  position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  transform-style:preserve-3d;-webkit-transform-style:preserve-3d;
  border-radius:28px !important;padding:26px 22px !important;display:flex;flex-direction:column;
  align-items:center;text-align:center;
  background:#FFFDF8 !important;
  background:linear-gradient(165deg,#FFFFFF 0%,#FFFDF5 55%,#FAF4E8 100%) !important;
  border:2px solid #EDE2CE !important;
  box-shadow:0 16px 36px -10px rgba(135,105,65,.14),0 4px 14px rgba(135,105,65,.06),inset 0 1.5px 0 rgba(255,255,255,.95) !important;
  color:#1E1B18 !important;
  box-sizing:border-box;overflow:visible !important;
  transition:opacity 0.22s ease;
}
@media(min-width:640px){.flash-face{padding:30px 28px !important}}
@media(max-width:380px){.flash-face{padding:20px 16px !important}}
@media(max-height:560px){
  .card-flashcard,
  .card.card-flashcard,
  html body:not(.fz-teacher-mode) .card.card-flashcard,
  body.fz-lux .card.card-flashcard{
    min-height:calc(100vh - 90px) !important;
    gap:8px !important;
  }
  .flashcard{
    height:clamp(260px,50vh,340px) !important;
    min-height:240px !important;
  }
  .flash-face{
    padding:14px 16px !important;
  }
}
.flash-front{
  transform:rotateY(0deg) translateZ(1px);
  -webkit-transform:rotateY(0deg) translateZ(1px);
  justify-content:space-between;
}
.flash-back{
  transform:rotateY(180deg) translateZ(1px);
  -webkit-transform:rotateY(180deg) translateZ(1px);
  justify-content:space-between;
}
.flashcard:not(.flipped) .flash-back{pointer-events:none !important}
.flashcard.flipped .flash-front{pointer-events:none !important}
.flash-front-main{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;width:100%}
.flash-front .word,
html body:not(.fz-teacher-mode) .flash-front h2.word,
.flashcard h2.word,
.flashcard .word{
  font-family:var(--fz-heading, 'Plus Jakarta Sans', sans-serif) !important;
  font-size:clamp(3.2rem,11vw,4.6rem) !important;
  font-weight:800 !important;letter-spacing:-.03em !important;line-height:1.1 !important;margin:8px 0 2px !important;
  color:#1A1715 !important;word-break:break-word;
}
.flash-front .phonetic,
.flashcard .phonetic{
  font-size:clamp(1.25rem,4.4vw,1.6rem) !important;color:#7D6B5A !important;font-weight:600 !important;margin-top:2px;
}
.flash-front-actions{display:flex;justify-content:center;align-items:center;width:100%;margin:12px 0 6px}
.flash-back{transform:rotateY(180deg);justify-content:space-between}
.flash-back-main{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;width:100%}
.flash-kicker,
.flashcard .flash-kicker{
  display:block;font-size:.82rem !important;font-weight:800 !important;letter-spacing:.16em !important;
  text-transform:uppercase;color:#B45309 !important;margin:0 !important;
}
.flash-meaning,
html body:not(.fz-teacher-mode) .flash-back h3.flash-meaning,
.flashcard h3.flash-meaning,
.flashcard .flash-meaning{
  font-family:var(--fz-heading, 'Plus Jakarta Sans', sans-serif) !important;
  font-size:clamp(2.4rem,8vw,3.4rem) !important;
  font-weight:800 !important;letter-spacing:-.025em !important;line-height:1.18 !important;color:#1A1715 !important;
  margin:0 !important;text-align:center !important;word-break:break-word;
}
.flash-example-box,
.flashcard .flash-example-box{
  width:100% !important;max-width:440px !important;background:#FDF9F0 !important;border:1.5px solid #EADECA !important;
  border-radius:20px !important;padding:14px 18px !important;margin:0 !important;text-align:center;box-sizing:border-box;
  box-shadow:inset 0 1px 3px rgba(120,95,60,.04) !important;
}
.flash-example-en,
.flashcard .flash-example-en{
  font-size:1.15rem !important;line-height:1.48 !important;color:#1E293B !important;font-style:italic !important;font-weight:600 !important;margin:0;
}
.flash-example-id,
.flashcard .flash-example-id{
  font-size:1.02rem !important;line-height:1.42 !important;color:#645649 !important;font-weight:500 !important;margin:6px 0 0 !important;
}
.flash-audio-btn{
  background:#FAF4E8 !important;border:1.5px solid #E5D7C0 !important;
  border-radius:999px !important;padding:10px 20px !important;display:inline-flex !important;
  align-items:center !important;gap:8px !important;font-size:.95rem !important;font-weight:700 !important;
  color:#382E25 !important;box-shadow:0 3px 10px rgba(135,105,65,.08) !important;cursor:pointer;
  transition:transform .15s ease,background .15s ease;
}
.flash-audio-btn:hover{background:#F3EBD8 !important;transform:scale(1.02)}
.flash-audio-btn:active{transform:scale(0.98)}
.flash-back-actions{
  display:flex !important;flex-direction:row !important;flex-wrap:nowrap !important;
  justify-content:center !important;align-items:center !important;gap:12px !important;
  width:100% !important;max-width:380px !important;margin:12px 0 6px !important;box-sizing:border-box !important;
}
.flash-back-actions .flash-audio-btn{
  flex:1 1 0 !important;min-width:0 !important;padding:10px 14px !important;font-size:.88rem !important;
  white-space:nowrap !important;justify-content:center !important;margin:0 !important;
}
.flash-flip-hint,
.flash-front .flash-flip-hint,
.flash-back .flash-flip-hint,
.flashcard .flash-flip-hint{
  display:inline-flex;align-items:center;gap:6px;font-size:.88rem !important;font-weight:600;
  color:#8E7B6C !important;margin:8px 0 0;
}
.flash-flip-hint svg,
.flash-front .flash-flip-hint svg,
.flash-back .flash-flip-hint svg{
  width:14px;height:14px;stroke:#8E7B6C !important;
}
.flashcard:focus-visible{outline:2px solid #F59E0B;outline-offset:2px;box-shadow:none}

/* Chips on Front Face */
.chips-row{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}
.flash-front .chip-level,
.flashcard .chip-level{
  background:#FEF3C7 !important;color:#92400E !important;border:1.5px solid #FCD34D !important;
  font-weight:800 !important;font-size:.88rem !important;padding:4px 12px !important;border-radius:999px !important;
}
.flash-front .chip-cat,
.flashcard .chip-cat{
  background:#F5EFEB !important;color:#6B5E54 !important;border:1.5px solid #E5D9CE !important;
  font-size:.88rem !important;padding:4px 12px !important;border-radius:999px !important;
}
.flash-front .chip-cat b,
.flashcard .chip-cat b{
  color:#2D241E !important;font-weight:800 !important;
}
.flash-face .eyebrow,
.flashcard .eyebrow{
  display:inline-flex !important;align-items:center !important;justify-content:center !important;
  background:#FEF3C7 !important;color:#92400E !important;border:1.5px solid #FCD34D !important;
  font-weight:800 !important;font-size:.84rem !important;padding:4px 14px !important;border-radius:999px !important;
  letter-spacing:.04em !important;text-transform:uppercase !important;margin:0 0 8px 0 !important;
}

/* Japanese Display inside Flashcard */
.flash-face .ja-toggle-btn{
  background:#F5EFEB !important;border-color:#E2D5C8 !important;color:#5C4E43 !important;
}
.flash-face .ja-toggle-btn.active{
  background:#FDE68A !important;border-color:#F59E0B !important;color:#92400E !important;
}

/* Primary Mastery Bar — Only 2 clean tactile decision buttons */
.flash-mastery-bar{
  width:100% !important;max-width:520px !important;display:grid !important;grid-template-columns:1fr 1fr !important;
  gap:14px !important;margin:0 auto !important;flex-shrink:0 !important;
}
.flash-btn-learning,.flash-btn-mastered{
  min-height:56px !important;border-radius:20px !important;font-size:1.05rem !important;font-weight:800 !important;
  padding:0 18px !important;display:inline-flex !important;align-items:center !important;justify-content:center !important;
  gap:8px !important;cursor:pointer;transition:transform .15s ease,box-shadow .15s ease !important;
}
.flash-btn-learning{
  background:#FFFFFF !important;border:2px solid #E5D9CE !important;color:#2D241E !important;
  box-shadow:0 4px 14px rgba(120,95,60,.08) !important;
}
.flash-btn-learning:hover{background:#FAF5EA !important;transform:translateY(-1px)}
.flash-btn-learning:active{transform:scale(0.98)}
.flash-btn-mastered{
  background:#FFD026 !important;border:2px solid #E5A800 !important;color:#0F172A !important;
  box-shadow:0 6px 18px rgba(255,208,38,.4) !important;
}
.flash-btn-mastered:hover{box-shadow:0 8px 22px rgba(255,208,38,.5) !important;transform:translateY(-1px)}
.flash-btn-mastered:active{transform:scale(0.98)}

.three{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:14px}

/* ---------- quiz shell ---------- */
.quiz-shell{padding-bottom:20px}
/* O2/i7: header sesi minimal. Grid auto 1fr auto (bukan 1fr auto 1fr) supaya kolom tengah
   melar dan bar progres punya lebar. Saat lesson-mode aktif, header ini satu-satunya krom
   atas: ia yang memikul notch (viewport-fit=cover) lewat env(safe-area-inset-top). */
.quiz-topbar{
  position:sticky;top:0;z-index:30;display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:var(--sp-3);
  padding:max(10px,env(safe-area-inset-top)) 0 var(--sp-3);background:rgba(var(--bg-rgb),.9);backdrop-filter:blur(14px)
}
.quiz-exit{min-width:44px;min-height:44px}
.quiz-progress{display:grid;grid-template-columns:auto auto;justify-content:center;align-items:baseline;gap:2px 4px;text-align:center;font-weight:700;font-variant-numeric:tabular-nums}
.quiz-progress span{font-size:var(--fs-body)}
.quiz-progress em{font-style:normal;color:var(--muted-soft)}
/* bar 4px --sun di bawah teks n/25: lapisan sekilas-pandang, teksnya tetap yang utama.
   Isi = soal TERJAWAB (scaleX var(--p) dipasang inline oleh draw()/teach). */
.quiz-progress-bar{grid-column:1/-1;display:block;height:4px;width:min(220px,100%);margin:4px auto 0;
  background:var(--line-soft);border-radius:var(--radius-pill);overflow:hidden}
.quiz-progress-bar b{display:block;height:100%;background:linear-gradient(90deg,var(--sun),var(--sun-deep));
  border-radius:var(--radius-pill);transform:scaleX(var(--p,0));transform-origin:left;transition:transform var(--dur-xl) var(--ease)} /* i15: isi progres = resep --dur-xl (O4 §9) */
@media(max-width:359px){.quiz-exit-label{display:none}} /* 320px: Keluar jadi ikon saja; aria-label tetap menyandang namanya */
@media(max-height:430px){.quiz-topbar{padding:max(6px,env(safe-area-inset-top)) 0 8px;gap:10px}.quiz-progress-bar{margin-top:2px}} /* lanskap: header kompak */
.quiz-next{justify-self:end;background:var(--sun);color:var(--text);border-color:var(--sun-deep);min-width:92px}
/* m028: keadaan nonaktif dulu memakai opacity global .42 di atas permukaan redup - hasilnya
   teks 2,4:1, tidak terbaca. Sekarang keadaan nonaktif punya warnanya sendiri (4,8:1):
   tetap jelas terbaca sebagai TIDAK BISA DIKLIK, tanpa menghilang. */
.quiz-next:disabled{background:var(--panel-soft);color:var(--text-disabled);border-color:var(--line);opacity:1}
/* m025-361: setelah menjawab, Lanjut tampil DUA kali - di sini dan di bilah melayang
   bawah (.quiz-floating-bar). Yang dipertahankan yang di zona jempol. #quizNext TIDAK
   dicabut dari markup: ia tetap satu-satunya pintu maju terprogram (bilah melayang,
   confidencePopNext, lewati-listening, dan tests/r2-ux-overhaul-smoke-test memanggilnya);
   click() tetap jalan pada elemen display:none. Setiap jalur yang menyalakannya juga
   memanggil showQuizFloatingNext(). */
.quiz-topbar .quiz-next{display:none}

/* m025-114: soal listening di tes penempatan. Tombolnya harus terbaca sebagai satu-satunya
   jalan ke soal - naskahnya sengaja tidak pernah dirender, jadi tanpa tombol ini murid
   hanya melihat pertanyaan tanpa bahan. */
.quiz-listen{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 14px}
/* m025-117: tombolnya ikut bahasa chunky milik redesign pastel - bidang koral, tinta
   coklat, bayangan pekat 4px yang memendek saat ditekan. Ia memakai koral, bukan kuning,
   supaya tidak bersaing dengan aksi utama layar; dan koral memang peran aksi kedua. */
.quiz-listen-btn{display:inline-flex;align-items:center;gap:8px;padding:11px 18px;min-height:44px;
  /* m028: koral dengan tinta coklat = 3,1:1. Tombol ini memutar audio soal - satu-satunya
     jalan menjawab soal listening - jadi ia dipindah ke permukaan tinta: krem di atas
     coklat 13,9:1, dan ia tetap TIDAK kuning sehingga tidak bersaing dengan aksi utama. */
  border:0;border-radius:var(--radius-md);background:var(--text);color:var(--on-core);
  font-weight:700;letter-spacing:-.01em;cursor:pointer;
  box-shadow:0 4px 0 var(--ink-press),0 10px 22px rgba(36,26,17,.13);
  transition:transform var(--dur-xs) var(--ease),box-shadow var(--dur-xs) var(--ease),background var(--dur-s) var(--ease)}
.quiz-listen-btn:hover:not(:disabled){background:var(--ink-hover)}
.quiz-listen-btn:active:not(:disabled){
  transform:translateY(3px);box-shadow:0 1px 0 var(--ink-press),0 4px 10px rgba(36,26,17,.12)}
.quiz-listen-btn:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.quiz-listen-btn:disabled{background:var(--panel-soft);color:var(--text-disabled);opacity:1;
  cursor:progress;transform:translateY(3px);
  box-shadow:0 1px 0 var(--line)}
.quiz-listen .muted{font-size:13px}
/* i10 2026-08-28 (O5 §5.1): panggung dengar di ATAS stem (urutan markup diatur draw()):
   tombol Dengarkan jadi hero satu panggung terpusat — satu-satunya bahan soal listening
   memang tombol ini, resep tinta m028 di atas diwarisi apa adanya. */
.quiz-listen-hero{display:grid;justify-items:center;gap:8px;margin:6px 0 16px;padding:18px 16px;
  border:1px solid var(--line-soft);border-radius:var(--radius-lg);background:var(--panel-soft)}
.quiz-listen-btn-hero{padding:16px 30px;font-size:1.05rem;border-radius:var(--radius-pill)}
.quiz-listen-hero .muted{text-align:center}

/* ---------- level grid ---------- */
.level-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:11px}
.level-card{width:100%;display:flex;align-items:center;gap:12px;text-align:left;padding:16px;background:var(--surface-solid)}
.level-number{width:32px;height:32px;border-radius:var(--radius-sm);display:grid;place-items:center;background:var(--accent-soft);color:var(--accent-strong);font-weight:700}
.level-card p{margin:2px 0 0;color:var(--muted);font-size:.75rem}

/* ---------- welcome / modal overlays ---------- */
.welcome,.modal{
  /* Backdrop dulu kabut TERANG di atas layar terang (rgba(bg,.82)) - panel dialog
     tidak pernah benar-benar terangkat dari latarnya. Scrim gelap turunan --text
     memisahkan keduanya tanpa menambah satu elemen pun. */
  position:fixed;inset:0;background:var(--scrim);backdrop-filter:blur(18px);
  display:grid;place-items:center;z-index:100;opacity:0;pointer-events:none;transition:opacity var(--dur-l) var(--ease);
  padding:20px;
}
.welcome.show,.modal.show{opacity:1;pointer-events:auto}
.welcome.hidden,.modal.hidden{display:none}
.welcome-panel,.modal-panel{
  width:min(460px,100%);padding:32px 26px;border:1px solid var(--line);border-radius:var(--radius-lg);
  background:rgba(var(--surface-pure-rgb),.98);box-shadow:var(--shadow-lg);text-align:center;
  transform:translateY(16px) scale(.96);transition:transform .45s var(--ease-spring);
}
.welcome.show .welcome-panel,.modal.show .modal-panel{transform:none}
.notification-locked .app,.notification-locked .bottomnav{visibility:hidden;pointer-events:none;user-select:none}
.notification-gate{display:grid;place-items:center;opacity:1;pointer-events:auto;background:rgba(26,12,18,.82);backdrop-filter:blur(18px)}
.notification-gate.hidden{display:none}.notification-gate.show{opacity:1}
.notification-panel{box-shadow:var(--shadow-lg)}
.notification-requirement{display:flex;gap:10px;align-items:flex-start;margin:18px 0 14px;padding:13px 14px;border:1px solid rgba(184,69,47,.18);border-radius:var(--radius-sm);background:var(--accent-soft);color:var(--text);font-size:.78rem;line-height:1.5;text-align:left}
.notification-requirement svg{width:18px;flex:0 0 auto;margin-top:1px;color:var(--accent-strong)}
.notification-status{margin:10px 0 0!important;padding:10px 12px;border-radius:var(--radius-sm);background:var(--surface-warm);color:var(--muted)!important;font-size:.76rem!important;font-weight:700}
.notification-status.success{background:#edf8f3;color:#277f68!important}.notification-status.error{background:#fff0f2;color:#b04b5f!important}
.notification-help{font-size:.72rem!important;margin:12px 0 0!important}.notification-panel .primary[disabled]{opacity:.72;cursor:not-allowed;transform:none}
/* ---------- Gerbang akun Puter, digubah mengikuti Audit UX Bagian 3 ----------
   Bentuknya sekarang mengikuti layar Apple Sign-In: latar tenang satu warna, lambang
   merek di atas, judul besar berjarak lega, SATU tombol utama penuh lebar berbentuk
   pil, lalu keterangan kecil yang diam. Tidak ada ikon dekoratif, tidak ada kartu
   bergradien, tidak ada elemen bawaan browser yang terlihat - kelapangan yang membawa
   kesan mahal, bukan ornamen. */
.auth-locked .app,.auth-locked .bottomnav{visibility:hidden;pointer-events:none;user-select:none}
.auth-gate{z-index:150;background:var(--bg);backdrop-filter:none}
.auth-gate .auth-panel{
  width:min(400px,100%);
  padding:44px 34px 36px;
  border:1px solid var(--line);
  border-radius:var(--radius-lg);
  background:var(--panel);
  box-shadow:var(--shadow-lg);
  text-align:center;
}
.auth-gate .auth-mark{display:block;width:72px;height:72px;margin:0 auto 26px;border-radius:var(--radius-md);object-fit:contain}
.auth-gate .auth-panel h2{
  margin:0 0 10px;
  font-family:var(--fz-heading);
  font-size:1.62rem;line-height:1.2;letter-spacing:-.03em;font-weight:700;
  color:var(--text);
}
.auth-gate .auth-panel #authGateBody{
  margin:0 auto 26px;max-width:19rem;
  color:var(--muted);font-size:.88rem;line-height:1.6;
}
/* Status dirancang sebagai komponen sendiri, bukan alert bawaan browser (Bagian 3). */
.auth-gate .auth-status{
  margin:0 0 16px;padding:10px 14px;border-radius:var(--radius-sm);
  background:var(--panel-soft);color:var(--muted);
  font-size:.76rem;font-weight:700;line-height:1.45;
}
.auth-gate .auth-status.success{background:var(--green-soft);color:var(--green)}
.auth-gate .auth-status.error{background:var(--red-soft);color:var(--red)}
/* Satu tombol, penuh lebar, tinggi 52px - hierarki tombol Apple: yang utama tidak
   berbagi panggung dengan apa pun. */
.auth-gate .auth-primary{
  display:flex;align-items:center;justify-content:center;gap:9px;
  width:100%;min-height:52px;padding:0 20px;
  border:0;border-radius:var(--radius-pill);
  background:var(--sun);color:var(--text);
  font-family:var(--fz-body);font-size:.96rem;font-weight:600;letter-spacing:-.01em;
  box-shadow:0 10px 26px rgba(36,26,17,.14);
}
.auth-gate .auth-primary:hover{background:var(--sun-deep);border-color:transparent;box-shadow:var(--shadow-md)}
.auth-gate .auth-primary svg{width:19px;height:19px}
.auth-gate .auth-primary[disabled]{background:var(--panel-soft);color:var(--text-disabled);opacity:1;cursor:not-allowed;transform:none;box-shadow:none}
/* m026-02 tombol sekunder "Lanjut tanpa akun". Bentuknya sengaja SEKUNDER - tanpa
   latar, tanpa bayangan - supaya hierarki Apple di atas tetap utuh: yang utama tetap
   satu. Tetap penuh lebar dan tetap 44px supaya bisa ditekan dengan ibu jari. */
.auth-gate .text-button{
  display:flex;align-items:center;justify-content:center;
  width:100%;min-height:44px;margin:12px 0 0;padding:0 16px;
  border:0;background:transparent;box-shadow:none;
  color:var(--accent-strong);font-family:var(--fz-body);font-size:.86rem;font-weight:600;
}
.auth-gate .text-button:hover{background:var(--panel-soft);box-shadow:none;transform:none}
.auth-gate .text-button[disabled]{color:var(--text-disabled);cursor:not-allowed;transform:none}
.auth-gate #authGateSkipHelp{margin:10px 0 0}
.auth-gate .auth-help{margin:18px 0 0;color:var(--muted);font-size:.76rem;line-height:1.55}
.auth-gate .auth-legal{margin:14px 0 0;color:var(--muted-soft);font-size:.68rem;line-height:1.5}
@media (max-width:420px){.auth-gate .auth-panel{padding:36px 24px 30px;border-radius:var(--radius-lg)}.auth-gate .auth-mark{width:60px;height:60px;margin-bottom:20px}}
.auth-panel .primary[disabled]{opacity:.6;cursor:not-allowed;transform:none}
.welcome-mark,.modal-mark{font-weight:700;letter-spacing:-.06em;font-size:1.02rem;color:var(--black)}
.welcome-panel h2,.modal-panel h2{font-size:1.9rem;letter-spacing:-.03em;margin:12px 0 8px;font-weight:700}
.welcome-panel p,.modal-panel p{color:var(--muted);line-height:1.6;font-size:.92rem}
.welcome-panel .primary,.modal-actions{margin-top:16px}
.modal-actions{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
.modal-actions button{flex:1;min-width:120px}
/* Audit 04-001: di 320px "Simpan pengaturan" tidak muat di tombol 122px - teksnya
   menerobos keluar kotak dan menimpa "Batal". Di layar sesempit itu tombolnya
   dibiarkan membungkus jadi baris penuh (flex-wrap sudah ada di .modal-actions). */
@media (max-width:340px){.modal-actions button{flex-basis:100%}}

/* ---------- FIEZEL AI ---------- */
.ai-btn{
  margin-top:14px;width:100%;
  background:linear-gradient(135deg,var(--accent-soft),var(--panel-soft));
  border-color:var(--line);color:var(--accent-strong);font-weight:700;
}
.ai-btn:hover{border-color:var(--accent);box-shadow:var(--shadow-md)}
.ai-answer{margin-top:6px;line-height:1.7;font-size:.92rem;color:var(--text);text-align:left}
.ai-answer p{margin:0 0 10px;color:var(--text)}
/* Penanda jawaban mode hemat. Bukan galat, jadi tidak memakai warna galat - hanya nada
   sekunder plus garis kiri supaya murid tahu jawaban ini datang dari FIEZEL, bukan AI. */
.ai-degraded-note{margin:0 0 10px;padding:6px 10px;border-left:3px solid var(--line);
  background:var(--panel-soft);color:var(--muted);font-size:.82rem;line-height:1.55;text-align:left}
.ai-loading{display:flex;gap:7px;justify-content:center;margin:22px 0}
.ai-loading span{width:9px;height:9px;border-radius:50%;background:var(--accent);animation:aiBounce calc(var(--dur-l) + var(--dur-l)) var(--ease) infinite}
.ai-loading span:nth-child(2){animation-delay:var(--dur-s)}
.ai-loading span:nth-child(3){animation-delay:var(--dur-m)}
@keyframes aiBounce{0%,80%,100%{transform:translateY(0);opacity:.5}40%{transform:translateY(-7px);opacity:1}}

@media(min-width:640px){
  .app{padding-top:30px}
  .stats{grid-template-columns:repeat(4,1fr)}
}
@media(max-width:640px){
  .hero h2{font-size:1.6rem}
  .three{grid-template-columns:1fr 1fr}
  .three button:last-child{grid-column:1/-1}
  .level-grid{grid-template-columns:1fr}
  .quiz-topbar{top:-1px}
}

/* D15 (audit D5-S7): scroll-behavior ikut dimatikan di blok OS ini, bukan hanya di
   preferensi in-app (.reduce-motion) - murid yang menyetel kurangi-gerak di OS tidak
   boleh tetap mendapat smooth-scroll dari html{scroll-behavior:smooth}. */
@media(prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}/* q17-M1: delay ikut nol — kartu riseIn tidak boleh muncul berurutan di bawah reduce */
}

/* ---------- misc feature blocks (progress / diagnostics) ---------- */
.adaptive-note{margin-top:8px}
.passage{background:var(--surface-cool);border:1px solid var(--line);border-radius:var(--radius-lg, 16px);padding:20px 22px;margin-bottom:18px}
.passage h3{margin:4px 0 10px;font-size:1.15rem;font-weight:700}
.passage p{white-space:pre-wrap;word-break:break-word}
/* i10 2026-08-28 (O5 §4a): kartu bacaan = halaman buku, bukan kartu UI — judul serif
   display, ukuran baca 1rem, jarak baris 1.85, lebar baris dibatasi 62ch. */
.card-reading{background:var(--panel);box-shadow:none;border:1px solid var(--line-soft);border-radius:var(--radius-lg, 18px)}
.passage-reading h3{font-family:"Instrument Serif",serif;font-size:1.55rem;line-height:1.25;margin:4px 0 12px;color:var(--ink)}
.passage-reading p{font-size:1.04rem;line-height:1.85;color:var(--text);max-width:64ch;letter-spacing:0.005em}
.flash-back .muted{margin-top:12px}

/* Reading Mode: 2-column layout on Desktop & Tablet, comfortable peek on Mobile */
@media(min-width:860px){
  .quiz-shell:has(.card-reading){
    display:grid!important;
    grid-template-columns:1.2fr 1fr!important;
    grid-template-areas:"topbar topbar" "reading question"!important;
    gap:24px!important;
    align-items:start!important;
    max-width:1140px!important;
    margin:0 auto!important;
  }
  .quiz-shell:has(.card-reading) .quiz-topbar{grid-area:topbar!important}
  .quiz-shell:has(.card-reading) .card-reading{
    grid-area:reading!important;
    position:sticky!important;
    top:76px!important;
    max-height:calc(100vh - 100px)!important;
    overflow-y:auto!important;
    scrollbar-width:thin;
    margin-bottom:0!important;
  }
  .quiz-shell:has(.card-reading) > .card:not(.card-reading){grid-area:question!important}
  .reading-jump-bar{display:none!important}
}

/* Desktop 3-column split when Reading passage AND Side Mascot are both present */
@media(min-width:980px){
  .quiz-shell:has(.card-reading).has-paw-side{
    display:grid!important;
    grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) 164px!important;
    grid-template-areas:"topbar topbar topbar" "reading question mascot"!important;
    gap:20px!important;
    max-width:1320px!important;
    margin:0 auto!important;
  }
  .quiz-shell:has(.card-reading).has-paw-side .quiz-topbar{grid-area:topbar!important}
  .quiz-shell:has(.card-reading).has-paw-side .card-reading{grid-area:reading!important}
  .quiz-shell:has(.card-reading).has-paw-side > .card:not(.card-reading){grid-area:question!important}
  .quiz-shell:has(.card-reading).has-paw-side > .fz-paw-side{
    grid-area:mascot!important;
    grid-column:3!important;
    grid-row:2/span 8!important;
    position:sticky!important;
    top:96px!important;
    margin:0!important;
    display:flex!important;
    z-index:1!important;
    pointer-events:none!important;
  }
}
@media(min-width:860px) and (max-width:979px){
  .quiz-shell:has(.card-reading) > .fz-paw-side{
    display:none!important;
  }
}
.reading-jump-bar{margin-bottom:12px}
.reading-jump-btn{
  display:inline-flex;align-items:center;gap:8px;
  background:var(--surface-cool);border:1px solid var(--line-soft);
  border-radius:var(--radius-pill, 999px);padding:6px 14px;
  font-size:.84rem;font-weight:600;color:var(--muted);cursor:pointer;
  transition:background .15s ease,color .15s ease;
}
.reading-jump-btn:hover{background:var(--panel);color:var(--ink)}
.reading-jump-btn svg{width:14px;height:14px}
.passage-reading{scroll-margin-top:76px}

/* Listening Mode: Speed controls and animated visualizer wave */
.quiz-listen-controls{display:flex;align-items:center;justify-content:center;gap:10px;margin-bottom:8px}
.quiz-listen-speed-btn{
  background:var(--surface-cool);border:1.5px solid var(--line);
  border-radius:var(--radius-pill, 999px);padding:8px 14px;min-height:44px;
  font-size:.88rem;font-weight:700;color:var(--ink);cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  transition:all .15s ease;
}
.quiz-listen-speed-btn:hover{background:var(--panel);border-color:var(--accent)}
.quiz-listen-speed-btn.is-slow{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
.quiz-audio-wave{display:flex;align-items:center;justify-content:center;gap:4px;height:24px;margin:6px 0 8px}
.quiz-audio-wave.hidden{display:none}
.quiz-audio-wave span{
  display:inline-block;width:4px;background:var(--accent);border-radius:2px;
  animation:audioWavePulse 1s ease-in-out infinite alternate;
}
.quiz-audio-wave span:nth-child(1){animation-delay:.1s;height:35%}
.quiz-audio-wave span:nth-child(2){animation-delay:.3s;height:75%}
.quiz-audio-wave span:nth-child(3){animation-delay:.2s;height:100%}
.quiz-audio-wave span:nth-child(4){animation-delay:.4s;height:60%}
.quiz-audio-wave span:nth-child(5){animation-delay:.15s;height:40%}
@keyframes audioWavePulse{0%{transform:scaleY(.3)}100%{transform:scaleY(1)}}

/* Floating Next Action Bar (Thumb-Zone Ergonomics)
   m025-361: z-index dulu 999 - di atas SEMUA lapisan, termasuk dialog .modal (z100), jadi
   "Lanjut" menimpa "Yakin mau keluar?" dan bisa diketuk di balik dialog itu. Bilah ini
   bagian halaman kuis, bukan lapisan: 50 = di atas isi kuis (topbar z30, pembimbing z41),
   di bawah setiap lapisan (dock tutor z55, overlay z60+, toast z80 yang tembus-pointer,
   lembar z95, .modal z100, #confidencePop). */
.quiz-floating-bar{
  position:fixed;bottom:calc(16px + env(safe-area-inset-bottom, 0px));
  left:0;right:0;display:flex;justify-content:center;align-items:center;
  padding:0 16px;z-index:50;pointer-events:none;opacity:0;
  transform:translateY(16px);
  transition:opacity .22s cubic-bezier(.16,1,.3,1),transform .22s cubic-bezier(.16,1,.3,1);
}
.quiz-floating-bar.is-visible{opacity:1;transform:translateY(0);pointer-events:auto}
.quiz-floating-next-btn{
  width:100%;max-width:480px;min-height:52px;
  display:flex;align-items:center;justify-content:center;gap:12px;
  border-radius:var(--radius-pill, 999px);font-size:1.05rem;font-weight:700;
  box-shadow:0 8px 24px -4px rgba(36,26,17,.3),0 2px 8px rgba(234,88,12,.25);
  cursor:pointer;border:none;
  background:linear-gradient(135deg,#EA580C,#C2410C);
  color:#fff;transition:transform .15s ease,box-shadow .15s ease;
}
.quiz-floating-next-btn:active{transform:scale(.96);transition-duration:.08s}
.quiz-shell{padding-bottom:calc(92px + env(safe-area-inset-bottom, 0px))!important}/* audit F08: 52px tombol + 16px jarak + nafas, ditambah area aman iOS - pembahasan terakhir tidak pernah tertutup */
.quiz-shell.has-retry-active,
.quiz-shell:has(#tutorTurn:not(.hidden)){padding-bottom:calc(220px + env(safe-area-inset-bottom, 0px))!important}
/* ==========================================================================
   Popup keyakinan (m025-133)
   ==========================================================================
   Percobaan ketiga, dan dua yang gagal sebelumnya layak dicatat karena keduanya salah
   dengan cara yang sama: kotak ini selalu dipindah TEMPATNYA, sementara masalahnya soal
   WAKTU. Di dasar panel umpan balik ia harus dicari dengan menggulir. Mengambang di dasar
   layar ia justru menutupi tombol Lanjut.

   Sebagai popup ia tidak perlu dicari dan tidak menghalangi apa pun - karena ia SENDIRI
   yang membawa tombol Lanjutnya, persis yang diminta OWNER.

   Ukurannya sengaja kecil dan duduk agak ke bawah: penjelasan jawaban ada di halaman di
   baliknya, dan latar gelapnya dibuat tipis supaya halaman itu tetap terlihat. Popup yang
   menutup pelajarannya sendiri akan menukar satu masalah dengan masalah lain.
   -------------------------------------------------------------------------- */
.confidence-pop{
  position:fixed;inset:0;z-index:2147481400;
  display:flex;align-items:flex-end;justify-content:center;
  padding:14px 14px calc(20px + env(safe-area-inset-bottom));
  background:var(--scrim-soft);
}
.confidence-card{
  width:min(420px,100%);
  padding:16px;border-radius:var(--radius-lg);
  border:1.5px solid var(--ink);background:rgba(var(--surface-pure-rgb),.98);
  box-shadow:0 3px 0 var(--ink),0 22px 50px rgba(36,26,17,.3);
}
.confidence-verdict{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-size:.98rem;font-weight:700;letter-spacing:-.01em}
.confidence-verdict svg{width:20px;height:20px;flex:none}
.confidence-verdict.is-ok{color:var(--good)}
.confidence-verdict.is-no{color:var(--bad)}
.confidence-q{margin:0 0 9px;font-size:.88rem;font-weight:700;color:var(--text)}

.confidence-scale{display:grid;grid-template-columns:repeat(3,1fr);gap:7px}
.confidence-scale button{
  flex-direction:column;gap:2px;min-height:62px;padding:9px 4px;
  font-size:.7rem;font-weight:700;line-height:1.25;text-align:center;border-radius:var(--radius-md);
}
.confidence-scale button span{font-size:1.15rem;font-weight:700;line-height:1;font-variant-numeric:tabular-nums}
/* Tiga tingkat, tiga warna - supaya terbaca sebagai SKALA, bukan tiga tombol yang
   kebetulan bersebelahan. */
.confidence-scale button:nth-child(1){background:var(--bad-soft)}
.confidence-scale button:nth-child(2){background:var(--sun-soft)}
/* Tinta tombol ketiga dipasang EKSPLISIT. --yellow beku di kedua tema, sementara tinta
   yang diwarisi ikut berbalik jadi krem di mode gelap - krem di atas kuning. */
.confidence-scale button:nth-child(3){background:var(--sun);color:var(--text)}

.confidence-skip{
  display:block;width:100%;margin-top:10px;padding:12px 6px;
  background:none;border:0;box-shadow:none;
  color:var(--muted);font-size:.78rem;font-weight:600;text-decoration:underline;
}
.confidence-skip:hover{background:none;box-shadow:none;transform:none;color:var(--text)}

.confidence-saved{
  display:flex;align-items:center;gap:6px;margin:0 0 12px;
  font-size:.86rem;font-weight:700;color:var(--good);
}
.confidence-saved svg{width:16px;height:16px}
.confidence-go{width:100%;min-height:54px;font-size:1rem;font-weight:700}

@media (prefers-reduced-motion:no-preference){
  .confidence-pop{animation:fzPopFade .2s var(--ease) both}
  .confidence-card{animation:fzPopRise .32s cubic-bezier(.3,1.12,.5,1) both}
  @keyframes fzPopFade{from{opacity:0}to{opacity:1}}
  @keyframes fzPopRise{from{opacity:0;transform:translateY(22px) scale(.97)}to{opacity:1;transform:none}}
  .confidence-pop.is-out{animation:fzPopFade .2s var(--ease) reverse both}
}
.confidence-pop.is-out{opacity:0;pointer-events:none}
.creator-credit{display:flex;align-items:center;gap:9px;margin-top:10px;color:var(--muted);font-size:.82rem}
.instagram-mark{width:22px;height:22px;border:2px solid var(--black);border-radius:var(--radius-xs);display:inline-grid;place-items:center;font-size:16px;line-height:1}
.grid>div>h3{margin:4px 2px 12px;font-size:1rem}
.grid hr{border:0;border-top:1px solid var(--line);margin:10px 0}
.timeline-row{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--line-soft);font-size:.82rem}
.timeline-row span:last-child{color:var(--muted);text-align:right}
.diag-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:12px 0}
.diag-grid>div{padding:12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface-tint)}
.confusion-network{display:grid;gap:9px}
.confusion-node{display:grid;grid-template-columns:1fr auto 1fr;gap:8px;align-items:center;padding:10px;border:1px solid var(--line);border-radius:var(--radius-sm)}
.confusion-node span:nth-child(3){text-align:right}
.confusion-node small{grid-column:1/-1;color:var(--muted)}
.creator-link{display:inline-flex;align-items:center;gap:7px;color:inherit;text-decoration:none}
.creator-link img{display:block}
@media(max-width:640px){
  .diag-grid{grid-template-columns:1fr}
  .timeline-row{align-items:flex-start;flex-direction:column}
  .timeline-row span:last-child{text-align:left}
}

/* ==========================================================================
   FIEZEL Design System v6.0
   Premium personal launcher, unified motion, tactile navigation, Creator Hub.
   ========================================================================== */

/* m025-46: this is the palette the product actually runs on - it overrides the block
   at the top of the file.
   m025-115: netralnya ikut pindah ke keluarga cream/pastel. Blok ini gampang terlewat
   justru karena ia yang menang - kalau hanya blok paling atas yang diganti, aplikasi
   tetap berjalan dengan netral marun lama sementara tokennya sudah pastel. */
/* F17: token blok ini pindah ke :root tunggal di awal berkas. */

/* ==========================================================================
   MODE GELAP DIHAPUS (Permintaan OWNER: "HAPUS KAN SISTEM MODE GELAP")
   ==========================================================================
   Aplikasi memiliki satu tampilan dasar: palet cream/terang yang konsisten.
   Seluruh jalur tema gelap dan selektor terkait telah dicabut seluruhnya. */

/* Font merek berlaku di SELURUH aplikasi, termasuk gerbang izin, gerbang akun, modal,
   dan toast - bukan hanya di splash/onboarding seperti sebelumnya (Audit Roadmap #4). */
body{background:var(--sky-bottom);font-family:var(--fz-body)}
h1,h2,h3,h4,.welcome-mark,.modal-mark{font-family:var(--fz-heading)}
/* Ukuran display: serif, berat 400, jarak huruf sedikit dirapatkan. Kerapatan negatif pada
   ukuran besar adalah yang membedakan judul yang "disetel" dari judul yang sekadar dibesarkan. */
.section-head h1,.welcome-panel h2,.modal-panel h2,.fiezel-title{
  font-family:var(--fz-display);font-weight:400;letter-spacing:-.015em}

.app{max-width:1120px;padding:var(--sp-5) var(--sp-6) calc(126px + env(safe-area-inset-bottom))}
button{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-weight:600}
button svg,.creator-link svg{width:17px;height:17px;flex:0 0 auto}
.wide{width:100%}

.topbar{
  position:sticky;top:0;z-index:35;margin:0 -10px 24px;padding:12px 10px;
  background:var(--chrome-bg);border-radius:0 0 var(--radius-md) var(--radius-md);
}
.brand-button{display:flex;align-items:center;gap:12px;border:0;background:transparent;padding:6px 2px;box-shadow:none;color:var(--ambient-text)}
.brand-button:hover{transform:none;border-color:transparent;box-shadow:none}
.brand{width:112px}.brand-edition{font-size:var(--fs-caption);letter-spacing:.14em;text-transform:uppercase;color:var(--ambient-muted);font-weight:700;border-left:1px solid rgba(255,255,255,.24);padding-left:12px}
/* Audit 20-003: di 280px topbar-actions menolak menyusut dan mendorong scroll horizontal.
   min-width:0 mengizinkan flex item ini mengecil di bawah lebar konten minimumnya. */
.topbar-actions{display:flex;align-items:center;gap:8px;min-width:0}
/* m025-113: tombol ikon duduk DI DALAM topbar, dan topbar kini memakai --chrome-bg yang
   ikut fase langit. Permukaan bertema di dalam kroma sadar-fase itulah cara lama bug
   kontras kembali: pukul 22.00 kromanya gelap, lingkaran ini tetap putih. Keduanya kini
   satu keluarga. */
.icon-button{width:44px;height:44px;padding:0;border-radius:50%;background:var(--glass-thin);color:var(--glass-text)}
.icon-button.active{color:var(--accent-strong);border-color:#cfc8f6;background:var(--accent-soft)}
.version{min-width:40px;text-align:right}

.section-kicker{display:block;font-size:var(--fs-caption);letter-spacing:.16em;text-transform:uppercase;color:var(--accent-on-glass);font-weight:700;margin-bottom:6px}
.section-head{padding:10px 0 4px;margin-bottom:18px}/* v6.1 (O4 §5): dup h1 clamp yang terbayangi dihapus — sumber tunggal = var(--fs-display). */
.card{background:rgba(var(--surface-rgb),.93);box-shadow:var(--shadow-sm)}
.primary{background:var(--sun);color:var(--text);border-color:var(--sun-deep)}
.primary:hover{background:var(--sun-deep);border-color:var(--sun-deep)}

/* Premium Home Launcher */
.home-page{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--sp-6)}/* kolom minmax(0,1fr): tanpa itu kolom implisit dilebarkan oleh min-content anak terlebar, dan di 320px Home menggeser horizontal (gerbang T6). */
.launcher-shell{
  position:relative;overflow:hidden;display:grid;grid-template-columns:minmax(0,1.42fr) minmax(300px,.72fr);gap:36px;
  grid-template-rows:1fr;
  min-height:500px;padding:clamp(34px,5vw,62px);border-radius:var(--radius-lg);color:#f8f8fb;
  background:linear-gradient(135deg,var(--launcher-start) 0%,rgba(21,26,56,.72) 56%,var(--launcher-end) 132%);
  /* v6.1 (O4 §2): satu bayangan launcher saja — def v6 di bawah memegang var(--shadow-md). */
}
.launcher-shell::after{content:"";position:absolute;width:320px;height:320px;border-radius:50%;right:-170px;top:-180px;background:rgba(216,179,107,.16);filter:blur(2px);pointer-events:none}
.launcher-copy{position:relative;z-index:1;align-self:center}
.launcher-meta{display:flex;align-items:center;flex-wrap:wrap;gap:10px;color:#c8cad8;font-size:.65rem;letter-spacing:.14em;text-transform:uppercase;font-weight:700}
.celestial-status{display:inline-flex;align-items:center;gap:7px;margin-left:auto;padding:7px 10px;border:1px solid rgba(255,255,255,.14);border-radius:var(--radius-pill);background:rgba(255,255,255,.07);letter-spacing:0;text-transform:none;color:#faf5f6}.celestial-status svg{width:14px;height:14px}.celestial-status span{color:#cdbcc1;font-weight:600}
.live-signal{width:7px;height:7px;border-radius:50%;background:#8fd8b8;box-shadow:0 0 0 6px rgba(143,216,184,.1);animation:signalPulse 2.4s ease-in-out infinite}
.launcher-greeting{color:var(--gold);font:500 1rem Georgia,"Times New Roman",serif;font-style:italic;margin:30px 0 8px}
.launcher-copy h1{font-size:clamp(2.5rem,5.7vw,5rem);line-height:.98;letter-spacing:-.06em;margin:0;max-width:850px;font-weight:700}.launcher-copy h1.login-message{font-size:clamp(2.15rem,4.5vw,4.25rem);line-height:1.02}
.launcher-copy h1 span{color:#e8a3ad}
.launcher-lead{font-size:1rem;line-height:1.7;color:#cdbcc1;max-width:680px;margin:22px 0 0}.learner-stage{display:flex;align-items:center;gap:8px;margin:13px 0 0;color:#c0aeb3;font-size:.72rem}.learner-stage svg{width:16px;height:16px;color:#d8b36b}
.launcher-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:30px}
/* v6.1 (O4 §8): varian .luxe putih raw-hex era launcher DIHAPUS (03-003) — .luxe kini
   murni alias primary lewat daftar selektor resep chunky v6. Kelas di markup tetap. */
.ghost-dark{background:transparent;color:#faf5f6;border-color:rgba(255,255,255,.2)}
.ghost-dark:hover{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.34)}
.launcher-trust{display:flex;flex-wrap:wrap;gap:18px;margin-top:26px;color:#9fa3b6;font-size:.72rem}
.launcher-trust span{display:flex;align-items:center;gap:7px}.launcher-trust svg{width:15px}

.coach-preview{position:relative;z-index:1;align-self:stretch;display:flex;flex-direction:column;padding:25px;border:1px solid rgba(255,255,255,.13);background:rgba(255,255,255,.075);border-radius:var(--radius-lg)}
.coach-head{display:flex;align-items:center;gap:11px}.coach-head>div{display:grid;gap:3px}.coach-head small{color:#c0aeb3;font-size:var(--fs-caption);letter-spacing:.14em}.coach-head b{font-size:.86rem}
.coach-icon{width:42px;height:42px;display:grid;place-items:center;border-radius:var(--radius-sm);color:#171d31;background:#d8b36b}.coach-icon svg{width:21px;height:21px}
.coach-level{display:flex;justify-content:space-between;align-items:end;margin:34px 0 22px;padding-bottom:18px;border-bottom:1px solid rgba(255,255,255,.12)}
.coach-level span{color:#afb2c4;font-size:.72rem}.coach-level strong{font:600 2.4rem Georgia,"Times New Roman",serif;color:#d9d3ff}
/* m025-99 (brief 3.7): kartu Coach kini menampilkan RINGKASAN, dan detailnya ada di balik
   tombol "Buka analisis personal" tepat di bawahnya. Pagar tinggi di sini adalah jaring
   pengaman kedua: dua kalimat pun bisa panjang, dan kartu ini tidak boleh lagi mendorong
   seluruh Home ke bawah seperti sebelum rilis ini. */
.coach-body{margin:0 0 4px}
.coach-body>p{margin:0 0 8px}
.coach-body>p:last-child{margin-bottom:0}
.coach-body strong{color:var(--gold);font-weight:700}
.coach-preview h2{font-size:1.35rem;line-height:1.25;letter-spacing:-.025em;margin:0 0 10px}.coach-preview p{color:#b7bacb;line-height:1.62;font-size:.83rem;margin:0 0 24px}
.coach-link{margin-top:auto;padding:0;justify-content:flex-start;color:#f6f5fa;background:transparent;border:0;box-shadow:none}.coach-link:hover{transform:translateX(3px);box-shadow:none;border-color:transparent}

.home-overview{display:grid;grid-template-columns:minmax(320px,.92fr) minmax(0,1.08fr);gap:12px}
.mission-panel{display:flex;align-items:center;gap:19px;padding:22px;border:1px solid var(--glass-line);background:var(--glass-thick);border-radius:var(--radius-md);color:var(--glass-text)}
.mission-panel h3{margin:2px 0 4px;font-size:1.05rem}.mission-panel p{margin:0;color:var(--glass-muted);font-size:.78rem;line-height:1.55}
.mission-ring{--ring-size:76px;width:var(--ring-size);height:var(--ring-size);flex:0 0 auto;border-radius:50%;display:grid;place-items:center;background:conic-gradient(var(--sun-deep) var(--mission),var(--line-soft) 0)}
.mission-ring::before{content:"";grid-area:1/1;width:60px;height:60px;border-radius:50%;background:var(--panel)}
.mission-ring div{grid-area:1/1;z-index:1;display:flex;align-items:baseline}.mission-ring strong{font-size:1.2rem}.mission-ring span{font-size:.65rem;color:var(--muted)}
.home-stats{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--glass-line);border-radius:var(--radius-md);background:var(--glass-thick);overflow:hidden;color:var(--glass-text)}
.home-stats>div{padding:22px 16px;border-right:1px solid var(--glass-line)}.home-stats>div:last-child{border:0}.home-stats small{display:block;color:var(--glass-muted);font-size:var(--fs-caption);text-transform:uppercase;letter-spacing:.1em}.home-stats strong{display:block;font-size:1.15rem;margin-top:8px}

.home-section-head{display:flex;align-items:end;justify-content:space-between;gap:20px;margin-top:14px}.home-section-head h2{font-size:var(--fs-h1);margin:0;letter-spacing:-.035em}.text-button{border:0;background:transparent;padding:6px;color:var(--accent-strong);box-shadow:none}.text-button:hover{box-shadow:none;border-color:transparent;transform:translateX(2px)}
/* ==========================================================================
   HOME "HARI INI" (m025-246)
   ==========================================================================
   Satu kartu, satu tombol. Semua warna lewat token, tanpa satu literal pun -
   itulah syarat kartu ini ikut berbalik sendiri di Tema Malam tanpa aturan
   kedua (pelajaran dari m025-85: permukaan yang memaku warnanya sendiri adalah
   satu-satunya sebab mode gelap lama tidak terbaca). */
/* Keadaan gagal audio di soal dengar kuis (m025-246). Tiga jalan keluar berdiri
   berdampingan di tempat kegagalannya terjadi - bukan di atas lipatan, tempat
   murid yang baru saja membaca "suaranya belum berbunyi" tidak akan melihatnya. */
.quiz-audio-fallback{
  margin-top:var(--sp-3);padding:var(--sp-3);
  border:1px solid var(--line);border-radius:var(--radius-sm);
  background:var(--surface-tint);
  display:flex;flex-direction:column;gap:var(--sp-2)}
.quiz-audio-fallback-actions{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.quiz-audio-fallback-actions button{flex:1 1 auto;min-height:44px}
.quiz-audio-fallback small{font-size:var(--fs-caption);line-height:var(--lh-body)}

/* Peringatan penyimpanan iOS (m025-246). Nada peringatan, bukan nada galat: ia
   memberi tahu sesuatu yang BISA terjadi dan menawarkan jalan keluarnya, jadi
   warnanya keluarga --info (kuning), bukan --bad (merah). */
.storage-warning{border:1px solid var(--info);background:var(--info-soft)}
.storage-warning h3{display:flex;align-items:center;gap:8px;margin:0 0 6px;color:var(--text)}
.storage-warning h3 svg{width:18px;height:18px;color:var(--info)}
.storage-warning button{margin-top:var(--sp-3)}

/* Ringkasan akhir sesi (m025-246). Ditempel di layar hasil, di bawah skor:
   skor menjawab "berapa nilaiku", dua blok ini menjawab "apa yang bergerak" dan
   "apa yang menunggu besok". Semua warna lewat token, jadi ia ikut Tema Malam
   tanpa aturan kedua. */
.session-summary{
  text-align:left;margin-top:var(--sp-5);padding-top:var(--sp-4);
  border-top:1px solid var(--line)}
.session-summary h3{
  margin:0 0 var(--sp-3);font-size:var(--fs-caption);letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);font-weight:700}
.summary-block{margin-bottom:var(--sp-3)}
.summary-block>b{display:block;font-size:var(--fs-small);color:var(--text);margin-bottom:4px}
.summary-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.summary-list li{
  font-size:var(--fs-small);color:var(--text);
  padding:8px 10px;border-radius:var(--radius-xs);background:var(--good-soft)}
.summary-due{margin:0;font-size:var(--fs-small);color:var(--text)}

.today-card{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:var(--sp-6);box-shadow:var(--shadow-md);
  display:flex;flex-direction:column;gap:var(--sp-3);
  max-width:640px;margin:0 auto}
.today-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3)}
/* AUDIT-2026-09-21 T5: keping LEVEL+REVIEW di today-head — versi ringkas dari .hero-stat,
   satu baris di 320px, tetap ≥24px (WCAG 2.5.8) dan memakai token (syarat Tema Malam). */
.today-head-chips{display:flex;align-items:center;gap:8px}
.today-head-chips .hero-stat{padding:5px 10px;gap:4px}
.today-head-chips .hero-stat b{font-size:.85rem}
.today-head-chips .hero-stat small{font-size:.58rem}
.today-eyebrow{
  font-size:var(--fs-caption);letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);font-weight:700}
.today-title{
  font-family:var(--fz-display);font-weight:400;letter-spacing:-.015em;
  font-size:var(--fs-display);line-height:var(--lh-tight);margin:0;color:var(--text)}
/* AUDIT-2026-09-21 T8: kepala seksi latihan singkat — dulu h4 + tiga style= inline di luar
   jangkauan contrast-test/ui-structure-test. Kini lewat token. */
.quick-practice-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.quick-practice-title{margin:0;font-size:13px;font-weight:700;color:var(--text)}
.quick-practice-hint{color:var(--muted)}
.today-lead{margin:0;color:var(--muted);font-size:var(--fs-small);line-height:var(--lh-body)}
.today-isi-head{
  margin:var(--sp-2) 0 0;font-size:var(--fs-caption);letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);font-weight:700}
/* Isi sesi terbaca sebagai DAFTAR, bukan sebagai paragraf: murid harus bisa
   menghitung apa yang akan ia kerjakan dengan sekali lihat. */
.today-blocks{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-2)}
.today-blocks li{
  display:flex;flex-direction:column;gap:2px;
  background:var(--surface-tint);border:1px solid var(--line-soft);
  border-radius:var(--radius-sm);padding:var(--sp-3)}
.today-blocks li b{font-size:var(--fs-body);color:var(--text)}
.today-blocks li span{font-size:var(--fs-small);color:var(--muted);line-height:var(--lh-body)}
.today-empty{margin:0;color:var(--muted);font-size:var(--fs-small);line-height:var(--lh-body)}
.today-cta{width:100%;margin-top:var(--sp-2);min-height:52px;font-size:var(--fs-body)}
/* Tombol "latihan tambahan" setelah target tercapai. SENGAJA bukan .primary:
   satu layar, satu tombol primer - dan menagih sesi kedua sekuat sesi pertama
   adalah persis yang membuat aplikasi belajar terasa menuntut. */
.today-cta-soft{
  width:100%;margin-top:var(--sp-2);background:var(--surface-tint);
  border:1px solid var(--line);color:var(--text)}
/* Runtun SEKUNDER: satu baris kecil, bukan keping sebesar ajakan utamanya. */
.today-streak{
  margin:0;display:flex;align-items:center;gap:6px;
  font-size:var(--fs-small);color:var(--muted)}
.today-streak .fz-i{width:18px;height:18px}
.home-today .trust-line,.home-today .home-level-context{margin-top:var(--sp-2)}
@media (prefers-reduced-motion:no-preference){
  .today-blocks li{animation:today-block-in .32s var(--ease,ease) both;animation-delay:calc(var(--ti,0)*60ms)}
}
@keyframes today-block-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

.learning-launcher{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
/* Pintu Online & Teman di Home: satu kartu, jadi ia mengisi barisnya sendiri alih-alih
   duduk selebar seperempat di grid empat kolom. Kartunya juga lebih pendek dari launcher
   belajar — ini pintu sekunder, bukan salah satu dari empat tujuan utama. */
.social-home-launcher{grid-template-columns:1fr}
/* Kartu Home saat ada undangan teman yang belum dijawab. Pembeda visualnya SATU: garis
   emas yang sama dengan .social-code, supaya "ada sesuatu yang menunggumu" terbaca tanpa
   warna baru, tanpa animasi, dan tanpa kosakata bentuk baru di Home. */
.social-launch-invite,.social-launch-news{border-color:var(--gold);box-shadow:inset 0 0 0 1px rgba(201,162,75,.35)}
/* Lencana jumlah kabar belum terbaca. Ditumpangkan pada .launch-icon yang sudah ada, jadi
   ia tidak menambah kolom dan tidak menggeser tata letak kartu di 390px. */
.social-launch .launch-icon{position:relative}
.social-badge{position:absolute;top:-4px;right:-6px;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--gold);color:var(--text);font-size:.68rem;font-weight:700;line-height:18px;text-align:center;box-shadow:0 0 0 2px var(--panel)}
.social-home-launcher .launch-card{min-height:132px}
@media (max-width:900px){.social-home-launcher{grid-template-columns:1fr}}
@media (max-width:560px){.social-home-launcher{grid-template-columns:1fr}.social-home-launcher .launch-card{min-height:108px}}
.launch-card{position:relative;min-height:220px;padding:24px;display:grid;grid-template-columns:1fr auto;grid-template-rows:auto 1fr;text-align:left;align-items:start;justify-content:stretch;background:var(--panel);border-color:var(--line);overflow:hidden}
.launch-card>span:nth-child(2){grid-column:1/-1;align-self:end;display:grid;gap:6px}.launch-card>svg{grid-column:2;grid-row:1;width:18px;color:var(--muted)}
.launch-icon{width:46px;height:46px;display:grid;place-items:center;border-radius:var(--radius-sm);background:var(--accent-soft);color:var(--accent-strong)}.launch-icon svg{width:22px;height:22px}
.launch-card small{color:var(--muted);font-size:var(--fs-caption);letter-spacing:.1em;text-transform:uppercase}.launch-card b{font-size:var(--fs-body);letter-spacing:-.025em}.launch-card em{font-style:normal;font-weight:500;color:var(--muted);font-size:.78rem;line-height:1.5}
.launch-card:hover{transform:translateY(-5px);box-shadow:var(--shadow-md)}
.grammar-launch .launch-icon{background:var(--sun-soft);color:var(--info)}.reading-launch .launch-icon{background:var(--good-soft);color:var(--good)}.skills-launch .launch-icon{background:var(--info-soft);color:var(--info)}
.skills-page{display:grid;gap:18px}.voice-setup-card{display:flex;align-items:center;justify-content:space-between;gap:22px;padding:22px;border:1px solid var(--line);border-radius:var(--radius-md);background:rgba(var(--surface-rgb),.93);color:var(--text)}.voice-setup-copy{min-width:0;flex:1}.voice-setup-card h2{margin:0 0 7px;font-size:1.15rem}.voice-setup-card p{max-width:720px;margin:0;color:var(--muted);font-size:.8rem;line-height:1.55}.voice-setup-actions{display:flex;gap:10px;align-items:center;flex:0 0 auto}.voice-setup-card button{flex:0 0 auto}.neural-voice-choice{display:grid;gap:5px;margin-top:14px;max-width:360px}.neural-voice-choice span{font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.neural-voice-choice select{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface-solid);color:var(--text);font:inherit}.neural-voice-choice small{color:var(--muted);font-size:.72rem;line-height:1.4}.skills-loading{padding:24px}
.privacy-strip{display:flex;justify-content:space-between;align-items:center;gap:18px;padding:20px 22px;border:1px solid var(--line);border-radius:var(--radius-md);background:rgba(var(--surface-rgb),.9);color:var(--text)}
.privacy-strip>div{display:flex;align-items:center;gap:13px}.privacy-strip b{font-size:.86rem}.privacy-strip p{margin:3px 0 0;color:var(--muted);font-size:.74rem}.privacy-icon{width:40px;height:40px;display:grid;place-items:center;border-radius:var(--radius-sm);color:var(--accent-strong);background:var(--accent-soft)}

/* Controls, reports, result states */
.settings-list{display:grid;margin:22px 0;text-align:left;border-top:1px solid var(--line)}
.setting-row{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:12px;padding:15px 0;border-bottom:1px solid var(--line);cursor:pointer}
.setting-icon{width:38px;height:38px;display:grid;place-items:center;border-radius:var(--radius-sm);background:var(--panel-soft);color:var(--accent-strong)}
.setting-row span:nth-child(2){display:grid;gap:3px}.setting-row small{color:var(--glass-muted);font-size:.7rem;line-height:1.4}
/* Centang bawaan browser digambar PUTIH di atas accent-color. --sun gagal di situ
   (putih di atas kuning 1,4:1); tinta memberi 10:1+ tanpa menggambar apa pun. */
.setting-row input,.consent-row input{accent-color:var(--text);width:20px;height:20px}
.report-settings{margin:4px 0 18px;padding:18px;text-align:left;background:var(--surface-warm);border-radius:var(--radius-md)}.report-settings .row{align-items:start}.report-settings .row p{margin:3px 0 0}
.endpoint-label{display:grid;gap:7px;margin:16px 0 12px;font-size:.72rem;font-weight:700;color:var(--muted)}
/* Audit 04-005: tautan ini cuma setinggi 16px - jauh di bawah sasaran sentuh 44px.
   Padding vertikal 14px menaikkan kotak sentuhnya jadi 44px; margin negatif menelan
   pertumbuhannya supaya tata letak fold Lanjutan tidak bergeser satu piksel pun. */
a.setup-link{display:inline-flex;align-items:center;gap:8px;margin:0 -10px -14px;padding:14px 10px;color:var(--accent-strong);font-size:.74rem;font-weight:700;text-decoration:none}a.setup-link:hover{text-decoration:underline}a.setup-link svg{width:16px;height:16px}
button.setup-link{display:block;width:100%;margin:6px 0;padding:10px 14px;color:var(--accent-strong);font-size:.82rem;font-weight:700;text-decoration:none;background:transparent;border:none;box-shadow:none;border-radius:8px;cursor:pointer;text-align:center}button.setup-link:hover{text-decoration:underline;background:rgba(2,132,199,0.06)}
.endpoint-label input{width:100%;min-height:48px;padding:13px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--panel);font:inherit;color:var(--text)}
/* :focus-visible, bukan :focus - lihat alasan di .fiezel-field input. */
.endpoint-label input:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.consent-row{display:grid;grid-template-columns:auto 1fr;gap:10px;align-items:start;font-size:.72rem;line-height:1.5;color:var(--muted);cursor:pointer}
.report-state{font-size:.7rem!important;margin:13px 0 0!important;padding-top:11px;border-top:1px solid var(--line)}
.report-preview{text-align:left;display:grid;gap:0;margin:18px 0;padding:15px 18px;background:var(--surface-warm);border:1px solid var(--line);border-radius:var(--radius-md)}.report-preview p{margin:5px 0;font-size:.8rem}
.memory-tip,.ai-disclosure{display:flex;align-items:flex-start;gap:9px}.memory-tip svg,.ai-disclosure svg{width:17px;flex:0 0 auto;margin-top:2px;color:var(--accent-strong)}
.result-stage{padding-top:7vh}.result-card{max-width:620px;margin:0 auto}.result-icon{width:62px;height:62px;display:grid;place-items:center;margin:0 auto 15px;border-radius:var(--radius-md);color:#765824;background:#f4e7ca}.result-icon svg{width:29px;height:29px}

.welcome-icon{width:54px;height:54px;display:grid;place-items:center;margin:0 auto 16px;border-radius:var(--radius-md);background:var(--accent-soft);color:var(--accent-strong)}.welcome-icon svg{width:25px;height:25px}
.welcome-mark,.modal-mark{font-size:.65rem;letter-spacing:.16em;color:var(--accent-strong)}
/* Audit UX Bagian 5: warna panel diambil dari token, bukan dipaku. Nilai lamanya
   rgba(255,254,250,.98) - putih hangat - membuat SETIAP modal dan gerbang tetap terang
   di mode gelap, sehingga teksnya nyaris hilang. */
.welcome-panel,.modal-panel{width:min(520px,100%);border-color:var(--line);background:var(--panel);color:var(--text)}
.modal-panel{max-height:min(760px,88vh);overflow:auto}

.bottomnav{width:min(620px,calc(100% - 24px));padding:7px;border-color:rgba(223,221,214,.82);background:rgba(var(--surface-rgb),.88);color:var(--text)}
.nav{display:flex;flex-direction:column;gap:3px;min-height:54px}.nav svg{width:18px;height:18px}.nav.active{color:var(--text);background:var(--sun-soft)}
.topline button,.toolbar button,.flash-actions button,.quiz-topbar button{display:inline-flex;align-items:center;gap:7px}
.feedback{background:var(--panel);color:var(--text)}
/* Aksen kiri 4px dipasang lewat box-shadow inset, BUKAN border-left: border akan
   menggeser padding dan membuat teks banner melompat saat state berubah. */
.feedback.feedback-success{border-color:var(--line);box-shadow:inset 4px 0 0 var(--good)}
.feedback.feedback-error{border-color:#F5C6BC;box-shadow:inset 4px 0 0 #D9534F;background:#FFF5F2}
.feedback-title{display:flex;align-items:center;gap:9px;margin-bottom:6px}.feedback-title svg{width:21px;height:21px}.feedback-success .feedback-title{color:var(--good)}.feedback-error .feedback-title{color:#B23B2A}
.feedback-your-pick{margin:2px 0 6px;padding:8px 12px;border-radius:10px;background:rgba(217,83,52,.08);border-left:3px solid #D9534F;font-size:var(--fs-body,15px);line-height:1.5}.feedback-your-pick strong{color:#B23B2A;margin-right:4px}
/* m025-565 Stempel Ingatan: satu baris meta di bawah vonis. Netral dan kecil dengan sengaja;
   kekuatannya di kalimat, bukan di visual. Tanpa ikon, bar, atau animasi. */
.feedback-stamp{margin:-2px 0 8px;font-size:12px;line-height:1.45;font-weight:500;letter-spacing:.01em;color:var(--muted);font-variant-numeric:tabular-nums}
:lang(th) .feedback-stamp{font-size:13px;line-height:1.6;letter-spacing:normal}
.diff-word-wrong{display:inline-flex;align-items:center;justify-content:center;min-width:28px;color:#FF8A80;background:rgba(255,82,82,.22);border:1px solid rgba(255,82,82,.45);border-bottom:2.5px solid #FF5252;padding:2px 8px;margin:0 4px;border-radius:6px;font-weight:800;text-decoration:none;box-sizing:border-box}
.diff-word-correct{display:inline-flex;align-items:center;justify-content:center;min-width:28px;color:#69F0AE;background:rgba(0,230,118,.22);border:1px solid rgba(0,230,118,.45);border-bottom:2.5px solid #00E676;padding:2px 8px;margin:0 4px;border-radius:6px;font-weight:800;box-sizing:border-box}
.token-nudge-shake{animation:nudgeShake .45s cubic-bezier(.36,.07,.19,.97) both;border-color:#F59E0B!important;box-shadow:0 0 8px rgba(245,158,11,.45)!important}
@keyframes nudgeShake{10%,90%{transform:translate3d(-2px,0,0)}20%,80%{transform:translate3d(3px,0,0)}30%,50%,70%{transform:translate3d(-3px,0,0)}40%,60%{transform:translate3d(3px,0,0)}}
.token-submit-retry{background:#F59E0B!important;border-color:#D97706!important;color:#181826!important;font-weight:700!important}
.token-submit-retry svg{width:18px;height:18px;margin-right:6px}
.tried-tag{font-size:11px;font-weight:600;padding:2px 6px;border-radius:4px;background:rgba(255,255,255,.1);color:var(--muted,#94A3B8);margin-left:8px;vertical-align:middle}
.grammar-grid .card{display:grid;gap:10px}.lesson-card-foot{display:flex;align-items:center;justify-content:space-between;gap:12px}.lesson-card-foot>span{font-size:var(--fs-caption);color:var(--muted)}
.lesson-title{font-size:var(--fs-h1);margin:8px 0 10px}.grammar-lesson-card>p{line-height:1.7}
/* v6.1 (O4 §3): maks DUA dari {border, bayangan, bg tint} — panel inset cukup tint. */
.lesson-example{margin:var(--sp-5) 0;padding:var(--sp-4);border-radius:var(--radius-md);background:var(--surface-warm)}.lesson-example>span{font-size:var(--fs-caption);letter-spacing:.13em;text-transform:uppercase;color:var(--accent-strong);font-weight:700}.lesson-example h3{margin:7px 0 8px;font-size:1rem;line-height:1.5}.lesson-example p{margin:0;color:var(--muted);font-size:.82rem;line-height:1.55}
.practice-contract{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-5);margin:var(--sp-3) 0;padding:var(--sp-5);border-radius:var(--radius-lg);background:rgba(var(--surface-rgb),.9);color:var(--text);border:1px solid var(--line)}.practice-contract h3{margin:0 0 5px}.practice-contract p{margin:0;max-width:600px;color:var(--muted);font-size:.84rem;line-height:1.55}.practice-contract button{flex:0 0 auto;min-height:44px;border-radius:999px;padding:0 18px;font-weight:700}@media(max-width:560px){.practice-contract{flex-direction:column;align-items:stretch;gap:14px}.practice-contract button{width:100%;justify-content:center}}

@keyframes signalPulse{0%,100%{opacity:.7;transform:scale(.92)}50%{opacity:1;transform:scale(1.08)}}
.reduce-motion *{animation-duration:.001ms!important;animation-delay:0s!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
html:has(body.reduce-motion){scroll-behavior:auto!important}/* v30 2026-08-29: toggle in-app harus setara jalur OS \u2014 riseIn delay dinolkan + smooth-scroll dimatikan (html di luar jangkauan selektor ber-scope body). */

@media(min-width:900px){.topbar{padding-top:14px}.section-head{padding-top:22px}}
@media(max-width:860px){
  .launcher-shell{grid-template-columns:1fr;grid-template-rows:auto auto;min-height:0}.coach-preview{min-height:290px}
  .home-overview{grid-template-columns:1fr}.learning-launcher{grid-template-columns:1fr 1fr}
}
@media(max-width:640px){
  .app{padding:12px 14px calc(116px + env(safe-area-inset-bottom))}.topbar{margin:0 -2px 16px;padding:9px 2px}.brand-edition{display:none}.version{display:none}
  .icon-button{width:44px;height:44px}.launcher-shell{padding:24px 18px 30px;border-radius:var(--radius-lg);gap:24px}.celestial-status{width:100%;margin-left:17px;justify-content:flex-start}.launcher-copy h1{font-size:2.65rem}.launcher-copy h1.login-message{font-size:2.25rem}.launcher-lead{font-size:.88rem}.launcher-actions{display:grid}.launcher-actions button{width:100%}.launcher-trust{gap:10px}
  .coach-preview{padding:20px}.home-stats{grid-template-columns:1fr 1fr}.home-stats>div:nth-child(2){border-right:0}.home-stats>div:nth-child(-n+2){border-bottom:1px solid var(--line)}
  /* m025-98 (brief redesign 3.7). Hero diukur 966px di 375x812 - lebih tinggi dari satu
     layar penuh, untuk satu sapaan. Yang dipotong di sini RUANG dan pengulangan, bukan kata:
     brief 3.1 secara eksplisit mempertahankan gaya bahasa Gen Z dan emoji sebagai identitas
     suara FIEZEL, jadi tidak satu kalimat pun diformalkan atau dibuang.

     - Narasi langit ("Matahari mendekati tenggelam") disembunyikan di ponsel saja; teksnya
       tetap hidup di atribut title dan tetap tampil di layar lebar. Ia membuat baris meta
       membungkus jadi dua baris untuk keterangan yang tidak membantu keputusan belajar.
     - Baris "kelas 1 SMA · Semester 1 · Tahun Ajaran 2026/2027" adalah data administratif
       yang tidak pernah berubah; ia tidak menolong murid memutuskan apa pun hari itu.
     - Judul 2,65rem menghasilkan tiga baris setinggi 184px di layar 375px. Diturunkan
       secukupnya supaya tetap terbaca sebagai judul, bukan sebagai paragraf besar.
     - Brief 3.5: satu CTA primer per layar. Tombol kedua dijadikan gaya teks, bukan tombol
       penuh kedua yang bersaing dengan yang utama. */
  #celestialDetail{display:none}
  .learner-stage{display:none}
  .launcher-copy h1{font-size:1.95rem;line-height:1.06}
  .launcher-greeting{margin:20px 0 6px}
  .launcher-actions{gap:8px}
  .launcher-actions .ghost-dark{min-height:40px;padding:8px 12px;border:0;background:transparent;text-decoration:underline;text-underline-offset:3px}
  .mission-panel{align-items:flex-start}
  /* m025-98 (brief redesign 3.7, OWNER: "terlalu panjang untuk scroll sampai bawah").
     Enam kartu modul dulu diruntuhkan menjadi SATU kolom di ponsel. Diukur di 375x812:
     blok itu sendirian setinggi 976px - hampir 1,2 layar - padahal isi tiap kartu cuma tiga
     kata ("1.765 KATA / Vocabulary"). Satu kolom membuatnya terbaca sebagai daftar panjang,
     bukan sebagai pilihan. Dua kolom memotongnya jadi sekitar setengah tanpa menghilangkan
     satu pun informasi, dan itulah bentuk yang dipakai aplikasi sekelas Spotify/Duolingo.
     min-height diturunkan karena kartu dua kolom tidak perlu setinggi kartu selebar layar. */
  .learning-launcher{grid-template-columns:1fr 1fr;gap:10px}.launch-card{min-height:118px}
  .voice-setup-card{align-items:stretch;flex-direction:column}.voice-setup-actions{width:100%;display:grid;grid-template-columns:1fr}.voice-setup-card button{width:100%}
  .home-section-head{align-items:flex-start;flex-direction:column}.privacy-strip{align-items:flex-start;flex-direction:column}.privacy-strip>button{width:100%}
  .bottomnav{bottom:max(8px,env(safe-area-inset-bottom));width:calc(100% - 16px)}.nav{font-size:var(--fs-caption);padding:8px 2px}
  .welcome-panel,.modal-panel{padding:26px 20px;border-radius:var(--radius-lg)}.modal{padding:12px}.setting-row{grid-template-columns:auto 1fr auto}.practice-contract{align-items:stretch;flex-direction:column}.practice-contract button{width:100%}.lesson-card-foot{align-items:flex-start;flex-direction:column}.lesson-card-foot button{width:100%}
}

/* m025-30 neural voice rate control */
.neural-voice-choice input[type="range"]{width:100%;accent-color:var(--accent,#9B3A4A);height:28px}
.neural-voice-choice input[type="range"]:disabled{opacity:.5}

/* m025-32 Indonesian optional voice block */
.indonesian-voice-block{margin-top:14px;padding-top:14px;border-top:1px solid var(--line,#EFE7DE)}
.indonesian-voice-block p{margin:.35rem 0 0;color:var(--muted,#6E635C);line-height:1.5}

/* m025-33 FIEZEL Classroom */
.classroom-page{display:grid;gap:14px}
.classroom-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
.classroom-cat{display:grid;gap:4px;justify-items:start;text-align:left;padding:16px;border-radius:var(--radius-md);border:1px solid var(--line,#EFE7DE);background:var(--panel,#fff);color:var(--text,#2E2724);min-height:88px}
.classroom-cat small{color:var(--muted,#6E635C)}
.classroom-board{padding:18px;border-radius:var(--radius-md);background:var(--panel,#fff);color:var(--text,#2E2724);border:1px solid var(--line,#EFE7DE)}
.classroom-board h2{margin:.2rem 0 .5rem}
.classroom-formula{font:600 1.05rem/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;padding:10px 12px;border-radius:var(--radius-sm);background:var(--panel-soft,#f6eef0)}
.classroom-board ul{margin:.6rem 0 0;padding-left:1.1rem;line-height:1.6}
.classroom-subtitle-card{padding:16px;border-radius:var(--radius-md);background:var(--panel,#fff);color:var(--text,#2E2724);border:1px solid var(--line,#EFE7DE)}
.classroom-en{font-weight:600;line-height:1.5;margin:.3rem 0}
.classroom-id{color:var(--accent,#9B3A4A);font-weight:600;line-height:1.5;margin:.2rem 0;min-height:1.4em}
.classroom-options{display:grid;gap:9px}
.classroom-option{text-align:left;padding:14px;border-radius:var(--radius-sm);min-height:48px}
.classroom-option.is-correct{border-color:var(--good-bright);background:var(--good-soft)}
.classroom-option.is-wrong{border-color:var(--bad);background:var(--bad-soft)}
.classroom-actions{display:flex;flex-wrap:wrap;gap:9px}
.classroom-actions button{min-height:46px;padding:0 16px;border-radius:var(--radius-sm)}

/* m025-43 mandatory one-batch neural voice download — stays until it finishes */
.voice-bundle-sheet{position:fixed;inset:0;z-index:95;display:grid;place-items:center;padding:16px;background:linear-gradient(160deg,rgba(7,13,29,.95),rgba(45,37,86,.95));backdrop-filter:blur(10px)}
body.voice-bundle-locked{overflow:hidden}
body.voice-bundle-locked .bottomnav,body.voice-bundle-locked .app-header{pointer-events:none;opacity:.3}
.voice-bundle-panel{width:min(520px,100%);display:grid;gap:10px;padding:20px;border-radius:var(--radius-lg);background:var(--panel,#fff);color:var(--text,#2E2724);border:1px solid var(--line,#EFE7DE);box-shadow:var(--shadow-lg)}
.voice-bundle-mark{font:700 11px/1.4 -apple-system,system-ui,sans-serif;letter-spacing:.12em;color:var(--accent,#9B3A4A)}
.voice-bundle-panel h2{margin:0}
.voice-bundle-panel p{margin:0;color:var(--muted,#6E635C);line-height:1.55}
.voice-bundle-track{height:8px;border-radius:var(--radius-pill);background:var(--line-soft,var(--panel-soft));overflow:hidden}
.voice-bundle-track span{display:block;height:100%;width:0;border-radius:var(--radius-pill);background:var(--sun-deep);transition:width .3s ease}
.voice-bundle-progress{font-size:.92rem}
.voice-bundle-actions{display:flex;gap:9px;justify-content:flex-end;flex-wrap:wrap}
.voice-bundle-actions button{min-height:48px;padding:0 18px;border-radius:var(--radius-sm)}
.voice-bundle-pill{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(84px + env(safe-area-inset-bottom,0));z-index:60;padding:9px 16px;border-radius:var(--radius-pill);background:var(--panel,#fff);color:var(--text,#2E2724);border:1px solid var(--line,#EFE7DE);box-shadow:0 10px 30px rgba(7,13,29,.18);font:600 .86rem/1.3 -apple-system,system-ui,sans-serif}
@media (prefers-reduced-motion:reduce){.voice-bundle-track span{transition:none}}

/* m025-44 FIEZEL Library: shelf, reader, audiobook, tap-to-translate */
.library-page{display:grid;gap:14px}
.library-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:11px}
.library-card{display:grid;grid-template-columns:56px 1fr;gap:12px;align-items:start;text-align:left;padding:15px;border-radius:var(--radius-md);border:1px solid var(--line,#EFE7DE);background:var(--panel,#fff);color:var(--text,#2E2724);border-left:4px solid var(--book-accent,#9B3A4A)}
.library-cover{font-size:2rem;line-height:1}
.library-meta{display:grid;gap:3px}
.library-meta b{font-size:1.02rem}
.library-meta small{color:var(--muted,#6E635C)}
.library-meta em{color:var(--muted,#6E635C);font-style:normal;line-height:1.45}
.library-badge{justify-self:start;margin-top:3px;padding:2px 8px;border-radius:var(--radius-pill);background:var(--panel-soft,#f6eef0);color:var(--muted,#6E635C);font:600 10px/1.6 -apple-system,system-ui,sans-serif;letter-spacing:.04em}
/* --book-accent (aksen per buku dari JS) tetap dihormati; hanya fallback-nya pindah. */
.library-progress{display:block;height:5px;margin-top:7px;border-radius:var(--radius-pill);background:var(--line-soft,var(--panel-soft));overflow:hidden}
.library-progress span{display:block;height:100%;background:var(--book-accent,var(--sun-deep))}
.library-reader{padding-bottom:190px}
.library-reader-head{display:flex;gap:12px;align-items:flex-start}
.library-back{min-height:44px;padding:0 14px;border-radius:var(--radius-sm)}
.library-note{margin:0;padding:10px 12px;border-radius:var(--radius-sm);background:var(--panel-soft,#f6eef0);color:var(--muted,#6E635C);font-size:.88rem;line-height:1.5}
.library-text{display:grid;gap:2px}
.library-chapter{margin:16px 0 6px;font-size:1.05rem}
.library-sentence{display:block;width:100%;text-align:left;padding:7px 10px;border:none;border-radius:var(--radius-xs);background:transparent;color:var(--text,#2E2724);font:500 1.06rem/1.72 -apple-system,system-ui,sans-serif}
.library-sentence[data-active]{background:var(--panel-soft,#f6eef0);box-shadow:inset 3px 0 0 var(--accent,#9B3A4A)}
/* m025-45: the translation floats in the middle of the screen. The book stays visible
   behind it and a tap outside dismisses it - a reader, not a modal. */
.library-translation-layer{position:fixed;inset:0;z-index:78;display:grid;place-items:center;padding:20px;background:rgba(7,13,29,.28);backdrop-filter:blur(2px)}
.library-translation-card{width:min(460px,100%);display:grid;gap:7px;padding:18px 18px 14px;border-radius:var(--radius-lg);background:var(--panel,#fff);border:1px solid var(--line,#EFE7DE);box-shadow:var(--shadow-lg)}
.library-translation-mark{font:700 10px/1.4 -apple-system,system-ui,sans-serif;letter-spacing:.12em;color:var(--accent,#9B3A4A)}
.library-translation-en{margin:0;font-weight:600;line-height:1.5}
.library-translation-id{margin:0;color:var(--accent,#9B3A4A);font-weight:600;line-height:1.5}
.library-translation-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
#libraryCloseOne{margin-left:auto;width:44px;padding:0}
.library-translation-actions button{min-height:42px;padding:0 13px;border-radius:var(--radius-sm)}
.library-dock{position:fixed;left:0;right:0;bottom:calc(64px + env(safe-area-inset-bottom,0));z-index:40;display:grid;gap:7px;padding:11px 14px;background:var(--chrome-bg,rgba(250,247,247,.94));backdrop-filter:blur(12px);border-top:1px solid var(--line,#EFE7DE)}
.library-progress-line{height:5px;border-radius:var(--radius-pill);background:var(--line-soft,var(--panel-soft));overflow:hidden}
.library-progress-line span{display:block;height:100%;background:var(--sun-deep);transition:width .25s ease}
.library-status{margin:0;font-size:.84rem;color:var(--muted,#6E635C)}
.library-controls{display:flex;gap:8px;align-items:center}
.library-controls button{min-height:48px;padding:0 14px;border-radius:var(--radius-sm)}
.library-controls .primary{flex:1}
/* m028 fase4: tombol kecepatan duduk di baris status di KIRI, bukan di .library-controls.
   Terukur di 390x844: baris kontrol sudah penuh (mundur + Audiobook + maju + Tanya Fiezel
   selebar 281px) sehingga tombol kelima melipat; dan seluruh sudut kanan-bawah dok berada di
   lajur gelembung pembimbing (x316-374, y682-740) yang menelan pointer - Playwright menolak
   mengetuk tombol di sana. Pojok kiri baris status adalah satu-satunya tempat di dok yang
   bebas dari gelembung sekaligus tetap terlihat sambil menyimak.
   Lebarnya dipaku supaya siklus 0.75x -> 1x -> 1.25x tidak menggeser teks statusnya. */
.library-dock-line{display:flex;align-items:center;gap:8px}
.library-dock-line .library-status{flex:1;min-width:0}
.library-speed{flex:0 0 auto;min-width:62px;padding:0 12px;border-radius:var(--radius-sm);text-align:center;font-weight:700;font-variant-numeric:tabular-nums}
.library-ask-sheet{position:fixed;inset:0;z-index:80;display:grid;place-items:center;padding:16px;background:rgba(7,13,29,.5)}
.library-ask-panel{width:min(480px,100%);display:grid;gap:9px;padding:20px;border-radius:var(--radius-lg);background:var(--panel,#fff);color:var(--text,#2E2724)}
.library-ask-mark{font:700 11px/1.4 -apple-system,system-ui,sans-serif;letter-spacing:.12em;color:var(--accent,#9B3A4A)}
.library-ask-panel h2{margin:0}
.library-ask-quote{margin:0;padding:9px 11px;border-radius:var(--radius-sm);background:var(--panel-soft,#f6eef0);line-height:1.5}
.library-ask-panel textarea{width:100%;padding:11px;border-radius:var(--radius-sm);border:1px solid var(--line,#EFE7DE);font:inherit;resize:vertical}
.library-ask-actions{display:flex;gap:8px;justify-content:flex-end}
.library-ask-actions button{min-height:46px;padding:0 16px;border-radius:var(--radius-sm)}
.library-ask-answer{margin:0;line-height:1.55;color:var(--accent,#9B3A4A);font-weight:600}
.library-ask-answer:empty{display:none}
@media (max-width:620px){.library-sentence{font-size:1.02rem}}
@media (prefers-reduced-motion:reduce){.library-progress-line span{transition:none}}


/* ==========================================================================
   m025-46 — Liquid Glass surfaces
   Depth from blur and a hairline, never from boxes stacked on boxes. Hierarchy
   from the type ramp, never from capitals. Every hit target clears 44px.
   Pinned selectors elsewhere in this file are untouched on purpose.
   ========================================================================== */

.card,.launcher-shell,.coach-preview,.launch-card,.mission-panel,.home-stats>div{
  background:var(--glass-thick);
  border:.5px solid var(--glass-edge);
  color:var(--glass-text);
  box-shadow:0 1px 1px rgba(36,26,17,.03),0 8px 24px rgba(36,26,17,.07);
}
.card{border-radius:var(--radius-lg);padding:18px}
.card p.muted,.launch-card small,.coach-preview p{color:var(--glass-muted)}

/* Large title. This is what replaces the capitals the screens used to shout with. */
.section-head h1{font-size:var(--fs-display);line-height:1.18;font-weight:700;letter-spacing:-.6px;margin:0}
.section-head p{font-size:var(--fs-small);line-height:1.4;color:var(--ambient-muted);margin:.25rem 0 0}
.section-head{margin-bottom:18px}

/* One primary action per screen, and it is unmistakable.
   v6.1 (O4 §8, preseden F2-16): lapisan primary era-accent yang dulu di sini DIHAPUS —
   ia kalah kaskade dari resep chunky v6 (blok "1. Tombol chunky") dan tidak pernah
   ter-render; menyimpannya hanya memaksa fase berikutnya menebak mana yang hidup. */

.launcher-shell{border-radius:var(--radius-lg)}
.coach-preview{border-radius:var(--radius-lg)}
.launch-card{border-radius:var(--radius-md);min-height:84px}
/* v6.1 (O4 §5): pasangan px 15/13 dihapus — .launch-card b/small kini dari skala --fs. */

/* m025-98 (brief redesign 3.7): pembungkus expand/collapse untuk blok yang tidak perlu
   dibuka bersamaan. Dipakai di Home untuk peta kemampuan dan pemilih tujuan belajar.
   Target sentuhnya 44px penuh, dan panahnya berputar supaya keadaannya terbaca tanpa
   perlu membaca label. */
.home-fold{border:1px solid var(--glass-line);border-radius:var(--radius-md);background:var(--glass-thick);color:var(--glass-text);margin:12px 0 0;overflow:hidden}
.home-fold>summary{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:44px;padding:11px 16px;cursor:pointer;list-style:none;font-size:.82rem;font-weight:700;color:var(--glass-text)}
.home-fold>summary::-webkit-details-marker{display:none}
.home-fold>summary svg{width:17px;height:17px;flex:0 0 auto;color:var(--glass-muted);transition:transform .2s var(--ease)}
.home-fold[open]>summary svg{transform:rotate(180deg)}
.home-fold[open]>summary{border-bottom:1px solid var(--glass-line)}
.home-fold>.journey-skills,.home-fold>.journey-goal{margin:0;padding:14px 16px 16px;border:0;background:transparent}

/* m025-101 — tur pengenalan (coach marks). OWNER: "anggaplah ada user baru... ga ngerti cara
   pake, seharusnya ada tutorial seperti apps terkenal".

   Sorotannya dibuat dengan SATU box-shadow raksasa, bukan empat panel peredup: satu elemen,
   satu lapis cat, dan lubangnya selalu pas mengikuti kotak targetnya berapa pun ukurannya.
   Lubang itu pointer-events:none supaya ia tidak pernah menelan sentuhan - lapisan induknya
   yang menangkapnya, dan sentuhan di mana pun memajukan tur. */
/* Baris Pengaturan yang berupa AKSI, bukan sakelar. Bentuknya sengaja sama persis dengan
   .setting-row supaya daftarnya tetap terbaca satu irama, hanya penutupnya panah alih-alih
   kotak centang. m025-88 mencatat perkenalan tidak bisa diputar ulang sama sekali; ini
   jalannya. */
.setting-row-action{width:100%;text-align:left;border:0;background:transparent;font:inherit;cursor:pointer}
.setting-row-action>svg:last-child{width:17px;height:17px;color:var(--muted);justify-self:end}

.fz-tour{position:fixed;inset:0;z-index:2147481800;color:var(--glass-text,#fff)}
.fz-tour-hole{position:fixed;border-radius:var(--radius-md);pointer-events:none;
  box-shadow:0 0 0 9999px rgba(10,5,8,.78),0 0 0 2px rgba(255,255,255,.55) inset;
  transition:top .26s var(--ease,ease),left .26s var(--ease,ease),width .26s var(--ease,ease),height .26s var(--ease,ease)}
.fz-tour-card{position:fixed;left:16px;right:16px;padding:20px 20px 16px;border-radius:var(--radius-lg);
  background:var(--glass-solid,#fff);color:var(--text,#2E2724);box-shadow:0 24px 70px rgba(0,0,0,.34);
  animation:fz-tour-in .28s cubic-bezier(.22,.8,.28,1) both}
.fz-tour-card.is-top{top:max(22px,env(safe-area-inset-top))}
.fz-tour-card.is-bottom{bottom:calc(104px + env(safe-area-inset-bottom))}
@keyframes fz-tour-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.fz-tour-card h2{margin:8px 0 6px;font-size:1.12rem;line-height:1.25;letter-spacing:-.02em}
.fz-tour-card p{margin:0;font-size:.86rem;line-height:1.6;color:var(--muted,#6E635C)}
.fz-tour-dots{display:flex;gap:6px}
.fz-tour-dot{width:6px;height:6px;border-radius:50%;background:var(--line,#e9dfe1)}
.fz-tour-dot.is-active{background:var(--accent,#9B3A4A);width:18px;border-radius:3px}
.fz-tour-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:16px}
.fz-tour-skip{min-height:44px;padding:10px 14px;border:0;background:transparent;color:var(--muted,#6E635C);font:inherit;font-size:.82rem;font-weight:700;cursor:pointer}
.fz-tour-next{min-height:44px;padding:11px 22px;border:0;border-radius:var(--radius-sm);background:var(--accent,#9B3A4A);color:#fff;font:inherit;font-size:.86rem;font-weight:700;cursor:pointer}
/* Kurangi-gerak: sorotannya tetap ada, hanya perpindahannya yang tidak dianimasikan. */
.fz-tour-still .fz-tour-hole{transition:none}
.fz-tour-still .fz-tour-card{animation:none}

/* Tab bar mengapung sebagai satu kapsul.

   m025-93 (brief redesign Bab 2, bug kritis #2): OWNER melaporkan "bottom navigation bar
   menimpa konten saat scroll - teks/angka terpotong di belakang nav pill". Ini BUKAN soal
   padding: ruang bawah .app sudah 112px + safe-area, sementara pill hanya memakan 73px.
   Yang salah adalah pill-nya sendiri - diukur di peramban pada m025-91:

       background:      rgba(255, 255, 255, 0.74)
       backdrop-filter: none

   m025-81 mencabut backdrop-filter dari chrome demi baterai, tetapi TRANSPARANSINYA
   ditinggal. Token --glass-thick dirancang untuk kaca buram; tanpa blur ia hanya panel
   bening, jadi 26% dari apa pun yang lewat di bawahnya menembus ke atas dan angka yang
   sedang bergulir terbaca samar di balik pill.

   Blur TIDAK dikembalikan - keputusan baterai m025-81 tetap berlaku. Yang dipakai adalah
   pola yang sama dengan Spotify/Apple Music: konten diredupkan SEBELUM sampai ke tab bar
   lewat satu lapisan gradien statis (lihat .nav-scrim), dan pill-nya sendiri dibuat cukup
   pekat sehingga tidak pernah bisa dibaca tembus. Keduanya nol biaya render. */
.bottomnav{
  background:var(--glass-solid);
  border:.5px solid var(--glass-edge);border-radius:var(--radius-lg);padding:6px;
}
/* Peredup di dasar layar. pointer-events:none supaya ia tidak pernah menelan sentuhan, dan
   ia duduk DI BAWAH pill (z-index 39 lawan 40) supaya tab tetap tajam di atasnya. */
.nav-scrim{
  position:fixed;left:0;right:0;bottom:0;z-index:39;pointer-events:none;
  height:calc(96px + env(safe-area-inset-bottom));
  background:linear-gradient(to top,var(--bg) 34%,rgba(0,0,0,0));
}
@media (prefers-reduced-transparency:reduce){.nav-scrim{background:var(--bg)}}
.nav{min-height:44px;color:var(--glass-muted);border-radius:var(--radius-lg)}
.nav.active{color:var(--accent-on-glass);background:transparent;transform:none;font-weight:600}

/* Sheets sit on the heavier material, because they take the whole screen. */
.modal-panel,.welcome-panel{
  background:var(--glass-thick);
  -webkit-backdrop-filter:var(--glass-blur-heavy);backdrop-filter:var(--glass-blur-heavy);
  border:.5px solid var(--glass-edge);border-radius:var(--radius-lg);color:var(--glass-text);
  box-shadow:0 1px 2px rgba(36,26,17,.06),0 -8px 60px rgba(36,26,17,.18);
}

/* The sky is a clock, not wallpaper: it stays, but it stops competing with the text. */
.sky-light{opacity:.72}
.global-celestial{opacity:.9}

/* --------------------------------------------------------------------------
   m025-46 fix: text on glass must follow the material, not the light theme.
   The mission panel and the stat strip used to be near-opaque cream cards with
   dark type. Turning them into glass made them follow the sky, but their labels
   still came from the light-theme tokens, so at night they sank into their own
   background. Caught by rendering the page, not by any assertion.
   -------------------------------------------------------------------------- */
.card,.launcher-shell,.coach-preview,.launch-card,.mission-panel,.home-stats,.home-stats>div{color:var(--glass-text)}
.card h1,.card h2,.card h3,.card b,.card strong,
.mission-panel h3,.home-stats strong,.launch-card b{color:var(--glass-text)}
.card p.muted,.card .muted,.mission-panel p,.home-stats small,
.launch-card small,.coach-preview p,.coach-preview small{color:var(--glass-muted)}

/* Headings sitting straight on the sky take the ambient colour, which already
   tracks the phase - otherwise they are dark type on a dark sky after sunset. */
.section-head h1,.home-section-head h2,.home-section-head h3{color:var(--ambient-text)}
.section-head p{color:var(--ambient-muted)}

/* The stat labels were the last capitals left on Home. */
.home-stats small,.stats small{text-transform:none;letter-spacing:.01em;font-size:var(--fs-caption)}

/* R2 Personal Learning Journey. Memakai token yang sama dengan home-overview supaya panel ini
   terbaca sebagai bagian dari Home, bukan tempelan. */
.journey-week{color:var(--ambient-muted);font-size:.7rem;letter-spacing:.04em}
.journey-panel{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:14px}
.journey-mission,.journey-today,.journey-goal{padding:22px;border:1px solid var(--glass-line);border-radius:var(--radius-md);background:var(--glass-thick);color:var(--glass-text)}
.journey-mission small,.journey-today small,.journey-goal small{display:block;color:var(--glass-muted);font-size:.62rem;text-transform:uppercase;letter-spacing:.1em}
.journey-mission h3{margin:8px 0 6px;font-size:1.05rem;text-transform:capitalize}
.journey-target{margin:6px 0 0;font-size:.78rem;color:var(--glass-text)}
.journey-why,.journey-note{margin:8px 0 0;color:var(--glass-muted);font-size:.74rem;line-height:1.55}
.journey-blocks{list-style:none;margin:10px 0 0;padding:0;display:grid;gap:8px}
.journey-block{display:grid;gap:2px;padding:10px 12px;border:1px solid var(--glass-line);border-radius:var(--radius-sm)}
.journey-block b{font-size:.8rem}.journey-block span{color:var(--glass-muted);font-size:.72rem;line-height:1.5}
.journey-block-review{border-color:var(--accent-on-glass)}
.journey-recovery{margin:8px 0 0;font-size:.74rem;color:var(--accent-on-glass)}
.journey-today button{margin-top:12px;width:100%}
.journey-skills{display:grid;grid-template-columns:repeat(5,1fr);border:1px solid var(--glass-line);border-radius:var(--radius-md);background:var(--glass-thick);color:var(--glass-text);overflow:hidden;margin-bottom:14px}
.journey-skill{padding:16px 12px;border-right:1px solid var(--glass-line);display:grid;gap:6px}
.journey-skill:last-child{border-right:0}
.journey-skill b{font-size:.78rem}.journey-skill span{color:var(--muted);font-size:.72rem}
.journey-skill.is-unmeasured span{font-style:italic}
.journey-goal-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.journey-goal-chip{padding:8px 12px;border:1px solid var(--line);border-radius:var(--radius-pill);background:transparent;color:var(--text);font-size:var(--fs-caption);min-height:36px}
/* Chip terpilih = BIDANG kuning + tinta gelap, bukan garis+teks aksen: satu-satunya
   penanda "terpilih" sebelum ini adalah warna garis 1px - hampir tak terlihat. */
.journey-goal-chip.is-active{background:var(--sun);border-color:var(--sun-deep);color:var(--text);font-weight:600}
@media(max-width:760px){.journey-panel{grid-template-columns:1fr}.journey-skills{grid-template-columns:repeat(2,1fr)}.journey-skill{border-bottom:1px solid var(--line)}}
.journey-skill small{color:var(--muted);font-size:.66rem;letter-spacing:.01em}
.readiness-block{margin-bottom:14px}
.readiness-block h4{margin:0 0 8px;font-size:.86rem}
.readiness-met{color:var(--accent)}
.readiness-unknown,.readiness-not_met{color:var(--muted)}
.backup-settings .backup-actions{margin-top:10px}
.backup-settings #backupPreview:empty{display:none}


/* ========================================================================================
   FIEZEL brand: Percik + splash + onboarding
   Sumber warna dan tipografi: FIEZEL_Complete_Design_Specification.pdf, bagian 2 dan 15.
   Token di bawah SENGAJA dinamai --fz-* dan dilingkupi ke elemen `.fiezel-*` saja - ini
   BUKAN skema warna aplikasi (yang tetap --accent maroon dkk di :root atas). Menyamakan
   keduanya berarti mengecat ulang puluhan layar lain yang tidak diminta pada redesign ini;
   splash dan onboarding adalah lapisan tersendiri sehingga aman dilingkupi sendiri.
   ======================================================================================== */

@font-face{font-family:'FZ Instrument Serif';font-style:normal;font-weight:400;font-display:swap;
  src:url('./assets/fonts/InstrumentSerif-400.woff2') format('woff2')}
@font-face{font-family:'FZ Plus Jakarta Sans';font-style:normal;font-weight:400;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-400.woff2') format('woff2')}
@font-face{font-family:'FZ Plus Jakarta Sans';font-style:normal;font-weight:500;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-500.woff2') format('woff2')}
@font-face{font-family:'FZ Plus Jakarta Sans';font-style:normal;font-weight:600;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-600.woff2') format('woff2')}
@font-face{font-family:'FZ Plus Jakarta Sans';font-style:normal;font-weight:700;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-700.woff2') format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:400;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-400.woff2') format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:500;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-500.woff2') format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:600;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-600.woff2') format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:700;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-700.woff2') format('woff2')}
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:800;font-display:swap;
  src:url('./assets/fonts/PlusJakartaSans-700.woff2') format('woff2')}
/* m025-246: @font-face 'FZ Fredoka' DICABUT bersama keluarga fontnya (OWNER:
   "Tipografi: 3 -> 2 keluarga font (buang Fredoka)"). Tidak ada satu pun selektor yang
   masih menyebut nama keluarga itu - satu-satunya pemakainya adalah --fz-display-round,
   dan token itu sekarang menunjuk Jakarta. Deklarasi yang ditinggalkan di sini akan
   membuat peramban menyiapkan wajah yang tidak pernah dilukis; berkas woff2-nya ikut
   dicabut dari preload index.html dan dari precache sw.js. */

.fiezel-splash,.fiezel-ob{
  /* m028 "Warm Paper, Bright Mind". Peran token TIDAK berubah - hanya nilainya, plus
     empat token baru untuk peran yang dulu dipaksa dipikul --fz-accent sendirian:
     bidang aksi (--fz-sun-grad), bidang terpilih (--fz-sun-soft), tinta kecil di atas
     krem (--fz-info), dan panggung gelap (--fz-core). Kuning tetap warna BIDANG,
     tetapi arah "Lembut" menurunkannya dari kuning penuh ke #F7EACB: bidang di sini tidak
     lagi dibatasi oleh warnanya sendiri melainkan oleh bayangan, jadi kuning penuh
     kehilangan pekerjaannya dan hanya menyisakan kerasnya. Tinta tetap tidak pernah
     memakai kuning — peran itu dipegang --fz-gold #7A5512 (7,0:1 di atas krem).
     BLOK INI DISALIN APA ADANYA ke CSS kritis index.html; tests/splash-first-paint-test.js
     membandingkan keduanya baris demi baris, jadi setiap suntingan di sini harus
     diikuti suntingan yang sama persis di sana. */
  --fz-bg:#FBF7F3; --fz-paper:#FFFFFF; --fz-ink:#2E2724; --fz-ink-muted:#6E635C;
  --fz-accent:#9B3A4A; --fz-accent-deep:#7E2D3B; --fz-gold:#7A5512; --fz-soft:#F6E9EB;
  --fz-line:#EFE7DE;
  --fz-sun:#F7EACB; --fz-sun-soft:#FBF3E2; --fz-sun-press:#EFDFB8;
  --fz-sun-grad:linear-gradient(180deg,#F7EACB,#EFDFB8);
  --fz-info:#7A5512; --fz-core:#1B1418; --fz-core-soft:#2A2126; --fz-on-core:#FDFAF3;
  --fz-display:'FZ Plus Jakarta Sans',-apple-system,'Segoe UI',sans-serif;
  --fz-heading:'FZ Plus Jakarta Sans',-apple-system,'Segoe UI',sans-serif;
  --fz-body:'FZ Plus Jakarta Sans',-apple-system,'Segoe UI',sans-serif;
}


/* Star/Charm Twinkle (bagian 14): scale .85->1.08, rotate +-6deg, opacity .75->1, 2.2s. */
@keyframes fzm-twinkle{0%,100%{transform:scale(.85) rotate(-6deg);opacity:.75}50%{transform:scale(1.08) rotate(6deg);opacity:1}}
.fiezel-star{display:inline-block;animation:fzm-twinkle 2.2s ease-in-out infinite}

/* ---------- Lapisan penuh layar (splash dan onboarding) ----------
   Versi sebelumnya menaruh kartu kecil terapung di tengah layar kosong - OWNER menandainya
   "tidak penuh layar, terlalu kecil". Perbaikannya: latar krem menutupi SELURUH viewport,
   maskotnya besar di area atas, dan lembar konten (--fz-paper) menempel di tepi bawah layar
   selebar penuh dengan sudut atas membulat - pola "bottom sheet" yang dipakai onboarding
   mobile modern, dan CTA-nya selalu terjangkau ibu jari tanpa harus scroll ke tengah. */
.fiezel-splash,.fiezel-ob{
  position:fixed;inset:0;z-index:2147482000;display:flex;flex-direction:column;
  background:var(--fz-bg);font-family:var(--fz-body);color:var(--fz-ink);
  padding-top:max(18px,env(safe-area-inset-top));
  animation:fzm-page-in .4s cubic-bezier(.22,.61,.36,1) both;
}
/* m028: kepala onboarding kini bidang gelap yang menempel ke tepi atas, jadi padding
   aman-area dipindah KE DALAM band itu - kalau tidak, ada garis krem tipis di atas bidang
   gelap yang terbaca sebagai kesalahan render. Lapisannya juga boleh digulir: langkah
   pemilihan tujuan lebih tinggi dari 844px begitu enam chip level muncul, dan sebelum ini
   kelebihannya terpotong tanpa jalan keluar. */
.fiezel-ob{z-index:2147481900;padding-top:0;overflow-y:auto;overscroll-behavior:contain}
.fiezel-ob-reveal{padding-top:max(26px,calc(env(safe-area-inset-top) + 10px))}
.fiezel-splash[hidden]{display:none}
.fiezel-splash.is-leaving,.fiezel-ob.is-leaving{animation:fzm-page-out .3s ease-in both}
/* Page In/Out (bagian 14): fade + slide, 400ms masuk / 300ms keluar. */
@keyframes fzm-page-in{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}
@keyframes fzm-page-out{from{opacity:1;transform:none}to{opacity:0;transform:translateX(-16px)}}

.fiezel-topbar{display:flex;align-items:center;justify-content:space-between;
  padding:4px 16px;min-height:40px}

/* ---------- m028: reveal gelap di kepala onboarding ----------
   Splash tutup di panggung gelap, lalu aplikasi terang. Sebelum ini peralihannya adalah
   potongan keras: gelap penuh langsung jadi krem penuh. Band ini yang menjembatani -
   bidang core yang sama dengan splash, mengecil jadi kepala layar, membawa wordmark yang
   baru saja tersusun di splash. Ia dekorasi murni: tidak ada aksi di dalamnya. */
.fiezel-ob-reveal{
  position:relative;overflow:hidden;flex:0 0 auto;margin:-1px 0 0;
  background:radial-gradient(120% 130% at 50% 0%,var(--fz-core-soft) 0%,var(--fz-core) 62%);
  border-radius:0 0 var(--radius-lg) var(--radius-lg);
  padding:26px 20px 20px;text-align:center;color:var(--fz-on-core);
}
.fiezel-ob-reveal::before{
  content:"";position:absolute;left:50%;top:36%;width:min(70vw,300px);height:170px;
  transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(255,199,0,.26),rgba(255,199,0,0));
}
.fiezel-ob-reveal .fiezel-wordmark{position:relative;width:min(46vw,178px);margin:0 auto;display:block}
.fiezel-ob-word{position:relative;margin:0;font-family:var(--fz-heading);font-weight:700;
  font-size:1.8rem;letter-spacing:.02em;color:var(--fz-on-core)}
.fiezel-ob-tag{position:relative;margin:10px 0 0;font-size:var(--fs-caption);font-weight:700;
  letter-spacing:.32em;text-indent:.32em;text-transform:uppercase;color:var(--fz-sun)}

/* ---------- m028: stepper enam langkah ----------
   Perkenalan lama hanya memberi tahu di mana murid berada lewat titik-titik kecil di dalam
   carousel - dan hanya di satu langkah. Sekarang posisinya selalu terbaca: nomor langkah,
   nama langkah, dan enam segmen. Jumlah langkah dan urutannya TIDAK berubah. */
.fiezel-stepper{padding:16px 16px 4px;flex:0 0 auto}
.fiezel-stepper-eyebrow{display:block;font-size:var(--fs-caption);font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--fz-info)}
.fiezel-stepper-names{display:block;margin-top:3px;font-size:13px;font-weight:600;
  line-height:1.4;color:var(--fz-ink-muted)}
.fiezel-stepper-names b{color:var(--fz-ink);font-weight:700}
.fiezel-segments{display:grid;grid-template-columns:repeat(6,1fr);gap:5px;margin-top:10px}
.fiezel-segments i{height:6px;border-radius:var(--radius-pill);background:var(--fz-line)}
.fiezel-segments i.is-done{background:var(--fz-sun-grad)}
/* Back selalu ada dari langkah 1+, Skip selalu ada - keduanya ukuran sentuh penuh
   walau tampilannya ringan, karena ini SATU-SATUNYA jalan keluar dari lapisan penuh layar. */
.fiezel-back,.fiezel-skip{min-height:44px;min-width:44px;display:inline-flex;align-items:center;
  gap:4px;background:none;border:0;color:var(--fz-ink-muted);font-family:var(--fz-body);
  font-size:13px;font-weight:600;padding:0 6px}
.fiezel-topbar.is-bare{min-height:0;padding:0;height:6px}
.fiezel-back[hidden],.fiezel-skip[hidden]{visibility:hidden}
.fiezel-skip{text-decoration:underline;margin-left:auto}

.fiezel-stage{flex:0 0 auto;display:flex;flex-direction:column;align-items:stretch;
  min-height:0;padding:6px 16px 0;text-align:left}
/* m028-maskot: wajah 64px di SAMPING gelembung diganti maskot besar DI ATAS gelembung.
   Susunan kolom dipilih karena aritmetikanya: pada 390px lebar isi hanya 358px, dan
   maskot 132px + gelembung 270px tidak muat berdampingan tanpa memaksa gelembungnya
   menyusut jadi dua kata per baris. Menumpuknya juga yang menjaga aturan DIRECTION -
   maskot tidak pernah berada di atas kolom nama atau tombol, ia berada DI ATASNYA dalam
   aliran normal, tanpa position:absolute sama sekali. */
.fiezel-stage-art{display:flex;flex-direction:row;align-items:center;justify-content:center;
  gap:6px;min-height:0;width:100%}
.fiezel-stage-art img{max-height:38vh;width:auto}

/* ---------- m028-maskot: MASKOT PAW di kepala tiap panel perkenalan ----------
   Lambang Lucide di dalam kartu 64px (m025-80) dilepas: ia menunggu pustaka yang dimuat
   `defer` dan karena itu bisa lahir sebagai kotak kosong, dan sebuah lambang yang gagal
   tampil lebih buruk daripada tidak ada lambang. Penggantinya bukan gambar baru melainkan
   maskot yang SUDAH ada di produk (<fiezel-mascot>, features/mascot) - satu sumber bentuk,
   satu sistem gerak, kini juga di layar pertama yang dilihat murid.

   Ukurannya dijepit clamp: 132px pada 390px, 152px pada layar lebar. Keduanya di dalam
   rentang yang diminta (120-160px), dan tidak satu pun bergantung pada tinggi viewport -
   maskot yang tumbuh mengikuti vh adalah maskot yang menelan CTA di layar pendek. */
.fiezel-ob-mascot{
  /* Nilai bawaan bila JS tidak mengirimnya. Angka dari JS menjadi BATAS ATAS, bukan ukuran
     mati: pada 390px yang menang tetap 34vw (=132px), jadi satu angka tidak bisa membuat
     layar kecil kebanjiran maskot. */
  /* m025-241: perkenalan dibuat muat satu layar tanpa gulir. Maskot turun dari 132-148px
     ke ukuran kepala yang cukup untuk membawa gelembung sapaan di sampingnya. */
  --fz-ob-paw:104px;
  width:clamp(78px,23vw,var(--fz-ob-paw));
  aspect-ratio:320/300;
  flex:0 0 auto;
  display:grid;place-items:center;
  /* Tidak ada bidang, tidak ada cincin, tidak ada bayangan: maskotnya sendiri sudah
     membawa bayangan tanahnya di dalam SVG, dan piringan di belakangnya hanya membuat
     badan kuning duduk di atas kuning. */
  background:none;border:0;box-shadow:none;
  pointer-events:none;
}
/* Komponen memaku .fz-mascot ke 200px; di sini lebarnya milik wadah. Warna TIDAK
   disentuh - tidak satu pun fill/stroke maskot ditimpa dari berkas ini. */
.fiezel-ob-mascot .fiezel-ob-paw{width:100%;height:100%}
/* Micro-entrance saat langkah berganti: satu scale settle 240ms dengan pegas yang sama
   dipakai seluruh aplikasi. Sekali per langkah, bukan gerak yang berulang - maskot yang
   melompat tiap kali layar dicat ulang terbaca hiperaktif, bukan hidup. */
.fiezel-ob-mascot.is-entering{animation:fzm-ob-paw-in 240ms var(--ease-spring) both}
@keyframes fzm-ob-paw-in{
  from{transform:scale(.88) translateY(8px);opacity:.55}
  to{transform:none;opacity:1}
}
/* Fase 6 - serah terima ke gelembung pembimbing (spesifikasi 11 §2.3): saat perkenalan
   ditutup lewat "Mulai Belajar", PAW menyusut ke pusat dok gelembung. Transform + opacity
   SAJA - tanpa layout, tanpa rotasi - sasarannya dikirim JS lewat --fz-ob-hx/--fz-ob-hy
   (fiezel-onboarding.js beginHandoff). Opacity bertahan sampai ~68% jalan supaya yang
   terbaca adalah karakter PINDAH ke pojok, bukan lenyap di tempat. Kurangi-gerak tidak
   perlu aturan sendiri di sini: blok .fiezel-ob-still di bawah sudah mematikan SEMUA
   animasi maskot perkenalan, jadi jalur itu keluar lewat fade is-leaving saja. */
.fiezel-ob-mascot.is-handoff{
  /* Nilai bawaan arah pojok kanan-bawah; beginHandoff() menimpanya dengan sasaran piksel
     yang diukur dari dok gelembung sungguhan (gaya inline menang atas aturan kelas ini). */
  --fz-ob-hx:30vw;
  --fz-ob-hy:40vh;
  animation:fzm-ob-paw-handoff 320ms var(--ease) both;
  will-change:transform,opacity;
}
@keyframes fzm-ob-paw-handoff{
  0%{transform:none;opacity:1}
  68%{opacity:.9}
  100%{transform:translate(var(--fz-ob-hx,30vw),var(--fz-ob-hy,40vh)) scale(.2);opacity:0}
}
/* Kail rig untuk tunjukan lengan langkah 4 (is-pointing): hari ini cukup condong tipis ke
   arah CTA di bawahnya; rig Direction C boleh menimpanya dengan pose lengan sungguhan.
   Transform saja, dan ikut mati bersama animasi lain pada jalur kurangi-gerak. */
.fiezel-ob-mascot.is-pointing{transform:translateY(2px) scale(1.02);transition:transform .28s var(--ease)}
/* Cadangan bila custom element tidak terdaftar: ikon paw, tetap satu bentuk yang sama. */
.fiezel-ob-paw-fallback{display:grid;place-items:center;width:64%;height:64%;color:var(--fz-ink)}
.fiezel-ob-paw-fallback svg{width:100%;height:100%}

/* Lambang kecil di dalam kartu (SVG inline, tanpa pustaka - lihat GLYPHS di
   features/onboarding/fiezel-onboarding.js). */
.fiezel-glyph{width:20px;height:20px;flex:0 0 auto}
.fiezel-back .fiezel-glyph{width:18px;height:18px}
.fiezel-carousel-arrow .fiezel-glyph{width:22px;height:22px}
/* Gelembung sapaan. Kalimatnya berbeda tiap langkah, jadi murid tidak merasa sedang
   diwawancarai formulir - ada yang menemani. */
.fiezel-greet-bubble{
  position:relative;margin:0;background:var(--fz-paper);border:1.5px solid var(--fz-line);
  border-radius:var(--radius-md);
  /* Sudut yang "dipotong" pindah ke ATAS: gelembung sekarang duduk di bawah maskot, jadi
     ekornya harus menunjuk ke atas - ke wajah yang sedang bicara. */
  /* Gelembung sekarang duduk DI SAMPING kepala maskot, jadi ekornya menunjuk ke kiri. */
  border-bottom-left-radius:4px;
  padding:7px 10px;box-shadow:var(--shadow-sm);
  font-size:12.5px;font-weight:500;line-height:1.35;color:var(--fz-ink);max-width:190px;
  /* Gelembung ikut di tengah bersama maskot: pada layar lebar gelembung yang menempel ke
     tepi kiri sementara maskotnya di tengah terbaca seperti dua elemen yang tidak saling
     bicara. Teksnya tetap rata kiri karena ini kalimat, bukan judul. */
  align-self:center;text-align:left;
}
@media (max-height:700px){.fiezel-stepper{padding-top:10px}.fiezel-ob-reveal{padding:18px 20px 14px}}

/* m028: lembar bawah selebar layar diganti kartu. Bottom sheet dipilih dulu supaya CTA
   terjangkau ibu jari - itu masih benar, dan tetap dijaga: kartu ini yang terakhir dalam
   kolom, jadi tombolnya tetap duduk di bawah. Yang hilang cuma dua sudut yang menempel ke
   tepi layar, dan bersama itu kesan "dialog sistem" yang tidak pernah dimaksudkan. */
.fiezel-sheet{position:relative;flex:0 0 auto;width:auto;background:var(--fz-paper);
  border-radius:var(--radius-lg);
  border:1px solid var(--fz-line);
  box-shadow:var(--shadow-md);
  margin:10px 16px max(14px,env(safe-area-inset-bottom));
  padding:16px 18px 16px;
  display:flex;flex-direction:column;align-items:stretch;gap:8px;text-align:left}

.fiezel-badge{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;
  background:var(--fz-sun);color:var(--fz-ink);font-family:var(--fz-heading);font-weight:700;font-size:13px}
.fiezel-title{margin:0 0 2px;font-family:var(--fz-heading);font-weight:600;font-size:1.38rem;
  line-height:1.22;color:var(--fz-ink)}
.fiezel-body{margin:0;font-size:15px;line-height:1.55;color:var(--fz-ink-muted);max-width:24rem}
.fiezel-note{margin:0;font-size:13px;line-height:1.5;color:var(--fz-ink-muted);max-width:24rem}

/* Component Styling Guidelines (bagian 2): Primary/Secondary/Ghost. */
.fiezel-btn{min-height:44px;font-family:var(--fz-body);font-weight:700;font-size:16px;
  border-radius:var(--radius-md);padding:15px 20px;width:100%;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  transition:transform .12s ease-out,box-shadow .12s ease-out}
/* Aksi utama memakai bidang sun, bukan tinta: satu-satunya kuning penuh di layar adalah
   apa yang harus disentuh berikutnya. Tulisannya tinta di atas kuning (10,4:1) - bukan
   putih di atas kuning, yang cuma 1,9:1 dan itulah kesalahan paling sering pada tombol
   kuning di mana pun. */
.fiezel-btn-primary{background:var(--fz-sun-grad);color:var(--fz-ink);border:0;
  box-shadow:0 3px 0 var(--fz-sun-press),var(--shadow-sm)}
.fiezel-btn-primary:active{transform:translateY(2px);box-shadow:0 1px 0 var(--fz-sun-press)}
.fiezel-btn-secondary{background:var(--fz-ink);color:var(--fz-on-core);border:0;
  box-shadow:var(--shadow-sm)}
.fiezel-btn-secondary:active{transform:translateY(2px)}
.fiezel-btn-ghost{background:transparent;color:var(--fz-ink-muted);border:0;box-shadow:none;
  font-size:14px;font-weight:600;width:100%}
/* Nonaktif punya warnanya sendiri, bukan opacity .4 yang menyeret teks ke 2,3:1. Tombol
   yang belum bisa ditekan tetap harus BISA DIBACA - itu yang menjelaskan apa syaratnya. */
.fiezel-btn[disabled]{background:var(--fz-soft);color:var(--text-disabled);box-shadow:none;
  transform:none;pointer-events:none}

/* m025-117 Step 1: kolom nama murid. Tinggi sentuh 48px (di atas ambang 44px yang dijaga
   gate a11y), font 16px supaya iOS TIDAK memperbesar halaman saat kolom mendapat fokus -
   zoom itu menggeser seluruh lapisan perkenalan dan terbaca sebagai layar yang melompat. */
.fiezel-field{display:flex;flex-direction:column;align-items:flex-start;gap:8px;
  width:100%;text-align:left}
.fiezel-field>span{font-size:var(--fs-caption);letter-spacing:.09em;text-transform:uppercase;
  font-weight:700;color:var(--fz-info)}
.fiezel-field input{width:100%;min-height:52px;font-size:16px;font-weight:600;font-family:var(--fz-body);
  color:var(--fz-ink);background:var(--fz-bg);border:1.5px solid var(--fz-line);border-radius:var(--radius-md);
  padding:12px 16px;transition:border-color .14s ease-out,box-shadow .14s ease-out}
.fiezel-field input::placeholder{color:var(--fz-ink-muted);font-weight:500;opacity:1}
/* SATU aturan, dan HANYA :focus-visible. Sebelumnya ada aturan `:focus` telanjang kedua
   yang memasang garis --fz-gold emas tua plus cahaya kuning 3px - itulah "kotak kuning" yang
   muncul setiap kali murid MENGETUK kolom nama di ponsel. `:focus-visible` tidak menyala untuk
   ketukan atau fokus programatik, jadi indikatornya kembali ke tempat yang memang membutuhkannya:
   navigasi papan tik. */
.fiezel-field input:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
/* Step 1 tidak punya tombol "Lewati" (langkah wajib). Penahan ini menjaga tombol "Kembali"
   tetap di kolom kiri, supaya kepala layarnya tidak bergeser antar-langkah. */
.fiezel-skip-spacer{display:inline-block;min-width:44px;min-height:44px}

.fiezel-dots{display:flex;gap:6px;margin-top:2px}
.fiezel-dot{width:7px;height:7px;border-radius:50%;background:var(--fz-line)}
.fiezel-dot.is-active{background:var(--fz-sun-press)}

/* ---------- Splash (Step 0) ---------- */
.fiezel-splash-body{flex:1;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:14px;padding:24px;text-align:center}
.fiezel-splash-word{font-family:var(--fz-heading);font-weight:700;font-size:2.6rem;
  letter-spacing:.01em;color:var(--fz-accent);margin:0;display:flex;align-items:center;gap:8px}
.fiezel-splash-tag{font-family:var(--fz-body);font-size:.72rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--fz-ink-muted);margin:0}
.fiezel-splash-bubble{position:relative;max-width:20rem;background:#fff;border:1px solid var(--fz-line);
  border-radius:var(--radius-md);padding:12px 16px;color:var(--fz-ink);font-size:.86rem;line-height:1.5;
  box-shadow:0 4px 14px rgba(74,17,25,.12)}
.fiezel-splash-bubble::after{content:"";position:absolute;left:50%;bottom:-9px;width:16px;height:16px;
  transform:translateX(-50%) rotate(45deg);background:#fff;border-right:1px solid var(--fz-line);
  border-bottom:1px solid var(--fz-line)}

/* ==========================================================================
   Sapaan pembuka bermerek v4 (ruling OWNER 2026-08-28 / OA-6)
   Splash lama (F tumbuh + sheen emas) DIGANTI: logo kini TERBENTUK DARI AWAN
   PARTIKEL di kanvas (features/brand/fiezel-splash-particles.js), dua batang
   emas hidup sebagai EQUALIZER sinkron tabel ketukan, wordmark kecil naik di
   bawah, lalu CAP PAW menghentak otomatis sebagai transisi penutup
   (features/brand/fiezel-splash-pawstamp.js, CSS-nya disuntik modul itu).
   ATURAN blok ini:
   1. TANPA sheen/halo/glow (ruling OWNER) - seluruh lapisan kilau lama dihapus.
   2. Gerak utama digerakkan JS per-frame dari satu jam rAF (m025-86); CSS di
      sini hanya menata LETAK dan KEADAAN. @keyframes hanya untuk jalur
      kurangi-gerak (pudar-masuk pada ketukan yang sama).
   3. Hanya transform + opacity antar-frame; tanpa filter, tanpa blur.
   4. Palet TERKUNCI: medan #1B1418, emas #F0C241/#FFD94F, krem #FFF4DA.
   ========================================================================== */
.fiezel-splash-dark{background:#1B1418;padding-top:0}
.fiezel-splash-brand{
  background:radial-gradient(circle at 30% 18%,#2A2126 0%,#1B1418 55%,#120C0F 100%);
  position:relative;overflow:hidden;
  /* m025-91 OWNER: "tulisan fiezel itu diletakkan di bawah lagi seperti duolingo".
     Baris pertama menyerap seluruh sisa tinggi, jadi tanda terpusat di area atas-tengah;
     wordmark dan tagline menempel ke bawah lewat padding, bukan lewat angka mati - itu
     sebabnya susunannya tetap benar dari layar pendek sampai tablet. */
  display:grid;grid-template-rows:1fr auto auto;justify-items:center;align-items:center;
  gap:0;padding:24px 24px 17vh;
}
/* 1. Kanvas partikel - memenuhi bidang splash; bitmap-nya diukur particles.init. */
.fz-splash-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
/* 2. SVG logo tajam. Posisi awal dari grid (masih dipakai jalur statis);
      pada jalur gerak JS menimpanya dengan px persis (rumus identik
      particles.init: kotak 512 terpusat, 62% sisi terpendek) supaya SVG
      menumpuk piksel-persis di atas target partikel. Grup F & batang mulai
      tak terlihat; JS meng-crossfade-nya per timing partikel. */
.fiezel-logo{width:62vmin;height:auto;display:block;overflow:visible;transform:translateX(-0.5859375%)}
.fz-fgroup,.fz-barsgroup{opacity:0;will-change:opacity}
.fiezel-logo .fz-f,.fiezel-logo .fz-bar{transform-box:fill-box}
/* 3. Wordmark KECIL di bawah - ruang kosong yang lapang adalah bagian desain.
      Dipusatkan lewat margin auto (BUKAN transform): jalur statis memakai
      transform:none, dan JS jalur gerak hanya menambah translateY. */
.fiezel-splash-brand .fiezel-splash-word{
  /* Aturan dasar .fiezel-splash-word adalah flex-baris; di splash brand wordmark
     dan tagline harus BERTUMPUK - display:block mengembalikannya. */
  position:absolute;display:block;left:0;right:0;margin:0 auto;
  bottom:calc(7vh + env(safe-area-inset-bottom,0px));
  width:min(52vw,238px);text-align:center;opacity:0;
  transform:translateY(14px);will-change:transform,opacity;pointer-events:none;
}
.fiezel-splash-brand .fiezel-wordmark{display:block;width:min(30vw,132px);height:auto;margin:0 auto}
.fiezel-splash-brand .fiezel-splash-tag{
  font-family:var(--fz-body);font-size:12px;letter-spacing:.30em;
  text-transform:uppercase;color:#FFD94F;margin:14px 0 0;white-space:nowrap;
}
.fiezel-splash-brand .fiezel-splash-kelasku{margin-top:13px;display:flex;align-items:center;justify-content:center}
.fiezel-splash-brand .kelasku-brand{display:inline-flex;align-items:baseline;justify-content:center;gap:6px;white-space:nowrap}
.fiezel-splash-brand .kelasku-wordmark{font-family:var(--fz-heading,'Plus Jakarta Sans',sans-serif) !important;font-weight:800;font-size:16px;letter-spacing:.02em;color:#34D399 !important;line-height:1;display:inline-block;animation:fz-kelasku-reveal .75s cubic-bezier(.16,1,.3,1) 1.4s both}
.fiezel-splash-brand .kelasku-tag{font-family:var(--fz-body,'Plus Jakarta Sans',sans-serif);font-size:10.5px;font-weight:600;letter-spacing:.04em;color:rgba(253,250,243,.65);line-height:1;display:inline-block;animation:fz-tag-reveal .65s cubic-bezier(.16,1,.3,1) 1.52s both}
@keyframes fz-kelasku-reveal{from{opacity:0;transform:translateY(8px);filter:blur(4px)}to{opacity:1;transform:none;filter:none}}
@keyframes fz-tag-reveal{from{opacity:0;transform:translateY(4px)}to{opacity:.65;transform:none}}
/* Kurangi-gerak: lebih sedikit GERAKAN, bukan lebih sedikit pengalaman.
   Partikel dan hentakan dibuang; yang tersisa muncul dengan MEMUDAR pada
   KETUKAN YANG SAMA (--fz-b* dari fiezel-choreography.js) dan durasi yang
   sama dengan ketukannya - susunannya tetap terbaca, tanpa satu piksel pun
   yang bergerak. Cap PAW memakai jalur reduced modul pawstamp sendiri. */
@keyframes fz-fade-in{from{opacity:0}to{opacity:1}}
.fiezel-splash-still .fz-splash-canvas{display:none}
.fiezel-splash-still .fz-fgroup,.fiezel-splash-still .fz-barsgroup{opacity:1}
.fiezel-splash-still .fiezel-logo .fz-f{
  transform:none!important;animation:fz-fade-in .95s ease var(--fz-b1,0ms) both}
.fiezel-splash-still .fiezel-logo .fz-bar{
  transform:none!important;animation:fz-fade-in .3s ease var(--fz-b6,1060ms) both}
.fiezel-splash-still .fiezel-splash-word{
  transform:none!important;animation:fz-fade-in .3s ease var(--fz-b7,1150ms) both}
.fiezel-splash-still .fiezel-splash-tag{
  transform:none!important;animation:fz-fade-in .24s ease var(--fz-b12,1900ms) both;opacity:0}
.fiezel-splash-still .fiezel-splash-kelasku{transform:none!important;animation:fz-fade-in .24s ease var(--fz-b12,1900ms) both;opacity:0}
.fiezel-splash-still .kelasku-wordmark,.fiezel-splash-still .kelasku-tag{animation:none!important;transform:none!important;filter:none!important}
@keyframes fz-splash-fade-out{from{opacity:1}to{opacity:0}}

/* ---------- Feature Carousel (Step 1) ---------- */
.fiezel-carousel-track{display:flex;flex-direction:column;gap:8px;width:100%;text-align:left}
.fiezel-carousel-item{display:flex;align-items:center;gap:10px;background:var(--fz-bg);
  border:1px solid var(--fz-line);border-radius:var(--radius-sm);padding:11px 13px;font-size:14px;font-weight:600}
.fiezel-carousel-item i,.fiezel-carousel-item .fiezel-glyph{flex:0 0 auto;color:var(--fz-gold)}
.fiezel-carousel-arrows{display:flex;align-items:center;gap:14px;justify-content:center}
/* padding:0 + width tetap: tanpa itu padding 13px/18px dari aturan `button` dasar membuat
   tombol "bulat" ini melebar jadi lonjong, dan border-radius:50% mengikuti bentuk kotaknya. */
.fiezel-carousel-arrow{width:44px;height:44px;min-height:44px;min-width:44px;padding:0;
  border-radius:50%;background:var(--fz-sun-soft);
  color:var(--fz-ink);border:1.5px solid var(--fz-line);display:grid;place-items:center}
.fiezel-carousel-arrow[disabled]{background:var(--fz-bg);color:#75654C;opacity:1}

/* ---------- Goal Selection (Step 2) ---------- */
/* m025-242: dua kolom - enam tujuan dalam satu kolom adalah alasan utama langkah ini
   harus digulir. Kartunya kini hanya membawa labelnya. */
.fiezel-goal-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px;width:100%}
/* Pilihan peran (Murid / Guru) di langkah nama onboarding. */
.fiezel-role-label{margin:10px 0 6px;font-size:.82rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--fz-ink-muted,var(--muted))}
.fiezel-role-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px;width:100%;margin-bottom:8px}
.fiezel-role-card{min-height:64px}
.fiezel-classcode-field input{letter-spacing:.18em;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase}
.fiezel-classcode-field[hidden]{display:none}
.fiezel-role-card span{font-size:.8rem;line-height:1.4}
@media (max-width:420px){.fiezel-role-grid{grid-template-columns:1fr}}
/* Card Selection (bagian 14): border->gold, bg->soft, scale 1->1.035->1, 300-400ms. */
/* align-items dipaksa flex-start: aturan dasar `button{display:inline-flex;align-items:center}`
   di kepala berkas ini menang atas text-align, jadi tanpa baris ini judul dan penjelasan
   kartu tujuan tetap rata tengah walau kartunya jelas-jelas daftar pilihan. */
.fiezel-goal-card{display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start;
  gap:3px;text-align:left;width:100%;min-height:48px;justify-content:center;
  border:1.5px solid var(--fz-line);border-radius:var(--radius-sm);padding:10px 12px;background:var(--fz-paper);
  transition:transform .32s cubic-bezier(.34,1.56,.64,1),border-color .3s,background .3s}
.fiezel-goal-card b{font-family:var(--fz-heading);font-weight:700;font-size:14px;color:var(--fz-ink)}
.fiezel-goal-card span{font-size:13px;color:var(--fz-ink-muted);line-height:1.45}
/* Keadaan terpilih tetap ditandai DUA hal - garis DAN bidang - supaya ia tetap terbaca
   oleh mata yang tidak membedakan warnanya dari krem. Arah "Lembut" hanya menukar
   warnanya (tinta -> aksen maroon, kuning lembut -> merah lembut); jumlah isyaratnya
   TIDAK dikurangi, karena yang menopang keterbacaannya adalah kedua isyarat itu
   bersama-sama, bukan warnanya. */
.fiezel-goal-card.is-selected{border:2px solid var(--fz-accent);background:var(--fz-soft);
  transform:scale(1.02)}
/* Popup pra-onboarding: dua autonym harus terbaca sebagai pilihan utama, bukan kartu tujuan.
   Layout dua kolom hanya dipakai saat cukup lebar; di ponsel sempit tetap satu kolom dengan
   target sentuh penuh. Bendera dekoratif, nama bahasa membawa makna aksesibelnya. */
.fiezel-language-sheet{margin-top:auto;margin-bottom:auto}
.fiezel-language-kicker{font-size:var(--fs-caption);font-weight:700;letter-spacing:.08em;
  color:var(--fz-info)}
.fiezel-language-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.fiezel-language-choice{min-height:88px;display:grid;grid-template-columns:auto 1fr;
  align-items:center;justify-content:stretch;gap:12px}
.fiezel-goal-card .fiezel-language-flag{font-size:30px;line-height:1}
.fiezel-language-copy{display:flex;flex-direction:column;gap:3px;text-align:left}
.fiezel-language-copy small{font-size:12px;color:var(--fz-ink-muted)}
@media (max-width:340px){.fiezel-language-grid{grid-template-columns:1fr}}
/* "Sudah punya akun?" di layar pemilih bahasa. SENGAJA sekunder: pemisah tipis,
   naskah kecil, tanpa warna aksi — mayoritas yang membuka layar ini murid baru yang
   memang harus memilih bahasa, dan tombol masuk yang menonjol akan membuat mereka
   ragu pada langkah pertama. */
.fiezel-language-signin{margin-top:18px;display:flex;flex-direction:column;
  align-items:center;gap:8px}
.fiezel-language-sep{display:flex;align-items:center;gap:10px;width:100%;
  font-size:var(--fs-caption);color:var(--fz-ink-muted)}
.fiezel-language-sep::before,.fiezel-language-sep::after{content:'';flex:1;height:1px;
  background:var(--fz-line)}
.fiezel-language-signin-note{margin:0;text-align:center;font-size:12px;line-height:1.5;
  color:var(--fz-ink-muted);max-width:38ch}
/* Tinggi minimum supaya isi layar tidak melompat saat tombol Google akhirnya tiba. */
.fiezel-language-google{min-height:44px;display:flex;justify-content:center;
  align-items:center}
.fiezel-level-row{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-start;width:100%}
.fiezel-level-chip{min-height:44px;padding:0 16px;border-radius:var(--radius-pill);border:1.5px solid var(--fz-line);
  background:var(--fz-paper);color:var(--fz-ink);font-family:var(--fz-body);font-weight:700;font-size:13px}
.fiezel-level-chip.is-selected{border:1.5px solid var(--fz-accent);background:var(--fz-accent);color:#FFFFFF}

/* ---------- Summary (Step 5) ---------- */
.fiezel-summary-card{width:100%;background:var(--fz-bg);border:1px solid var(--fz-line);
  border-radius:var(--radius-sm);padding:14px;display:flex;flex-direction:column;gap:8px;text-align:left}
.fiezel-summary-row{display:flex;justify-content:space-between;gap:10px;font-size:14px}
.fiezel-summary-row b{color:var(--fz-ink)}
.fiezel-summary-row span{color:var(--fz-ink-muted);text-align:right}

/* Confetti kecil, CSS murni, berhenti di bawah kurangi-gerak lewat blok global di atas. */
.fiezel-confetti{position:absolute;inset:0;pointer-events:none;overflow:hidden;border-radius:inherit}
.fiezel-confetti i{position:absolute;top:-10px;width:6px;height:6px;border-radius:1px;
  background:var(--fz-sun);animation:fzm-confetti 1.6s ease-in both}
.fiezel-confetti i:nth-child(2n){background:var(--fz-gold)}
.fiezel-confetti i:nth-child(3n){background:var(--fz-paper);border:1px solid var(--fz-gold)}
@keyframes fzm-confetti{to{transform:translateY(120px) rotate(220deg);opacity:0}}

/* ---------- Kurangi-gerak: splash dan onboarding tunduk pada blok global juga,
   ditambah override lokal untuk memastikan lambaian/kedip-setara berhenti total. ---------- */
.fiezel-splash-still .fiezel-star,.fiezel-ob-still .fiezel-star{animation:none}
/* m028-maskot: kurangi-gerak berarti maskot tampil sebagai POSE STATIS dari state yang
   SAMA - bukan maskot yang hilang, dan bukan maskot yang tetap bernapas. Kelas st-<state>
   yang menentukan pose sudah dipasang di markup, jadi mematikan animasinya tidak mengubah
   arti satu langkah pun. Dua jalan masuk dijaga sekaligus: preferensi sistem (lapisan
   dapat .fiezel-ob-still dari JS) dan preferensi aplikasi (.reduce-motion di <body>). */
.fiezel-ob-still .fiezel-ob-mascot,
.fiezel-ob-still .fiezel-ob-mascot *,
body.reduce-motion .fiezel-ob-mascot,
body.reduce-motion .fiezel-ob-mascot *{animation:none!important;transition:none!important}
@media (prefers-reduced-motion:reduce){
  .fiezel-ob-mascot,.fiezel-ob-mascot *{animation:none!important;transition:none!important}
}

/* ========== SKELETON LOADING STATES (Polished, Premium Feel) ========== */
/* Shimmer animation: Creates the premium "loading" feel like Spotify/Duolingo */
/* i15 2026-08-29 (audit 12-005): keyframe ini dulu bernama `shimmer` dan bertabrakan global
   dengan @keyframes shimmer milik tutor-v3.css (dimuat belakangan, jadi menang di mana-mana;
   varian persen-nya no-op untuk .skeleton yang mengandalkan background-size 1000px).
   Di-namespace jadi fzSkeletonShimmer di sisi style.css — tutor-v3.css tak disentuh. */
@keyframes fzSkeletonShimmer {
  0% { background-position: -1000px 0; }
  100% { background-position: 1000px 0; }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

.skeleton {
  /* Kilaunya dulu panel<->panel-soft: dua bidang yang hampir sama, di ATAS panel.
     Skeleton yang tidak terlihat berkedip sama dengan tidak ada skeleton. */
  background: linear-gradient(90deg, var(--line-soft) 25%, var(--panel-soft) 50%, var(--line-soft) 75%);
  background-size: 1000px 100%;
  animation: fzSkeletonShimmer 2s infinite;
  border-radius: var(--radius-md);
  height: 16px;
}

/* Skeleton card (useful for lists/grids) */
.skeleton-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 20px;
  margin-bottom: 12px;
}

.skeleton-card .skeleton { margin-bottom: 12px; }
.skeleton-card .skeleton:last-child { margin-bottom: 0; }

/* Skeleton variants for different sizes */
.skeleton-text { height: 16px; }
.skeleton-title { height: 24px; margin-bottom: 8px; }
.skeleton-subtitle { height: 14px; width: 60%; margin-bottom: 16px; }
.skeleton-avatar { width: 48px; height: 48px; border-radius: 50%; display: inline-block; }
.skeleton-line { height: 12px; margin-bottom: 8px; }
.skeleton-line:last-child { margin-bottom: 0; }

/* Skeleton grid (for grid layouts) */
.skeleton-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

.skeleton-grid .skeleton-card {
  padding: 16px;
  margin-bottom: 0;
}

/* Loading state wrapper */
.loading-state {
  opacity: 0.7;
  pointer-events: none;
}

/* Prevent FOUC (Flash Of Unstyled Content) */
[data-loading="true"] { visibility: hidden; }
[data-loading="false"] { visibility: visible; }

/* ========== EMPTY STATES (Friendly, Encouraging) ========== */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 20px;
  text-align: center;
  min-height: 300px;
  /* Garis PUTUS-PUTUS: satu-satunya penanda bahwa yang kosong itu memang tempat
     yang belum terisi, bukan kartu yang gagal dimuat. */
  background: var(--panel-soft);
  border-radius: var(--radius-lg);
  border: 1.5px dashed var(--line);
  margin: 20px 0;
}

.empty-state-icon {
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  margin-bottom: 16px;
  font-size: 2.5rem;
}

.empty-state-icon svg {
  width: 100%;
  height: 100%;
  color: var(--accent-soft);
  opacity: 0.8;
}

.empty-state h2 {
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--text);
  margin: 0 0 8px;
  letter-spacing: -0.02em;
}

.empty-state p {
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.6;
  margin: 0 0 20px;
  max-width: 280px;
}

.empty-state .primary {
  margin-top: 8px;
}

/* Variant: minimal empty state (for small containers) */
.empty-state-minimal {
  padding: 24px 16px;
  min-height: auto;
  background: transparent;
  border: 1px dashed var(--line-soft);
}

.empty-state-minimal h2 {
  font-size: 1.1rem;
  margin-bottom: 4px;
}

.empty-state-minimal p {
  font-size: 0.8rem;
}

/* Variant: inline empty message (for grid cells) */
.empty-inline {
  padding: 12px;
  color: var(--muted);
  font-size: 0.8rem;
  text-align: center;
  background: var(--panel-soft);
  border-radius: var(--radius-md);
}

/* Progress indicator during load */
.loading-progress {
  height: 2px;
  background: var(--line-soft);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 12px;
}

.loading-progress::after {
  content: "";
  display: block;
  height: 100%;
  width: 30%;
  background: linear-gradient(90deg, transparent, var(--sun), transparent);
  animation: fzSkeletonShimmer 1.5s infinite;
}

/* ========== MICRO-ANIMATIONS FOR TRANSITIONS & INTERACTIONS ========== */
/* Page view transitions.
   m025-487 — CROSS-FADE YANG SALING MENUTUPI, BUKAN DUA ANIMASI TERPISAH.
   Sebelum ini `old` memakai `pageOut` dan `new` memakai `pageIn` — dua kurva easing
   yang BERBEDA, jadi di tengah transisi snapshot lama sudah hampir habis sementara
   snapshot baru baru mulai muncul. Terukur di Chromium (tools/dev/fiezel-vt-audit.js):
   cakupan layar jatuh ke 0.752 — seperempat layar meredup setiap pindah tab, dan murid
   membacanya sebagai "berkedip seperti me-refresh halaman".
   Sekarang keduanya LINEAR pada `--dur-l` yang sama: old 1->0 dan new 0->1 pada laju
   yang sama persis, sehingga jumlah opacity keduanya KONSTAN 1 di sepanjang transisi —
   nol kedipan, dan tetap satu bahasa masuk-layar. (.fade di dalam #app digerbangi lewat
   `.is-repaint` ketika View Transition yang mengurusnya; lihat vtViewPaint di app.js.) */
/* Isolasi app-shell (topbar & bottomnav) agar TIDAK ikut berkedip atau cross-fade saat pindah tab */
.topbar {
  view-transition-name: topbar;
}
.bottomnav {
  view-transition-name: bottomnav;
}
::view-transition-old(topbar),
::view-transition-new(topbar),
::view-transition-old(bottomnav),
::view-transition-new(bottomnav) {
  animation: none;
  mix-blend-mode: normal;
}

::view-transition-old(root) {
  animation: vtFadeOut 0.14s cubic-bezier(0.4, 0, 1, 1) forwards;
}

::view-transition-new(root) {
  animation: vtFadeIn 0.18s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes pageOut {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes vtFadeOut { from { opacity: 1; } to { opacity: 0; } }
@keyframes vtFadeIn { from { opacity: 0; } to { opacity: 1; } }

/* [TOMBSTONE i15 2026-08-29, audit 12-003] @keyframes pageIn kedua (opacity-saja) DIHAPUS.
   Nama keyframe itu global; definisi belakangan menang, jadi kembar ini diam-diam MEMATIKAN
   animasi masuk-layar yang dirancang (rise+fade) untuk 15 layar .fade. Kini hanya ada SATU
   pageIn (rise+fade, dekat .fade di atas) dan ::view-transition-new memakainya juga —
   satu bahasa masuk-layar. Reduced-motion: pseudo ::view-transition tidak kena selector `*`
   global, jadi digerbangi eksplisit di bawah. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root),
  ::view-transition-old(topbar), ::view-transition-new(topbar),
  ::view-transition-old(bottomnav), ::view-transition-new(bottomnav) { animation: none; }
}

/* Card entrance animation */
@keyframes cardSlideIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.card.animate-in {
  animation: cardSlideIn 0.35s var(--ease) both;
}

/* Staggered card animations */
.cards-container .card:nth-child(1) { animation-delay: 0.05s; }
.cards-container .card:nth-child(2) { animation-delay: 0.1s; }
.cards-container .card:nth-child(3) { animation-delay: 0.15s; }
.cards-container .card:nth-child(n+4) { animation-delay: 0.2s; }

/* Modal/Dialog entrance */
@keyframes modalAppear {
  from {
    opacity: 0;
    transform: translateY(20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.modal {
  animation: modalAppear 0.3s var(--ease-spring) both;
}

/* Button press animation (tactile feedback) */
@keyframes buttonPress {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(0.97); }
}

button:active:not(.nav):not(:disabled) {
  transform: scale(0.975);
  transition: transform 0.08s ease-out;
}

/* Fade in for content reveal */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.content-reveal {
  animation: fadeIn 0.35s var(--ease);
}

/* Bounce for success states */
@keyframes successBounce {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

.success-state {
  animation: successBounce 0.4s var(--ease-spring);
}

/* Shake for error states */
@keyframes errorShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

.error-state {
  animation: errorShake 0.3s ease;
}

/* Respects prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* m025-92 subtitle Indonesia di bawah suara Inggris.
   Setelah suara Indonesia dihapus, baris ini adalah satu-satunya jalur pemahaman
   bahasa ibu, jadi keterbacaannya diperlakukan sebagai isi - bukan hiasan: latar
   pekat sendiri supaya kontras tidak bergantung pada apa pun yang ada di belakangnya,
   dan lebar dibatasi supaya matanya tidak menyeberangi layar tiap baris. */
.fiezel-subtitle{
  display:none !important;
  position:fixed;
  left:50%;
  transform:translateX(-50%);
  /* Di atas bilah navigasi bawah, dan menghormati area aman iOS. */
  bottom:calc(88px + env(safe-area-inset-bottom,0px));
  z-index:70;
  max-width:min(680px,calc(100vw - 32px));
  padding:10px 16px;
  border-radius:var(--radius-sm);
  background:rgba(20,16,18,.88);
  color:#fdf6f5;
  font-size:clamp(15px,4vw,18px);
  line-height:1.45;
  text-align:center;
  text-wrap:balance;
  pointer-events:none;
  box-shadow:0 6px 24px rgba(0,0,0,.28);
}
.fiezel-subtitle[hidden]{display:none}

/* Pergantian baris dihaluskan, tetapi hanya bagi yang tidak meminta gerak dikurangi. */
@media (prefers-reduced-motion:no-preference){
  .fiezel-subtitle{transition:opacity .18s ease}
}


/* m025-106 Tanya FIEZEL.

   Token di sini WAJIB token yang benar-benar ada di berkas ini. m025-105 memakai
   var(--card,#fff) - dan --card tidak pernah ada, jadi nilainya selalu jatuh ke putih
   keras sementara warna teksnya ikut halaman. Di mode gelap hasilnya teks terang di atas
   putih: kotaknya terlihat, ketikannya tidak. Yang benar adalah --panel dan --text, sama
   seperti .endpoint-label input yang sudah lama dipakai. */
.fiezel-ask-mark{height:18px;width:auto;display:block}

/* Tombolnya menumpuk tanda dan label, jadi ia tidak lagi sebangun dengan icon-button
   lain di topbar dan ukurannya diatur sendiri. */
.ask-button{display:flex;flex-direction:column;align-items:center;gap:2px;line-height:1;
  padding:4px 6px;height:auto;width:auto}
/* m025-107: OWNER melaporkan labelnya terlalu besar. Ukurannya sudah 9px, jadi yang
   membuatnya mendominasi bukan tinggi hurufnya melainkan BOBOTNYA: kapital tebal dengan
   jarak huruf melebar membuat "TANYA FIEZEL?" selebar ~60px di atas tombol 42px, sehingga
   ia melebar keluar tombolnya sendiri.

   Permintaan harfiahnya - 10x lebih kecil, yaitu 0,9px - tidak akan terlihat sama sekali.
   Yang diambil karena itu maksudnya: label yang mengecil sampai batas masih terbaca, dan
   tidak lagi bersaing dengan baloknya. Kapital, tebal, dan jarak huruf dicabut; ketiganya
   itulah yang menyumbang lebar, bukan tinggi hurufnya. */
/* Audit 14-002 (satu-satunya pelanggaran axe): opacity .75 menurunkan --muted jadi
   #928673 efektif - 3,4:1 di atas krem topbar, di bawah ambang 4,5:1. --muted penuh
   (--muted generasi lalu) sudah cukup kalem; kontrasnya ±5,7:1 tanpa mengubah kesan visualnya. */
.ask-button .ask-label{font-size:12px;/* q20-B1: literal dipin tests/search-feedback-test.js:239 — jangan tokenkan */font-weight:500;letter-spacing:0;
  color:var(--muted);white-space:nowrap}

.ask-box{display:flex;gap:8px;align-items:center;margin:4px 0 16px}
.ask-box input{flex:1;min-width:0;min-height:48px;padding:12px 14px;border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--panel);color:var(--text);font:inherit;outline:none}
.ask-box input::placeholder{color:var(--muted)}
/* outline dimatikan di atas demi sudut membulat, jadi penanda fokusnya WAJIB ada di
   sini: tanpa ini pengguna keyboard kehilangan jejak posisinya sama sekali. */
.ask-box input:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px;border-color:var(--focus-ring)}
.ask-box button{flex-shrink:0;padding:12px 16px;border-radius:var(--radius-sm)}
.ask-answer{padding:16px;margin-bottom:16px}
/* Jawaban model datang sebagai satu blok teks; tanpa ini baris barunya hilang dan
   penjelasan enam kalimat terbaca sebagai satu paragraf padat. */
.ask-answer p{white-space:pre-wrap}
.ask-related-title{font-size:13px;text-transform:uppercase;letter-spacing:.06em;
  opacity:.6;margin:0 0 8px}

/* Materi terkait. Gaya ini sempat HILANG saat style.css ditulis ulang di milestone lain
   dan tidak ada yang menyadarinya, karena tombolnya tetap berfungsi - hanya tampil
   telanjang. Tes sekarang menjaga token warnanya. */
.search-hit{display:flex;justify-content:space-between;align-items:center;gap:12px;
  width:100%;text-align:left;padding:14px;margin-bottom:8px;border:1px solid var(--line);
  border-radius:var(--radius-sm);background:var(--panel);color:var(--text);font:inherit;cursor:pointer}
.search-hit-title{font-weight:600;text-transform:capitalize}
.search-hit-view{font-size:var(--fs-caption);opacity:.6;text-transform:uppercase;letter-spacing:.06em;flex-shrink:0}

/* ==========================================================================
   m025-113 - Home minimalis dan eksklusif (brief redesign 4)

   OWNER: "dari atas sampai bawah masih berantakan sekali ui atau ux nya" lalu
   "buatkan dengan kesan minimalis dan eksklusif".

   Yang diukur sebelum menulis satu baris pun, di 375x812:
   - Home setinggi 2.791px. Tiga koma empat layar penuh untuk satu menu utama.
   - 12 kotak bergaris di dalamnya, termasuk kotak DI DALAM kotak (kartu Coach di dalam
     hero, empat kotak statistik di sebelah kotak misi).
   - Empat ajakan aksi bersaing di layar pertama, dua di antaranya memanggil fungsi yang
     sama persis (askCoachAI).
   - Tiga keluarga warna: marun merek, biru sisa palet v6, dan emas.
   - Satu bug kontras 1,05:1 pada seluruh kartu modul. Sudah diperbaiki di sumbernya
     (tutor-v3.css) - catatannya ada di sana.

   Prinsip lapisan ini, dan hanya ini:
   1. Satu material per bidang. Kedalaman datang dari garis rambut dan jarak, bukan dari
      kotak yang ditumpuk di atas kotak.
   2. Satu aksi utama per bidang.
   3. Satu wajah display (serif merek) untuk yang besar - judul, level, angka statistik -
      dan sans untuk sisanya. Huruf kapital hanya untuk label mikro.
   4. Tidak ada informasi yang dibuang. Yang dipotong adalah RUANG dan PENGULANGAN.
   ========================================================================== */

/* 1. Tanah halaman ikut fase langit juga di TEMA TERANG.
   m025-85 sudah meredam langit untuk tema gelap supaya halaman tidak menjadi lumpur.
   Kebalikannya tidak pernah ditangani: pukul 22.00 di tema terang, gradien langit gelap
   dipasang pada opasitas .58 di atas --ui-bg terang, jadi tanahnya berhenti di abu-abu
   ungu tengah - terlalu gelap untuk tinta gelap, terlalu terang untuk tinta terang, dan
   .scene-night sudah memasang tinta ambient TERANG di atasnya (sekitar 4,6:1). Karena
   materialnya memang sudah sepakat menggelap saat malam (kontrak m025-85), tanahnya yang
   dibuat ikut - bukan tintanya yang dibalik. */
/* m025-115: aturan "langit malam menjadi tanah" milik m025-113 dicabut. Ia ada karena
   material ikut menggelap saat malam; sejak brief pastel, material tidak pernah menggelap
   lagi di tema terang, jadi menggelapkan tanahnya justru membalik kontras. */

/* Tautan teks duduk langsung di atas tanah itu, jadi ia ikut fase yang sama. */
.text-button{color:var(--accent-on-glass);font-weight:600}

/* 2. Hero. Gradiennya dulu memuat satu stop BIRU (#151a38) di tengah dua marun; itulah
   yang membuat hero terbaca lumpur, bukan marun. Dua stop, satu keluarga. */


.launcher-meta{font-size:.6rem;letter-spacing:.18em}
/* Sapaan tidak lagi Georgia miring emas di sebelah judul serif: dua wajah display
   bertengkar di satu blok. Sapaan turun jadi label kecil, judulnya yang bicara. */
.launcher-greeting{font-family:var(--fz-body);font-style:normal;font-weight:600;font-size:.82rem;letter-spacing:.02em;margin:24px 0 10px}
.launcher-copy h1.login-message{font-family:var(--fz-display);font-weight:400;letter-spacing:-.01em;line-height:1.08}
/* Nama murid dulu satu baris raksasa merah muda di atas judul, memakan sepertiga hero.
   Ia tetap ada - sebagai sapaan mikro, tempat yang memang pantas untuknya. */
.launcher-copy h1.login-message span{display:block;font-family:var(--fz-body);font-size:.32em;font-weight:700;letter-spacing:.16em;text-transform:uppercase;margin:0 0 10px}
.launcher-copy h1.login-message br{display:none}


/* Kartu Coach berhenti menjadi kotak di dalam kotak; ia menjadi bagian bawah hero yang
   dipisahkan satu garis rambut. */
.coach-preview{padding:20px 0 0;border:0;border-radius:0;background:transparent}
.coach-icon{width:36px;height:36px;border-radius:var(--radius-sm)}
.coach-icon svg{width:18px;height:18px}
.coach-head small{letter-spacing:.16em}
.coach-level{margin:18px 0 14px;padding-bottom:14px}
.coach-level span{font-size:.62rem;letter-spacing:.16em;text-transform:uppercase}
.coach-level strong{font:400 2.1rem var(--fz-display);letter-spacing:-.01em}
.coach-preview h2{font-family:var(--fz-display);font-weight:400;font-size:1.2rem;letter-spacing:-.01em}
.coach-preview p{font-size:.82rem}
.coach-link{font-size:.82rem;font-weight:700}

/* 3. Ringkasan hari ini: SATU bidang, bukan lima kotak.
   Selektor sengaja diturunkan lewat .home-overview supaya deklarasi latar milik
   .mission-panel dan .home-stats sendiri tetap utuh - contrast-test membaca deklarasi itu
   sebagai sumber kebenaran untuk mengukur pasangan tinta/latarnya. */
.home-overview{gap:0;border:1px solid var(--glass-line);border-radius:var(--radius-md);background:var(--glass-thick);color:var(--glass-text);overflow:hidden;box-shadow:var(--shadow-sm)}
.home-overview .mission-panel,.home-overview .home-stats{border:0;border-radius:0;background:transparent;box-shadow:none}
.home-overview .mission-panel{border-bottom:1px solid var(--glass-line)}
.mission-panel h3{font-family:var(--fz-body);font-size:.95rem;font-weight:600;letter-spacing:-.01em}
.mission-ring{--ring-size:60px;background:conic-gradient(var(--sun-deep) var(--mission),var(--glass-line) 0)}
.mission-ring::before{width:46px;height:46px;background:var(--glass-solid)}
.mission-ring strong{font-size:1rem}
.mission-ring span{font-size:.6rem;color:var(--glass-muted)}
.home-stats strong{font:400 1.6rem var(--fz-display);letter-spacing:-.01em;margin-top:2px}
.home-stats small{text-transform:none;letter-spacing:.01em;font-size:.7rem}

/* 4. Perjalanan belajar: dua panel menjadi satu bidang dengan satu garis pemisah, dan
   blok rencana berhenti menjadi kotak-kotak kecil di dalam kotak. */
.journey-panel{grid-template-columns:1fr;gap:0;margin:0;border:1px solid var(--glass-line);border-radius:var(--radius-md);background:var(--glass-thick);color:var(--glass-text);overflow:hidden;box-shadow:var(--shadow-sm)}
.journey-panel .journey-mission,.journey-panel .journey-today{border:0;border-radius:0;background:transparent;box-shadow:none}
.journey-panel .journey-mission{border-bottom:1px solid var(--glass-line)}
.journey-mission small,.journey-today small{font-size:.6rem;letter-spacing:.16em}
.journey-mission h3{font:400 1.2rem var(--fz-display);letter-spacing:-.01em;margin:8px 0 6px}
.journey-blocks{gap:4px}
.journey-panel .journey-block{border:0;border-left:2px solid var(--glass-line);border-radius:0;padding:5px 0 5px 12px}
.journey-panel .journey-block-review{border-left-color:var(--accent-on-glass)}
.journey-skills{margin:0}
.home-fold{margin:0}
.home-fold>summary{font-weight:600}
/* Footer aksi Pengaturan ikut material kaca yang sama dengan panelnya. */
.modal-actions.settings-actions{border-top-color:var(--glass-line)}
.settings-fold{background:var(--glass-thick);color:var(--glass-text)}

/* 5. Kepala bagian: satu bentuk untuk semuanya - judul serif, tautan tenang di kanan. */
.home-section-head{margin:18px 0 0;align-items:baseline}
.home-section-head h2{font:400 1.35rem var(--fz-display);letter-spacing:-.01em}

/* 6. Kartu modul. Judulnya yang dibaca lebih dulu, angkanya menyusul - dulu terbalik,
   dan itu membuat enam kartu terbaca sebagai enam angka tanpa nama. */
.learning-launcher{gap:10px}
.launch-card{padding:16px}
.launch-card>span:nth-child(2){display:flex;flex-direction:column-reverse;gap:3px}
.launch-card b{font-family:var(--fz-body);font-weight:600;letter-spacing:-.01em}
.launch-card small{text-transform:none;letter-spacing:.01em;font-size:var(--fs-caption)}
.launch-card>svg{opacity:.4;width:15px}
.launch-icon{width:38px;height:38px;border-radius:var(--radius-sm)}
.launch-icon svg{width:19px;height:19px}

/* 7. Ponsel: satu irama jarak, satu kolom untuk yang panjang, dua kolom untuk yang pendek. */
@media(max-width:640px){
  .home-page{gap:14px}
  .launcher-shell{padding:22px 18px 24px;gap:18px;border-radius:var(--radius-lg)}
  .launcher-greeting{margin:18px 0 8px;font-size:.78rem}
  .launcher-copy h1.login-message{font-size:1.72rem}
  .launcher-lead{font-size:.84rem;line-height:1.6;margin:12px 0 0}
  .launcher-actions{margin-top:20px}
  .coach-preview{padding:18px 0 0}
  .coach-level{margin:14px 0 12px}
  .coach-level strong{font-size:1.8rem}
  .coach-preview h2{font-size:1.08rem}
  .home-overview .mission-panel{padding:16px;gap:14px}
  .home-overview .home-stats>div{padding:13px 16px}
  .home-stats strong{font-size:1.35rem}
  .journey-panel .journey-mission,.journey-panel .journey-today{padding:16px}
  /* Kepala bagian tetap SATU baris di ponsel: judul dan tautannya sejajar dasar huruf.
     Menumpuknya menambah 44px tinggi per bagian tanpa menambah satu informasi pun. */
  .home-section-head{flex-direction:row;align-items:baseline;gap:12px;margin:16px 0 0}
  .home-section-head h2{font-size:1.2rem}
  .home-section-head .text-button{padding:6px 0;font-size:.76rem;white-space:nowrap}
  .launch-card{min-height:100px;padding:14px}
  .launch-icon{width:34px;height:34px;border-radius:var(--radius-sm)}
}

/* 8. Aksi utama di atas material malam. Gradien marun gelap milik lapisan v6
   (#4a1a26 -> #241016) sah di siang hari, tetapi di atas kaca malam ia menjadi kotak
   gelap di atas kotak gelap: teksnya terbaca, tombolnya tidak. Malam hari aksi utama
   memakai bidang gading yang sama dengan tombol hero - satu-satunya bidang terang di
   layar, dan karena itu tidak pernah salah dikenali sebagai aksi utama. */
/* m025-115: aturan "aksi utama jadi gading saat malam" dicabut. Ia ada karena material
   ikut menggelap saat malam; sekarang aksi utama selalu bidang kuning pastel dengan
   tinta coklat, di jam berapa pun. */

/* Jam langit adalah keterangan, bukan bidang: ia berhenti memakan satu baris penuh. */
@media(max-width:640px){
  .celestial-status{width:auto;margin-left:0;padding:5px 10px}
  .launcher-meta{gap:8px}
}
/* Tombol utama di dalam hero selalu gading, siang maupun malam: hero-nya memang selalu
   marun gelap, jadi gradien marun milik lapisan v6 (yang menang spesifisitas atas
   .launcher-actions .luxe sejak v6 dipasang se-aplikasi) membuatnya gelap di atas gelap.
   Ini mengembalikan maksud aslinya, bukan menambah gaya baru. */

/* ==========================================================================
   m025-115 - Komponen pastel: ceria, eksklusif, minimalis, mahal
   Brief: FIEZEL_Instruksi_Redesign_UIUX.pdf (OWNER, v1) + susulan "semua warnanya
   harus pastel".

   Empat kata itu saling menegangkan, dan ketegangannya diselesaikan begini:
   - CERIA datang dari BIDANG: cream, kuning pastel, koral pastel, mint.
   - MAHAL datang dari TINTA DAN GARIS: coklat lembut, emas tipis, satu garis rambut,
     jarak yang longgar. Bukan dari warna gelap.
   - MINIMALIS dijaga dengan disiplin lama: satu aksi utama per bidang, satu material
     per bidang, tidak ada kotak di dalam kotak.
   - EKSKLUSIF datang dari yang paling murah dan paling terasa: ikon buatan sendiri,
     tombol yang benar-benar bisa "ditekan", dan tipografi serif untuk yang besar.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tombol chunky. Tombol pill putih rata diganti seluruhnya.
   Bayangan bawahnya PEKAT dan tidak buram - itulah yang membuat tombol terbaca
   punya tebal, dan kenapa menekannya terasa seperti menekan sesuatu: tombol turun
   3px dan bayangannya ikut memendek, persis seperti benda yang ditekan.
   -------------------------------------------------------------------------- */
button.primary,.primary.wide,.primary.luxe,html.fiezel-ui-v6 body .primary{
  background:var(--sun);color:var(--text);border:0;border-radius:var(--radius-md);
  min-height:52px;font-size:var(--fs-body);font-weight:700;letter-spacing:-.01em;
  box-shadow:var(--lift-sun),var(--shadow-sm);
  transition:transform var(--dur-xs) var(--ease),box-shadow var(--dur-xs) var(--ease),background var(--dur-s) var(--ease);
}
/* Hover MENGGELAP, bukan menerang: #FFE896 lebih terang dari --sun sehingga tombol
   terasa "menghilang" saat disentuh. Resep components.css §1: sun -> sun-deep. */
button.primary:hover,.primary.luxe:hover,html.fiezel-ui-v6 body .primary:hover{background:var(--sun-deep);color:var(--text)}
button.primary:active,.primary.luxe:active,html.fiezel-ui-v6 body .primary:active{
  transform:translateY(3px);box-shadow:var(--lift-sun-press)}
/* .primary.is-coral DIHAPUS di F2-16: grep pada app.js + index.html memberi NOL
   pemakaian. Ia sudah mati sebelum rebrand ini; menyimpan selector mati berarti
   fase berikutnya harus menebak apakah ia masih dipakai. Aksi kedua sekarang punya
   resep sendiri di components.css (varian tinta) dan akan dipasang saat markup
   memerlukannya. */

/* Tombol biasa ikut punya tebal, hanya lebih tenang. */
/* i10 2026-08-28 (O5 §2): + :not(.option) — empat tombol jawaban berbayang tebal membuat
   layar soal terasa seperti empat kartu bersaing dengan soalnya; pilihan kembali ke resep
   dasar .option yang tenang (garis --line, tanpa bayangan lantai). */
/* .ch-plain (m025-364): kontrol KelasKu yang BUKAN tombol angkat — segmen status, tombol
   ikon di baris tugas, lipatan grup, tautan Arsip. Bingkai & bayangan angkat di sini membuat
   segmen status terbaca sebagai deretan tab kedua di bawah tab KelasKu.
   .fz-plain (m025-367): hal yang sama untuk kontrol datar layar masuk (tab peran, tautan,
   pemilih bahasa, tombol mata kata sandi, panah Lanjut). */
html.fiezel-ui-v6 body button:not(.primary):not(.nav):not(.icon-button):not(.brand-button):not(.text-button):not(.coach-link):not(.fz-coach-bubble):not(.launch-card):not(.skill-card):not(.option):not(.skill-help-dot):not(.olm-dispute):not(.ch-plain):not(.fz-plain){
  border:1.5px solid var(--surface-edge);border-radius:var(--radius-md);
  box-shadow:var(--lift-edge);
  transition:transform var(--dur-xs) var(--ease),box-shadow var(--dur-xs) var(--ease);
}
html.fiezel-ui-v6 body button:not(.primary):not(.nav):not(.icon-button):not(.brand-button):not(.text-button):not(.coach-link):not(.fz-coach-bubble):not(.launch-card):not(.skill-card):not(.option):not(.skill-help-dot):not(.olm-dispute):not(.ch-plain):not(.fz-plain):active{
  transform:translateY(2px);box-shadow:var(--lift-edge-press)}

/* --------------------------------------------------------------------------
   2. Hero. Dasar maroon gelap diganti total oleh gradien kuning pastel, dan
   seluruh tintanya ikut berbalik menjadi coklat - kalau tidak, hero cerah dengan
   tinta terang adalah bug kontras yang sama yang baru diperbaiki di m025-113.
   -------------------------------------------------------------------------- */
.launcher-shell{
  background:linear-gradient(155deg,var(--launcher-start) 0%,var(--launcher-end) 118%);
  color:var(--ink);
  border:1px solid rgba(217,188,126,.45);
  box-shadow:var(--shadow-md);
}
/* Matahari sudut: satu lingkaran krem, bukan kabut emas yang tidak terbaca. */
.launcher-shell::after{
  width:210px;height:210px;right:-70px;top:-90px;
  background:radial-gradient(circle,rgba(255,255,255,.85) 0%,rgba(255,255,255,0) 70%);filter:none}
.launcher-meta{color:var(--ink);opacity:.62;font-size:.6rem;letter-spacing:.18em}
.launcher-greeting{color:var(--accent-strong);opacity:.9}
.launcher-copy h1.login-message{color:var(--ink)}
.launcher-copy h1.login-message span{color:var(--ink);opacity:.55}
.launcher-lead{color:var(--ink);opacity:.78}
.celestial-status{border:1px solid rgba(36,26,17,.14);background:rgba(255,255,255,.55);color:var(--ink)}
.celestial-status span{color:var(--ink);opacity:.7}
.live-signal{background:var(--green);box-shadow:0 0 0 5px rgba(46,139,105,.16)}

/* Kartu Coach di dalam hero tetap tanpa bingkai, hanya garis rambut - hanya
   warnanya yang ikut berbalik. */
.coach-preview{border-top:1px solid rgba(36,26,17,.14)}
.coach-icon{background:rgba(255,255,255,.7);color:var(--accent-strong);border:1px solid rgba(217,188,126,.6)}
.coach-head small{color:var(--ink);opacity:.6}
.coach-head b{color:var(--ink)}
.coach-level{border-bottom:1px solid rgba(36,26,17,.12)}
.coach-level span{color:var(--ink);opacity:.6}
.coach-level strong{color:var(--ink)}
.coach-preview h2{color:var(--ink)}
.coach-preview p{color:var(--ink);opacity:.78}
.coach-link{color:var(--accent-strong)}

/* --------------------------------------------------------------------------
   3. Ikon duotone buatan sendiri (features/ui/fiezel-icons.js).
   Ini titik ungkit termurah dari "template" ke "eksklusif", persis seperti yang
   ditulis brief: garis coklat + isian pastel, sudut membulat, satu keluarga.
   -------------------------------------------------------------------------- */
/* Audit 20-002: setiap konteks .fz-i WAJIB mendeklarasikan ukurannya sendiri, dan kelas
   dasarnya membawa pagar maksimum. Tanpa pagar ini, satu konteks yang lupa (seperti
   ritual harian) membuat SVG-nya mekar ke ukuran intrinsik 300px - kelas cacat yang
   sama dengan bug "ikon Peta 300px" di m025-166. Ukuran .fz-i terbesar yang disengaja
   hari ini 26px (.nav), jadi 48px aman untuk semua pemakaian sah. */
.fz-i{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;line-height:0;max-width:48px;max-height:48px}
.fz-i svg{width:100%;height:100%;display:block}
.fz-i .fz-fill{fill:var(--fz-i-fill,var(--yellow));transition:fill .2s var(--ease)}
.fz-i .fz-line{fill:none;stroke:var(--fz-i-line,var(--ink));stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.nav .fz-i{width:24px;height:24px}
.launch-icon .fz-i,.skill-card .fz-i{width:24px;height:24px}

/* --------------------------------------------------------------------------
   4. Tab bar. Tab aktif jadi kapsul kuning pastel, bukan hanya teks berwarna.
   -------------------------------------------------------------------------- */
.bottomnav{border:1px solid var(--surface-edge);box-shadow:0 2px 0 var(--surface-edge),var(--shadow-md)}
.nav{color:var(--muted);font-weight:600}
.nav .fz-i{--fz-i-fill:var(--surface-mute);--fz-i-line:var(--muted)}
.nav.active{color:var(--text);background:var(--sun-soft);font-weight:700}
.nav.active .fz-i{--fz-i-fill:var(--sun);--fz-i-line:var(--text)}

/* --------------------------------------------------------------------------
   5. Home hub: empat skill inti tes sebagai pusat gravitasi baru.
   Tidak ada yang dihapus - kartu modul lama tetap ada di bawahnya, hanya tidak
   lagi menjadi hal pertama yang dilihat.
   -------------------------------------------------------------------------- */
.skill-hub{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.skill-card{
  position:relative;display:grid;gap:10px;padding:16px;text-align:left;align-content:start;
  min-height:132px;border-radius:var(--radius-lg);border:1.5px solid var(--skill-line,var(--surface-edge));
  background:var(--skill-bg,var(--panel-soft));color:var(--ink);
  box-shadow:0 4px 0 var(--skill-line,var(--surface-edge)),0 12px 26px rgba(36,26,17,.10);
  transition:transform .14s var(--ease),box-shadow .14s var(--ease);
}
.skill-card:active{transform:translateY(3px);box-shadow:0 1px 0 var(--skill-line,var(--surface-edge)),0 6px 14px rgba(36,26,17,.10)}
.skill-card .fz-i{--fz-i-fill:var(--skill-ink,var(--yellow));--fz-i-line:var(--ink)}
.skill-card-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.skill-card b{font-size:1rem;font-weight:700;letter-spacing:-.01em}
.skill-card small{display:block;color:var(--ink);opacity:.66;font-size:.72rem;line-height:1.45}
.skill-badge{font-size:.6rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink);opacity:.78}/* q17-S4: 3.8:1 -> >=4.5:1 */
/* Cincin progres: satu conic-gradient, tanpa satu pun elemen tambahan. */
.skill-ring{
  width:38px;height:38px;border-radius:50%;display:grid;place-items:center;flex:0 0 auto;
  background:conic-gradient(var(--skill-ink,var(--yellow)) var(--ring,0%),rgba(36,26,17,.10) 0);
}
.skill-ring::before{content:"";grid-area:1/1;width:28px;height:28px;border-radius:50%;background:var(--skill-bg,var(--panel-soft))}
.skill-ring b{grid-area:1/1;z-index:1;font-size:.62rem;font-weight:700;color:var(--ink)}
.skill-listening{--skill-bg:#FBF3E2;--skill-line:#EFDFB8;--skill-ink:#7A5512}
/* --skill-ink adalah warna ANGKA di tengah cincin. Tiga dari empat nilai lamanya
   pastel: #A8DCC4 mengukur 1,4:1 dan #C9BCE4 1,8:1 terhadap bidangnya - angkanya
   memang tidak terbaca, bukan kurang terbaca. Sekarang tiap keterampilan memakai
   turunan pekat keluarganya. Writing masuk keluarga INFO (kuning tua): lilac tidak
   punya turunan pekat di sistem baru, dan --sun-deep 5,9:1 di atas info-soft.
   --skill-line dibiarkan literal: ia garis lokal, bukan token brief. */
.skill-speaking{--skill-bg:var(--bad-soft);--skill-line:#F6D3C9;--skill-ink:var(--bad-bright)}
.skill-reading{--skill-bg:var(--good-soft);--skill-line:#CDE9DD;--skill-ink:var(--good-bright)}
.skill-writing{--skill-bg:var(--info-soft);--skill-line:#F3E0AE;--skill-ink:var(--sun-deep)}

/* --------------------------------------------------------------------------
   6. Kartu modul lama ikut keluarga yang sama, hanya lebih tenang: ia bukan lagi
   pusat perhatian, tetapi tetap satu ketukan.
   -------------------------------------------------------------------------- */
.launch-icon{background:var(--yellow-soft);color:var(--accent-strong);border:1px solid var(--surface-edge)}
.grammar-launch .launch-icon{background:var(--sun-soft)}
.reading-launch .launch-icon{background:var(--good-soft)}
.skills-launch .launch-icon{background:var(--info-soft)}
/* v6.1 (O4 §3): grid home sudah punya shell ber-elevasi — kartu cukup lift taktil. */
.launch-card{border:1.5px solid var(--surface-edge);box-shadow:var(--lift-edge)}
.launch-card:active{transform:translateY(2px);box-shadow:0 1px 0 var(--surface-edge)}

/* --------------------------------------------------------------------------
   7. FIEZEL sebagai pembimbing: gelembung mengambang yang hadir di semua halaman.
   Ia BUKAN panel laporan lagi. Napasnya pelan supaya terbaca hidup, dan berhenti
   sepenuhnya kalau perangkat minta kurangi-gerak.
   -------------------------------------------------------------------------- */
.fz-coach-bubble{
  position:fixed;right:16px;bottom:calc(104px + env(safe-area-inset-bottom));z-index:41;
  width:58px;height:58px;padding:0;border-radius:50%;border:0;
  background:var(--accent);color:#FFFFFF;cursor:pointer;
  box-shadow:0 10px 24px -6px rgba(155,58,74,.36),var(--shadow-md);
  display:grid;place-items:center;
  transition:transform .16s var(--ease-spring),box-shadow .16s var(--ease);
}
.fz-coach-bubble:active{transform:translateY(2px) scale(.97);box-shadow:0 4px 12px -2px rgba(155,58,74,.3)}
.fz-coach-bubble .fz-coach-face{width:30px;height:30px}
/* v6.1 (I8 §6 / O3 §6 P0-2): sabuk-pengaman ukuran — anak maskot TIDAK boleh melebihi
   FAB 58×58; tanpa ini ia pernah render 96×90 dan menimpa CTA/nav di bawahnya. */
.fz-coach-bubble .fz-coach-mascot{width:100%;height:100%}
/* v6.1 (I11 residu 768px): di layar ≥768 pill nav 620px menyisakan selokan 74px di kanan —
   FAB turun sejajar baris nav, berhenti menumpangi sudut kartu skill/chip level. */
@media(min-width:768px){
  .fz-coach-bubble{bottom:max(16px,env(safe-area-inset-bottom))}
  .fz-coach-peek{bottom:calc(28px + env(safe-area-inset-bottom))}
}
.fz-coach-bubble .fz-coach-pulse{
  position:absolute;inset:-6px;border-radius:50%;border:2px solid var(--yellow);
  opacity:0;animation:fzCoachBreath 3.4s var(--ease) infinite}
@keyframes fzCoachBreath{0%{transform:scale(.94);opacity:.55}70%{transform:scale(1.16);opacity:0}100%{opacity:0}}
.fz-coach-dot{
  position:absolute;top:-3px;right:-3px;width:20px;height:20px;border-radius:50%;
  background:var(--bad);border:2px solid var(--bg);
  display:grid;place-items:center;font-size:var(--fs-caption);font-weight:700;color:var(--on-core)}
.fz-coach-bubble[hidden]{display:none}

/* Sapaan singkat yang muncul sendiri di samping gelembung. Ia menghilang sendiri;
   tidak ada tombol tutup, karena menutup sesuatu yang menyapa itu pekerjaan. */
.fz-coach-peek{
  position:fixed;right:84px;bottom:calc(116px + env(safe-area-inset-bottom));z-index:41;
  max-width:min(230px,62vw);padding:10px 13px;border-radius:var(--radius-md) var(--radius-md) var(--sp-1) var(--radius-md);
  border:1.5px solid var(--surface-edge);background:var(--glass-solid);color:var(--text);
  font-size:.78rem;line-height:1.45;box-shadow:var(--shadow-md);
  animation:fzCoachPeek .34s var(--ease-spring) both}
@keyframes fzCoachPeek{from{opacity:0;transform:translateY(6px) scale(.96)}to{opacity:1;transform:none}}
.fz-coach-peek[hidden]{display:none}

.fz-coach-sheet{
  position:fixed;inset:0;z-index:2147481500;display:flex;align-items:flex-end;justify-content:center;
  padding:12px;background:var(--scrim-soft);animation:fzCoachFade .2s var(--ease) both}
.fz-coach-sheet[hidden]{display:none}
@keyframes fzCoachFade{from{opacity:0}to{opacity:1}}
.fz-coach-panel{
  width:min(560px,100%);max-height:min(78vh,640px);display:flex;flex-direction:column;
  padding:16px 16px calc(14px + env(safe-area-inset-bottom));border-radius:var(--radius-lg);
  border:1.5px solid var(--surface-edge);background:var(--glass-solid);color:var(--text);
  box-shadow:0 -6px 60px rgba(36,26,17,.24);animation:fzCoachRise .28s var(--ease-spring) both}
@keyframes fzCoachRise{from{transform:translateY(24px);opacity:0}to{transform:none;opacity:1}}
.fz-coach-head{display:flex;align-items:center;gap:10px;padding-bottom:12px;border-bottom:1px solid var(--line)}
.fz-coach-head b{font-size:.95rem}
.fz-coach-head small{display:block;color:var(--muted);font-size:.68rem}
.fz-coach-avatar{width:38px;height:38px;border-radius:50%;background:var(--yellow);border:2px solid var(--ink);display:grid;place-items:center}
.fz-coach-avatar .fz-coach-face{width:22px;height:22px}
.fz-coach-close{margin-left:auto;width:38px;height:38px;border-radius:50%;display:grid;place-items:center;border:1.5px solid var(--surface-edge);background:transparent;color:var(--text);cursor:pointer}
/* m025-266: pintu "Cari materi" di kepala panel pembimbing -> layar Tanya FIEZEL (askView).
   Bentuk chip yang sama dengan .fz-coach-chip supaya terbaca sebagai pilihan, bukan tombol
   tutup kedua; margin-left:auto memindahkan tombol tutup ke ujung kanan seperti sebelumnya. */
.fz-coach-ask-page{margin-left:auto;display:inline-flex;align-items:center;min-height:32px;padding:5px 11px;border-radius:var(--radius-pill);font-size:.72rem;font-weight:600;cursor:pointer;border:1.5px solid var(--surface-edge);background:var(--panel-soft);color:var(--text);white-space:nowrap}
.fz-coach-ask-page:active{transform:translateY(1px)}
.fz-coach-ask-page+.fz-coach-close{margin-left:0}
.fz-coach-log{flex:1;overflow-y:auto;display:grid;gap:10px;padding:14px 2px;align-content:start}
.fz-coach-msg{max-width:88%;padding:10px 13px;font-size:.84rem;line-height:1.55;border-radius:var(--radius-md)}
.fz-coach-msg.is-coach{justify-self:start;border-radius:var(--radius-md) var(--radius-md) var(--radius-md) var(--sp-1);background:var(--yellow-soft);border:1px solid var(--surface-edge)}
.fz-coach-msg.is-user{justify-self:end;border-radius:var(--radius-md) var(--radius-md) var(--sp-1) var(--radius-md);background:var(--panel-soft);border:1px solid var(--surface-edge)}
.fz-coach-msg p{margin:0 0 6px}.fz-coach-msg p:last-child{margin:0}
.fz-coach-chips{display:flex;flex-wrap:wrap;gap:7px;padding:2px 0 10px}
.fz-coach-chip{
  min-height:36px;padding:7px 12px;border-radius:var(--radius-pill);font-size:.76rem;font-weight:600;cursor:pointer;
  border:1.5px solid var(--surface-edge);background:var(--panel-soft);color:var(--text)}
.fz-coach-chip:active{transform:translateY(1px)}
.fz-coach-form{display:flex;gap:8px;align-items:flex-end}
/* KEBIJAKAN ANTI-ZOOM-OTOMATIS iOS (m025-186).
   font-size di bawah 16px pada kontrol teks membuat iOS Safari MEMPERBESAR seluruh halaman
   saat kontrolnya difokus - lalu tidak mengembalikannya. Itulah gejala "terasa seperti
   website, bukan aplikasi" yang paling sering terlihat, dan akarnya BUKAN pinch: ia dipicu
   oleh fokus. Diukur sebelum perbaikan: textarea ini 13,76px (`.86rem`).
   Nilainya dipaku 16px, BUKAN dinaikkan sedikit, karena 16px adalah ambang perilaku Safari -
   15,9px tetap memicu zoom. Ukuran tampil dijaga tetap ringkas lewat padding dan tinggi,
   bukan lewat mengecilkan huruf. `tests/app-interaction-policy-test.js` menegakkan ambang ini. */
.fz-coach-form textarea{
  flex:1;min-height:44px;max-height:110px;padding:11px 13px;border-radius:var(--radius-md);resize:none;
  border:1.5px solid var(--surface-edge);background:var(--panel);color:var(--text);font:inherit;font-size:16px}
.fz-coach-send{width:46px;height:46px;flex:0 0 auto;border-radius:var(--radius-md);border:0;background:var(--yellow);color:var(--ink);
  box-shadow:0 3px 0 var(--yellow-deep);display:grid;place-items:center;cursor:pointer}
.fz-coach-send:active{transform:translateY(2px);box-shadow:0 1px 0 var(--yellow-deep)}
body.fz-coach-open{overflow:hidden}

/* --------------------------------------------------------------------------
   8. Micro-interaction saat sesuatu SELESAI. Kecil, sekali, lalu hilang.
   -------------------------------------------------------------------------- */
.fz-pop{animation:fzPop .5s var(--ease-spring) both}
@keyframes fzPop{0%{transform:scale(.7);opacity:0}60%{transform:scale(1.08)}100%{transform:none;opacity:1}}
.fz-confetti{position:fixed;inset:0;pointer-events:none;z-index:2147481400;overflow:hidden}
.fz-confetti i{--fz-fall:1.5s;position:absolute;top:-12px;width:8px;height:12px;border-radius:2px;opacity:.95;animation:fzFall var(--fz-fall) linear forwards}
@keyframes fzFall{to{transform:translateY(105vh) rotate(540deg);opacity:.2}}
@media (prefers-reduced-motion:reduce){
  .fz-coach-bubble .fz-coach-pulse,.fz-pop,.fz-confetti i{animation:none}
  .fz-coach-peek,.fz-coach-panel{animation:none}
}
body.reduce-motion .fz-coach-bubble .fz-coach-pulse,body.reduce-motion .fz-confetti i{animation:none}

/* --------------------------------------------------------------------------
   9. Halaman skill baru (Listening, Speaking, Writing) memakai pola yang sama
   dengan Reading/Grammar supaya tidak ada pola baru yang harus dipelajari.
   -------------------------------------------------------------------------- */
/* Baris atas halaman skill (permintaan OWNER 2026-08-31). Menggantikan kartu hero
   ~200px yang isinya pindah ke dialog "?" (app.js openSkillHelp). Barisnya hanya
   setinggi tombolnya, jadi kartu soal naik hampir satu layar penuh di ponsel.
   Tombolnya 44px penuh - lantai sasaran sentuh, bukan "kecil" secara harfiah; yang
   diminta kecil adalah kehadiran VISUALnya, dan itu dicapai lewat warna tenang dan
   lingkaran ramping, bukan dengan mengecilkan kotak sentuhnya di bawah lantai. */
/* Sticky, bukan statis. Selama sesi Skills Lab topbar aplikasi DISEMBUNYIKAN
   (setSessionStage), jadi tombol ini adalah satu-satunya jalan ke keterangan latihan -
   dan kalau ia ikut tergulir, ia hilang tepat saat murid menggulir daftar pilihan
   jawaban. Terukur di preview: y=-16px setelah gulir kecil, tepiannya terpotong.
   top:6px menyamai --sp yang dipakai topbar v6 di lebar ponsel (tutor-v3.css:94). */
.skill-page-topbar{display:flex;justify-content:space-between;align-items:center;margin:0 0 10px;position:sticky;top:6px;z-index:34}
.skill-help-dot{
  width:44px;height:44px;min-height:44px;padding:0;
  display:grid;place-items:center;margin-left:auto;
  border-radius:50%;border:1px solid var(--line);
  background:var(--panel-soft);color:var(--ink);
  font-size:1.05rem;font-weight:800;line-height:1;
  box-shadow:none;
}
.skill-back-btn{
  display:inline-flex;align-items:center;gap:8px;font-size:.88rem;font-weight:700;
  color:var(--text);background:var(--panel-soft);border:1px solid var(--line);
  border-radius:999px;padding:6px 14px;min-height:42px;cursor:pointer;
  transition:background .15s ease,border-color .15s ease;
}
.skill-back-btn:hover{background:var(--surface-tint);border-color:var(--line-strong)}
.skill-back-btn svg{width:16px;height:16px}
.skill-help-dot:hover{background:var(--sun-soft);transform:none}
/* DUA aturan menimpa bentuk tombol ini, dan keduanya harus dijawab - preview mencatnya
   dulu 16px, lalu 13px setelah yang pertama diatasi:
     1. style.css:2436 `html.fiezel-ui-v6 body button:not(...)` (0,4,3) -> radius-md 16px.
        Dijawab dengan MENAMBAHKAN .skill-help-dot ke rantai :not()-nya, mengikuti konvensi
        yang sudah dipakai .primary/.nav/.icon-button di repo ini.
     2. tutor-v3.css:33 `html.fiezel-ui-v6 button` (0,1,1) -> 13px, dan berkas itu dimuat
        SESUDAH style.css. Dijawab dengan menyamai bentuk pemilihnya di bawah ini (0,2,1).
   Keduanya lewat spesifisitas, bukan !important: !important juga akan mengalahkan tema
   yang memang berhak menimpa nanti. */
html.fiezel-ui-v6 .skill-help-dot{border-radius:50%}
/* PANGGUNG MATERI GRAMMAR (OWNER 2026-08-31: "design ulang grammar seperti listening").
   Susunan yang sama dengan sesi dengar: tokoh di KIRI, gelembung ucap di KANAN, dan
   judul materi duduk DI DALAM gelembung itu. Sebelum ini layar materi tidak punya maskot
   sama sekali - satu-satunya Pau adalah FAB mengambang di pojok, yang tidak pernah
   berhubungan dengan isi layarnya. Judulnya juga tercetak dua kali (hero + kartu); kini
   sekali, di tempat tokohnya mengucapkannya. */
.lesson-stage{display:flex;align-items:center;gap:10px;margin:0 0 12px}
/* Panggung maskot Writing: satu-satunya bedanya dengan panggung materi Grammar adalah
   tidak ada gelembung - judul dan lead sudah ada di hero tepat di atasnya, jadi gelembung
   hanya akan mengulang kalimat yang sama. Ukurannya dipinjam dari .lesson-stage-paw. */
.writing-stage{display:flex;justify-content:center;margin:0 0 12px}
.writing-stage .writing-mascot{width:100%;height:auto;display:block}
.lesson-stage-paw{flex:0 0 auto;width:clamp(104px,30vw,136px);display:block}
/* Ukuran naik dari clamp(64,22vw,96) 2026-08-31. Dua sebab, keduanya terukur:
   (1) OWNER dua kali menyebut maskot Grammar terlalu kecil dan ruang di bawahnya
       terlalu kosong; (2) di 390px lebar, rumus lama menghasilkan 86px render -
       DUA piksel di bawah lantai identitas 88px lapisan outfit (19 SS6.5), jadi
       pensil OF-07 yang diminta OWNER untuk sesi Grammar tidak akan pernah
       terpasang di layar materi. Rumus baru memberi 117px di 390px: di atas lantai
       88px, dan di ponsel lebar/tablet menembus 128px sehingga grafit pensil
       (bagian halus) ikut tampil. */
.lesson-stage-paw :is(fiezel-mascot,svg,img,canvas){width:100%;height:auto;display:block}
/* .fz-mascot di dalam custom element dipaku 200px (fiezel-motion.css:127); tanpa baris ini
   ia tidak ikut mengecil dan hanya meluber keluar kotaknya. */
.lesson-stage-paw .lesson-mascot .fz-mascot{width:100%}
.lesson-stage-paw .fz-i{width:100%;height:auto;aspect-ratio:1;color:var(--accent-strong)}
.lesson-bubble{
  position:relative;flex:1 1 auto;min-width:0;
  padding:12px 14px;border:1.5px solid var(--line);border-radius:18px;background:var(--panel-soft);
}
.lesson-bubble b{display:block;font-family:var(--fz-display);font-weight:400;font-size:1.18rem;line-height:1.25;letter-spacing:-.01em}
/* Ekor gelembung dari border transparan - ikut warna tema, nol aset tambahan. */
.lesson-bubble::before,.lesson-bubble::after{content:'';position:absolute;top:50%;transform:translateY(-50%);border:9px solid transparent}
.lesson-bubble::before{left:-19px;border-right-color:var(--line)}
.lesson-bubble::after{left:-16px;border-right-color:var(--panel-soft)}
/* Kontrol Level belajar di dalam dialog bantuan butuh ruang napasnya sendiri. */
.skill-help-level{margin:14px 0 0}

/* Isi dialog bantuan: naskah yang dulu berdiri sebagai hero. */
.skill-help-panel{position:relative}
.modal-close-corner{
  position:absolute;top:-8px;right:-8px;width:38px;height:38px;border-radius:999px;
  border:1px solid var(--line);background:var(--panel-soft);color:var(--muted);
  display:grid;place-items:center;cursor:pointer;padding:0;transition:all .15s ease;
}
.modal-close-corner:hover{color:var(--text);background:var(--surface-tint);border-color:var(--line-strong)}
.modal-close-corner svg{width:18px;height:18px}
.skill-help-panel h2{margin:.35rem 0 .5rem;font-size:1.35rem;letter-spacing:-.02em}
.skill-help-panel p{margin:0 0 .6rem;font-size:.92rem;line-height:1.6}
.skill-help-panel .skill-level-note{margin-top:12px}
.skill-help-panel .modal-actions{margin-top:18px}
.skill-page-hero{
  display:grid;gap:8px;padding:18px;border-radius:var(--radius-lg);margin-bottom:14px;
  border:1.5px solid var(--skill-line,var(--surface-edge));background:var(--skill-bg,var(--panel-soft));color:var(--ink)}
.skill-page-hero .skill-badge{opacity:.78}
.skill-page-hero h1{margin:0;font-size:1.5rem;letter-spacing:-.02em}
.skill-page-hero p{margin:0;font-size:.84rem;line-height:1.6;color:var(--ink);opacity:.76}
.writing-prompt{display:grid;gap:10px}
.writing-prompt textarea{
  width:100%;min-height:150px;padding:14px;border-radius:var(--radius-md);resize:vertical;font:inherit;font-size:.9rem;line-height:1.6;
  border:1.5px solid var(--surface-edge);background:var(--panel);color:var(--text)}
.writing-meta{display:flex;justify-content:space-between;gap:10px;font-size:.74rem;color:var(--muted)}
.writing-feedback{display:grid;gap:8px}
.writing-feedback .card{background:var(--yellow-soft)}

/* Badge runtun: satu-satunya tempat koral menjadi bidang penuh di Home (brief bagian 5 -
   "badge streak yang terasa didapat"). Ikon api ikut ukuran teksnya, bukan sebaliknya. */
.home-stats .streak-badge{
  display:inline-flex;align-items:center;gap:6px;margin-top:4px;padding:4px 10px 4px 7px;
  border-radius:var(--radius-pill);background:var(--sun-soft);border:1.5px solid var(--sun-deep);
  font-size:1rem;line-height:1.2}
.home-stats .streak-badge .fz-i{width:17px;height:17px;--fz-i-fill:var(--sun);--fz-i-line:var(--ink)}

/* m025-118 giliran bicara tutor.
   Sengaja BUKAN memakai gaya .feedback: keduanya berbeda peran dan tidak boleh terlihat
   sama. Kotak feedback membuka jawaban; giliran tutor justru sering menahannya, dan murid
   harus bisa membedakan "ini petunjuk, soalnya masih terbuka" dari "ini jawabannya". */
/* Petunjuk BUKAN kesalahan. Aksen marun membuat setiap giliran tutor terbaca sebagai
   peringatan; keluarga info (kuning tua) menandainya sebagai bantuan. */
.tutor-turn{margin-top:14px;padding:14px 16px;border-radius:var(--radius-md);
  background:var(--panel-soft);border:1px solid var(--line);
  border-left:3px solid var(--info)}
.tutor-turn.hidden{display:none}
.tutor-turn-head{display:flex;align-items:center;gap:8px;margin-bottom:8px;
  font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.tutor-turn-face{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;
  background:var(--sun);color:var(--text)}
.tutor-turn-face svg{width:14px;height:14px}
.tutor-turn-say{margin:0;font-size:.94rem;line-height:1.6;color:var(--ink)}
.tutor-turn-ask{margin:8px 0 0;font-size:.94rem;line-height:1.6;font-weight:600;
  color:var(--info)}
.tutor-turn-actions{margin-top:12px}
/* Tinggi sentuh 44px, sama dengan seluruh kontrol lain - tombol ini justru ditekan oleh
   murid yang sedang bingung, jadi ia tidak boleh jadi target yang sulit dikenai. */
.tutor-stuck{min-height:44px;padding:10px 16px;border-radius:var(--radius-sm);font-size:.86rem;
  background:transparent;border:1px solid var(--line);color:var(--muted)}
.tutor-stuck:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.tutor-report{display:flex;align-items:center;justify-content:center;gap:8px;margin:10px 0 0;
  font-size:.9rem;line-height:1.55;color:var(--ink)}
.tutor-report svg{width:16px;height:16px;flex:0 0 auto}

/* m025-126 - kartu konsep (tindakan
eteach) dan tawaran berhenti (reathe).
   Bidangnya memakai --surface-tint (punya pasangan gelap) dengan tinta yang diwarisi,
   sama seperti .tutor-turn - jadi gerbang bidang pastel m025-117 tetap terpenuhi dan
   kartunya ikut berbalik dengan benar di mode gelap. */
.tutor-card{display:grid;gap:12px}
.tutor-card-head{display:flex;align-items:center;gap:10px}
.tutor-card-head small{display:block;font-size:var(--fs-caption);letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.tutor-card-head b{font-size:var(--fs-h2);letter-spacing:-.01em}
.tutor-card-why{margin:0;padding:10px 12px;border-radius:var(--radius-sm);font-size:.86rem;line-height:1.55;
  background:var(--panel-soft);border-left:3px solid var(--info)}
.tutor-card-rule{margin:0;font-size:.98rem;line-height:1.6;font-weight:600}
.tutor-card-cue{display:flex;align-items:flex-start;gap:8px;margin:0;font-size:.88rem;line-height:1.55;color:var(--muted)}
.tutor-card-cue svg{width:16px;height:16px;flex:0 0 auto;margin-top:2px}
.quiz-teach-flag{font-size:var(--fs-caption);font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
/* Dua jalan keluar berdampingan, dan yang "berhenti" justru jadi tombol utamanya:
   pada titik ini FIEZEL memang sedang menyarankan berhenti, bukan sekadar mengizinkan. */
.tutor-breathe{display:flex;flex-wrap:wrap;gap:8px}
.tutor-breathe .primary{min-height:44px;padding:10px 18px;font-size:.88rem}
/* ==========================================================================
   PAW — gerak per halaman (m025-128)
   ==========================================================================
   OWNER memilih arah 02, lalu meminta dua hal: "animasinya buatkan lebih eksklusif lagi,
   dan authentic" dan "animasinya berubah tergantung user masuk ke menu bagian apa".

   APA YANG MEMBUAT GERAK TERASA MURAH, dan karena itu dihindari di seluruh blok ini:
   amplitudo besar, durasi pendek, easing bawaan, dan gerak yang mengulang persis sejak
   milidetik pertama. Semua itu menarik perhatian ke DIRINYA. Yang dipakai di sini
   kebalikannya - amplitudo di bawah 1,6 px, durasi 2,6-5,2 detik, easing yang ditulis
   sendiri, dan satu gerak masuk sekali-jalan tiap kali halaman berganti supaya loop-nya
   tidak pernah tertangkap sebagai loop.

   APA YANG MEMBUATNYA OTENTIK, bukan sekadar berbeda-beda. Tiap halaman mendapat gerak
   yang menggambarkan PEKERJAAN di halaman itu, bukan gerak acak yang kebetulan tidak sama:
   kosakata mengumpulkan, grammar menelusuri satu pola, membaca mengikuti satu baris,
   listening berjalan sebagai gelombang, speaking mendorong keluar dari tengah. Tes justru
   nyaris diam - saat murid sedang diukur, maskot yang bergerak adalah gangguan.

   SATU LAPIS YANG SELALU HIDUP: napas 5,2 detik pada seluruh marka. Gerak per halaman
   ditumpuk DI ATASNYA lewat elemen yang berbeda (balok, bukan grup), jadi keduanya tidak
   pernah saling menimpa transform.
   -------------------------------------------------------------------------- */

.fz-i .fz-paw-bar,.fz-i .fz-paw-pad{fill:var(--fz-i-line,var(--ink));stroke:none}

/* Tiap balok berputar/bergeser dari ALASNYA sendiri, bukan dari pusat kanvas. Tanpa
   fill-box, transform-origin dihitung terhadap viewBox dan keempat balok bergerak seperti
   satu papan - persis yang membuat animasi SVG terlihat kaku. */
.fz-paw-bar{transform-box:fill-box;transform-origin:50% 100%}
.fz-paw{transform-box:view-box;transform-origin:12px 13px}

@media (prefers-reduced-motion:no-preference){

  /* Lapis dasar: napas. Selalu hidup, di semua halaman, pada GRUP-nya. */
  .fz-coach-bubble .fz-paw,.fz-coach-avatar .fz-paw{
    animation:fzPawBreath 5.2s cubic-bezier(.37,0,.24,1) infinite;
  }
  @keyframes fzPawBreath{0%,100%{transform:scale(1)}50%{transform:scale(1.035)}}

  /* Gerak masuk sekali-jalan saat halaman berganti. Inilah yang membuat perpindahan
     terasa disusun, bukan ditukar: marka mengendap sekali sebelum karakter barunya
     mengambil alih. */
  .fz-coach-bubble.is-paw-shift .fz-paw{
    animation:fzPawSettle .62s cubic-bezier(.34,1.12,.52,1) 1;
  }
  @keyframes fzPawSettle{
    0%{transform:scale(.9) rotate(-5deg)}
    55%{transform:scale(1.05) rotate(1.5deg)}
    100%{transform:scale(1) rotate(0)}
  }
  .fz-coach-bubble.is-paw-shift .fz-paw-bar{animation:none}

  /* ---- home / ask / search: mengendap bergiliran, tidak menuntut apa pun ---- */
  [data-fz-scene="home"] .fz-paw-bar{animation:fzPawIdle 4.6s cubic-bezier(.37,0,.24,1) infinite}
  [data-fz-scene="home"] .fz-paw-bar:nth-child(2){animation-delay:.22s}
  [data-fz-scene="home"] .fz-paw-bar:nth-child(3){animation-delay:.44s}
  [data-fz-scene="home"] .fz-paw-bar:nth-child(4){animation-delay:.66s}
  @keyframes fzPawIdle{0%,72%,100%{transform:scaleY(1)}36%{transform:scaleY(1.07)}}

  /* ---- vocab: mengumpulkan. Balok naik satu per satu lalu DITAHAN sebentar,
          seperti koin yang dikumpulkan - bukan bolak-balik. ---- */
  [data-fz-scene="vocab"] .fz-paw-bar{animation:fzPawCollect 4.2s cubic-bezier(.32,1.06,.6,1) infinite}
  [data-fz-scene="vocab"] .fz-paw-bar:nth-child(2){animation-delay:.3s}
  [data-fz-scene="vocab"] .fz-paw-bar:nth-child(3){animation-delay:.6s}
  [data-fz-scene="vocab"] .fz-paw-bar:nth-child(4){animation-delay:.9s}
  @keyframes fzPawCollect{
    0%{transform:translateY(1.4px) scaleY(.9)}
    18%,74%{transform:translateY(0) scaleY(1)}
    100%{transform:translateY(1.4px) scaleY(.9)}
  }

  /* ---- grammar: satu pola dulu. Tepat SATU balok meninggi pada satu waktu, berjalan
          dari kiri ke kanan - kalimat yang diucapkan halaman ini sendiri. ---- */
  [data-fz-scene="grammar"] .fz-paw-bar{animation:fzPawPattern 4.8s cubic-bezier(.4,0,.2,1) infinite}
  [data-fz-scene="grammar"] .fz-paw-bar:nth-child(2){animation-delay:1.2s}
  [data-fz-scene="grammar"] .fz-paw-bar:nth-child(3){animation-delay:2.4s}
  [data-fz-scene="grammar"] .fz-paw-bar:nth-child(4){animation-delay:3.6s}
  @keyframes fzPawPattern{
    0%,50%,100%{transform:scaleY(1);opacity:.72}
    22%{transform:scaleY(1.16);opacity:1}
  }

  /* ---- reading / library / classroom: mengikuti satu baris. Sapuan pekat berjalan
          kiri ke kanan, seperti jari yang menuntun bacaan. ---- */
  [data-fz-scene="reading"] .fz-paw-bar{animation:fzPawLine 3.8s cubic-bezier(.45,0,.25,1) infinite}
  [data-fz-scene="reading"] .fz-paw-bar:nth-child(2){animation-delay:.26s}
  [data-fz-scene="reading"] .fz-paw-bar:nth-child(3){animation-delay:.52s}
  [data-fz-scene="reading"] .fz-paw-bar:nth-child(4){animation-delay:.78s}
  @keyframes fzPawLine{0%,58%,100%{opacity:.55}22%{opacity:1}}

  /* ---- listening: gelombang berjalan. Di sinilah bacaan "equalizer" yang tadinya
          risiko justru menjadi keuntungan - halaman ini memang tentang bunyi. ---- */
  [data-fz-scene="listening"] .fz-paw-bar{animation:fzPawWave 2.6s cubic-bezier(.37,0,.24,1) infinite}
  [data-fz-scene="listening"] .fz-paw-bar:nth-child(2){animation-delay:.17s}
  [data-fz-scene="listening"] .fz-paw-bar:nth-child(3){animation-delay:.34s}
  [data-fz-scene="listening"] .fz-paw-bar:nth-child(4){animation-delay:.51s}
  @keyframes fzPawWave{0%,100%{transform:scaleY(1)}50%{transform:scaleY(1.22)}}

  /* ---- speaking: mendorong keluar dari tengah. Dua balok tengah lebih dulu, lalu
          dua balok tepi menyusul - suara yang keluar, bukan yang masuk. ---- */
  [data-fz-scene="speaking"] .fz-paw-bar{animation:fzPawProject 3.1s cubic-bezier(.3,1.1,.6,1) infinite;animation-delay:.28s}
  [data-fz-scene="speaking"] .fz-paw-bar:nth-child(2),
  [data-fz-scene="speaking"] .fz-paw-bar:nth-child(3){animation-delay:0s}
  @keyframes fzPawProject{
    0%,64%,100%{transform:scaleY(1) translateY(0)}
    30%{transform:scaleY(1.14) translateY(-.9px)}
  }

  /* ---- writing: satu goresan. Marka miring sedikit dan balok tertinggi turun -
          gerak tangan yang menekan pena, bukan denyut. ---- */
  [data-fz-scene="writing"] .fz-paw-bar:nth-child(3){animation:fzPawStroke 4.4s cubic-bezier(.4,0,.2,1) infinite}
  @keyframes fzPawStroke{
    0%,70%,100%{transform:scaleY(1) rotate(0)}
    26%{transform:scaleY(.82) rotate(-4deg)}
    44%{transform:scaleY(1.04) rotate(2deg)}
  }

  /* ---- progress: naik jadi tangga, lalu ditahan lama. Halaman ini tentang hasil yang
          menumpuk, jadi geraknya berakhir di posisi tinggi - bukan kembali ke nol. ---- */
  [data-fz-scene="progress"] .fz-paw-bar{animation:fzPawClimb 5s cubic-bezier(.32,1.06,.6,1) infinite}
  [data-fz-scene="progress"] .fz-paw-bar:nth-child(2){animation-delay:.24s}
  [data-fz-scene="progress"] .fz-paw-bar:nth-child(3){animation-delay:.48s}
  [data-fz-scene="progress"] .fz-paw-bar:nth-child(4){animation-delay:.72s}
  @keyframes fzPawClimb{
    0%{transform:scaleY(.86)}
    16%,82%{transform:scaleY(1.1)}
    100%{transform:scaleY(.86)}
  }

  /* ---- test / skills: nyaris diam.
          Ini keputusan, bukan kelalaian. Saat murid sedang diukur, maskot yang bergerak
          adalah gangguan - jadi yang tersisa hanya napas pada grupnya, dan baloknya
          benar-benar diam. Halaman inilah yang membuktikan sistem geraknya punya
          pendapat, bukan sekadar punya variasi. ---- */
  [data-fz-scene="test"] .fz-paw-bar{animation:none}
}

/* Gerak mati sepenuhnya bila murid memintanya. Marka tetap utuh dan terbaca; tidak ada
   satu pun state yang HANYA bisa dibedakan lewat gerak - lihat titik notifikasi. */
@media (prefers-reduced-motion:reduce){
  .fz-paw,.fz-paw-bar{animation:none !important}
}

/* ==========================================================================
   PAW — kelahiran: partikel meledak, lalu MEMBENTUK marka (m025-129)
   ==========================================================================
   OWNER: "untuk pawnya harusnya ada animasi jangan motion aja, seperti effect particle
   burst, kemudian dari partikel itu terbentuk pawnya baru di lanjutkan oleh motion."

   URUTANNYA, dan kenapa dibagi begini:
     0,00-0,26s  dua belas partikel melesat KELUAR dari titiknya sendiri
     0,26-0,74s  partikel kembali dan mengunci di tempat asalnya
     0,52-0,86s  marka muncul dari balik partikel, sedikit membesar lalu mengendap
     0,74-0,92s  partikel padam
     0,92s ->    gerak per halaman mengambil alih, tanpa jeda

   KUNCINYA ADA DI ARAH ANIMASI, dan ini bagian yang gampang dibuat salah. Partikel di
   sini TIDAK lahir acak lalu mencari tempatnya - cx/cy tiap partikel sudah berdiri
   tepat di simpul bentuk PAW (ujung tiap balok, enam titik keliling bantalan), dan yang
   dianimasikan adalah perjalanan MENJAUH lalu KEMBALI ke nol. Arah sebaliknya - dua
   belas titik acak yang harus dituntun ke posisi akhirnya - akan meleset satu-dua piksel
   pada tiap partikel dan hasilnya terbaca sebagai kotoran, bukan pembentukan.

   Tumpang tindih 0,52-0,74s juga disengaja: marka mulai muncul SEBELUM partikelnya padam,
   jadi mata membaca "partikel menjadi marka", bukan "partikel hilang, lalu marka datang".
   Dua kejadian yang tidak bertumpuk terbaca sebagai dua kejadian.
   -------------------------------------------------------------------------- */

.fz-paw-spark{
  fill:var(--fz-i-line,var(--ink));
  transform-box:fill-box;transform-origin:50% 50%;
  opacity:0;
}
.fz-paw-sparks{pointer-events:none}

@media (prefers-reduced-motion:no-preference){
  .is-paw-born .fz-paw-spark{
    animation:fzPawSpark .92s cubic-bezier(.22,.68,.28,1) var(--sd,0s) 1 both;
  }
  @keyframes fzPawSpark{
    0%   {transform:translate(0,0) scale(.2);opacity:0}
    12%  {opacity:1}
    28%  {transform:translate(var(--sx,0px),var(--sy,-6px)) scale(1);opacity:1}
    74%  {transform:translate(0,0) scale(.85);opacity:1}
    100% {transform:translate(0,0) scale(.3);opacity:0}
  }

  /* Marka menyusul, dan gerak per halaman ditahan sampai ia selesai mengendap -
     kalau tidak, napas 5,2 detik akan bertabrakan dengan transform kelahirannya. */
  .is-paw-born .fz-paw{
    animation:fzPawForm .92s cubic-bezier(.3,1.08,.5,1) 1 both;
  }
  .is-paw-born .fz-paw-bar{animation:none}
  @keyframes fzPawForm{
    0%,52%{transform:scale(.62);opacity:0}
    72%   {transform:scale(1.07);opacity:1}
    100%  {transform:scale(1);opacity:1}
  }
}

/* Tanpa gerak: tidak ada kelahiran sama sekali, marka langsung utuh dan partikelnya
   tidak pernah terlihat. Bukan versi yang lebih cepat - versi yang memang diam. */
@media (prefers-reduced-motion:reduce){
  .fz-paw-spark{display:none}
}

/* ==========================================================================
   Tab bar — satu definisi, bukan enam (m025-129 -> m025-266)
   ==========================================================================
   OWNER (m025-129): "icon taskbarnya terlalu jadul kurang modern dan eye catching."
   OWNER (m025-266): tampilannya masih "kurang".

   Diagnosis m025-266, bukan selera: sebelum blok ini, tab bar didefinisikan oleh ENAM
   blok .bottomnav/.nav yang saling menimpa dari enam redesign berbeda - lebar pil
   560/620/580, ikon 18/24/26/22 px, dan EMPAT definisi keadaan aktif yang menumpuk:
   kapsul kuning + naik 2 px + bayangan 2 px + titik coklat + tebal 700. Hasilnya bukan
   yang dirancang siapa pun, melainkan penulis-terakhir yang menang. Titik coklat di
   bawah label terbaca sebagai noda, dan ikon tidak-aktif berbidang --surface-mute
   (nyaris putih di atas putih) sehingga lima ikon tampil sebagai empat garis + satu
   bidang - bukan satu keluarga.

   Kontrak baru, satu sinyal bentuk + satu sinyal warna:
     - Tab aktif = KAPSUL KUNING (--sun) di belakang ikon, ikon berbidang putih dengan
       garis tinta, label tinta 700. Kapsulnya digambar ::after (penanda bentuk yang
       bekerja tanpa warna - kontrak paw-mascot-test tetap dipegang), dan tab NAIK 3 px.
     - Tab tidak aktif = ikon berbidang --sun-soft (pastel yang TERLIHAT), garis --muted,
       label --muted 600. Kelima ikon kini punya bidang sebanding.
     - Label 12 px: lantai tipografi F2-15, bukan 11 px seperti blok yang dihapus.
   Blok .bottomnav/.nav yang lebih awal di berkas ini SENGAJA tidak dihapus: gerbang
   ui-structure/ux-redesign/a11y membaca literal di sana (glass-solid, z-index:40,
   width:calc(100% - 16px), min-height:44px). Blok ini penulis terakhir untuk semua
   properti yang menentukan rupa.
   -------------------------------------------------------------------------- */

.bottomnav{
  width:min(560px,calc(100% - 24px));padding:6px;gap:2px;
  border:1px solid var(--line);border-radius:var(--radius-xl);
  box-shadow:0 14px 34px -14px rgba(36,26,17,.28),0 1px 2px rgba(36,26,17,.06);
}
.nav,.bottomnav .nav{
  position:relative;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:4px;
  min-height:56px;padding:5px 2px 6px;border:0;border-radius:var(--radius-md);
  font-size:var(--fs-caption);font-weight:600;letter-spacing:.01em;line-height:1.35;color:var(--muted);
  background:transparent;box-shadow:none;
  transition:transform .22s var(--ease-spring),color .16s var(--ease);
}
.nav .fz-i{width:24px;height:24px;position:relative;z-index:1;margin-top:3px;--fz-i-fill:var(--sun-soft);--fz-i-line:var(--muted)}
.nav .fz-i .fz-line{stroke-width:2}
.nav span{position:relative;z-index:1;white-space:nowrap}
.nav:hover{background:transparent}
.nav:active{transform:scale(.95)}
/* Kapsul kuning di belakang ikon. Ukurannya 46x30 - lebih lebar dari ikon 24 px supaya
   terbaca sebagai wadah, bukan sebagai garis tepi ikon. */
.nav.active::after{
  content:"";position:absolute;top:0;left:50%;width:46px;height:30px;margin-left:-23px;
  border-radius:var(--radius-pill);background:var(--sun);z-index:0;
}
.nav.active,.bottomnav .nav.active{
  color:var(--ink);font-weight:700;background:transparent;box-shadow:none;
  transform:translateY(-3px);
}
.nav.active .fz-i,.bottomnav .nav.active .fz-i{--fz-i-fill:var(--panel);--fz-i-line:var(--ink)}

@media (prefers-reduced-motion:no-preference){
  .nav.active .fz-i{animation:fzNavPop .42s cubic-bezier(.3,1.32,.5,1) 1}
  @keyframes fzNavPop{
    0%{transform:scale(.84) translateY(2px)}
    58%{transform:scale(1.12) translateY(-1px)}
    100%{transform:scale(1) translateY(0)}
  }
}
/* ==========================================================================
   KelasKu Wordmark — Brand Typography & Contextual Styling
   Signature Plus Jakarta Sans 800 with emerald/sage #1F7A63 identity.
   ========================================================================== */

.kelasku-wordmark {
  font-family: var(--fz-heading, 'Plus Jakarta Sans', sans-serif) !important;
  font-weight: 800;
  font-style: normal;
  letter-spacing: -0.02em;
  color: #1F7A63 !important;
  display: inline-block;
  line-height: inherit;
  vertical-align: baseline;
  text-decoration: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* --- Bottom Navigation (.bottomnav .nav[data-view="classroom"]) --- */
.bottomnav .nav[data-view="classroom"] .kelasku-wordmark,
.bottomnav .nav .kelasku-wordmark {
  /* Audit F12 (2026-09-23): di nav bawah wordmark mengikuti gaya label tab lain - dulu
     selalu hijau tebal sehingga KelasKu tampak aktif di setiap layar. Hijau + tebal kini
     hanya saat tabnya memang aktif (aturan .active di bawah). */
  font-size: var(--fs-caption, 0.75rem);
  font-weight: inherit;
  line-height: 1.35;
  letter-spacing: -0.02em;
  color: inherit !important;
  white-space: nowrap;
  display: block;
  text-align: center;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  margin: 0;
  transform: none;
  transition: color 0.16s var(--ease, ease), transform 0.22s var(--ease-spring, ease);
}

.bottomnav .nav[data-view="classroom"].active .kelasku-wordmark {
  color: #1F7A63 !important;
  font-weight: 800;
}

.bottomnav .nav[data-view="classroom"].active .fz-i {
  --fz-i-line: #1F7A63;
}

/* Inverted contrast when inside primary/dark buttons or dark containers */
button.primary .kelasku-wordmark,
.btn-primary .kelasku-wordmark,
.btn-teacher .kelasku-wordmark,
.btn-teacher-hero .kelasku-wordmark,
.tg-side .kelasku-wordmark {
  color: #FFFFFF !important;
}

/* ==========================================================================
   Top bar — wordmark telanjang, dua ikon sunyi (m025-267)
   ==========================================================================
   Diagnosis, bukan selera. Sebelum blok ini topbar dirakit tiga berkas: tutor-v3.css
   memberinya radius 18 + border + bayangan + blur (kartu melayang), fiezel-lux.css
   memberinya margin -18px + border-bottom + blur (pita penuh), fiezel-2.css memangkas
   tingginya. Hasilnya pita penuh-lebar dengan sudut membulat dan bayangan - dua ide
   sekaligus, tidak satu pun utuh. Yang lebih fatal: .brand-button tidak dikecualikan
   dari resep "tombol chunky" v6, jadi WORDMARK DUDUK DI DALAM KOTAK PUTIH bergaris,
   sama beratnya dengan chip lonceng dan chip gigi di seberangnya. Tiga benda, tiga
   kotak, satu suara - tidak ada hierarki.

   Kontrak baru:
     - Topbar = PIL LENGKET dengan material yang SAMA dengan tab bar (--glass-solid,
       border --line, --radius-xl, bayangan yang sama): dua pil, atas dan bawah, satu
       keluarga. Tanpa blur (keputusan baterai m025-81 kini berlaku juga di sini);
       --chrome-bg dipekatkan ke .94 untuk pemakai lain yang masih membacanya.
     - Wordmark TELANJANG di atas pil: tidak ada kotak, tidak ada border. Ia satu-
       satunya benda bertinta penuh di baris ini, jadi ia yang menang.
     - Lonceng dan gigi = cakram --panel-soft 44 px tanpa border dan tanpa bayangan:
       hadir, tetapi bicara pelan. Lencana merah di lonceng tetap aksen kuat satu-satunya.
     - Gigi Pengaturan TIDAK boleh disembunyikan: satu-satunya pintu Pengaturan dalam
       mode pelajaran; tiga langkah tur menunjuknya.
   -------------------------------------------------------------------------- */
.topbar{
  position:sticky;top:8px;z-index:35;margin:0 0 18px;padding:6px 8px 6px 16px;min-height:60px;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  background:var(--glass-solid);border:1px solid var(--line);border-radius:var(--radius-xl);
  box-shadow:0 10px 22px -18px rgba(36,26,17,.20),0 1px 2px rgba(36,26,17,.06);
}
.topbar .brand-button{padding:6px 0;margin:0;border:0;border-radius:0;background:transparent;box-shadow:none;min-height:44px}
.topbar .brand-button:hover,.topbar .brand-button:active{transform:none;background:transparent;box-shadow:none}
.topbar .brand{width:100px}
.topbar-actions{gap:4px}
.topbar .icon-button{
  width:44px;height:44px;min-height:44px;padding:0;border-radius:50%;
  background:var(--panel-soft);border:0;box-shadow:none;color:var(--ink);
  transition:background-color var(--dur-s) var(--ease),transform var(--dur-s) var(--ease-spring);
}
.topbar .icon-button svg{width:20px;height:20px}
.topbar .icon-button:hover{background:var(--sun-soft);transform:none;box-shadow:none}
.topbar .icon-button:active{transform:scale(.94)}
.topbar .notif-button.has-new{background:var(--sun-soft)}
.topbar .notif-badge{top:2px;right:2px;box-shadow:0 0 0 2px var(--glass-solid)}
.course-switch-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:6px;
  min-height:38px;
  height:38px;
  padding:0 12px;
  border-radius:20px;
  border:1px solid var(--line);
  background:var(--panel);
  color:var(--ink);
  font-family:inherit;
  font-size:.82rem;
  font-weight:700;
  letter-spacing:.02em;
  box-shadow:var(--shadow-sm);
  cursor:pointer;
  user-select:none;
  -webkit-tap-highlight-color:transparent;
  transition:background-color var(--dur-s) var(--ease),
             border-color var(--dur-s) var(--ease),
             transform var(--dur-s) var(--ease-spring),
             box-shadow var(--dur-s) var(--ease);
}
.course-switch-btn:hover{
  background:var(--panel-soft);
  border-color:var(--surface-edge);
  transform:translateY(-1px);
}
.course-switch-btn:active{
  transform:scale(.94);
  background:var(--accent-soft);
}
.course-switch-btn:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
}
.course-switch-flag{
  font-size:1.05rem;
  line-height:1;
  display:inline-block;
}
.course-switch-label{
  font-size:.78rem;
  font-weight:800;
  letter-spacing:.06em;
  color:var(--ink);
}
.course-switch-btn[data-target-lang="ja"] .course-switch-label{
  color:var(--accent);
}
.course-switch-btn[data-target-lang="en"] .course-switch-label{
  color:var(--accent-strong);
}
@media(max-width:640px){
  .topbar{top:6px;margin:0 0 16px;padding:5px 6px 5px 14px;min-height:56px}
  .topbar .brand{width:92px}
  .course-switch-btn{min-height:36px;height:36px;padding:0 9px;gap:5px}
  .course-switch-flag{font-size:.95rem}
  .course-switch-label{font-size:.74rem}
}
@media(max-width:360px){
  .topbar{padding:5px 4px 5px 10px;gap:6px}
  .topbar .brand{width:80px}
  .course-switch-btn{min-height:34px;height:34px;padding:0 7px;gap:4px}
  .course-switch-label{font-size:.7rem}
  .topbar .icon-button{width:38px;height:38px;min-height:38px}
}

/* ==========================================================================
   Home — kepingan angka menggantikan sapaan serif (m025-129)
   ==========================================================================
   Pita ini menempati baris yang dulu diisi sapaan serif miring. Empat kepingan, dan
   keempatnya angka yang BISA NAIK - itu syaratnya, bukan lencana yang menempel pada
   angka mati.

   Runtun mendapat koral karena ia satu-satunya yang bisa HILANG; cincin harian memakai
   conic-gradient sehingga kemajuannya terbaca sebagai bentuk, bukan sebagai persen yang
   harus dibaca. Sisanya tetap cream supaya keramaiannya tidak pindah tempat saja.
   -------------------------------------------------------------------------- */
.hero-stats{display:flex;flex-wrap:wrap;gap:8px;margin:26px 0 14px}
.hero-stat{
  display:flex;flex-direction:column;gap:1px;
  padding:8px 13px;border-radius:var(--radius-md);
  background:rgba(var(--surface-pure-rgb),.96);border:1.5px solid var(--ink);
  box-shadow:0 2px 0 var(--ink);
  color:var(--ink);
}
/* i12/C3 2026-08-28: keping strip kini bisa <button> (LEVEL, REVIEW) \u2014 warisi tampilan chip. */
button.hero-stat{font:inherit;text-align:left;cursor:pointer}
button.hero-stat:active{transform:translateY(1px)}
@media(max-width:640px){.launcher-copy{min-width:0}.hero-stats{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;max-width:100%;min-width:0}.hero-stats .hero-stat{flex:0 0 auto}}/* v05 2026-08-29: jebakan min-content grid — .launcher-copy menolak menciut di bawah lebar keping, membuat strip bocor 29px keluar viewport 320 dan keping REVIEW tak tergapai; min-width:0 membuat kolom mengalah dan strip menggulir penuh. *//* q16-P2-1: keping tidak boleh menciut — biarkan strip menggulir di 320px */
/* i12/C4: baris trust satu-baris pengganti banner 200px. */
.trust-line{display:flex;gap:var(--sp-2);align-items:baseline;font-size:var(--fs-small);color:var(--accent-strong);margin:var(--sp-2) 0 0}
.hero-stat b{
  display:flex;align-items:center;gap:5px;
  font-size:1.02rem;font-weight:700;line-height:1.15;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;
}
.hero-stat small{font-size:.6rem;letter-spacing:.12em;text-transform:uppercase;font-weight:700;color:var(--muted)}
.hero-stat svg{width:15px;height:15px}
.hero-stat.is-streak{background:var(--sun-soft)}
/* Ikon kecil butuh >=3:1. --sun-deep hanya 1,9:1 di atas sun-soft, jadi tintanya --info. */
.hero-stat.is-streak svg{color:var(--info)}
.hero-stat.is-level{background:var(--sun)}
/* q17-M2: label kecil di atas emas butuh >=4.5:1 — tinta penuh, bukan muted (4.0:1). */
.hero-stat.is-level small{color:var(--ink)}

/* Cincin harian. Sudut conic dihitung dari --v (0-100), jadi satu variabel saja yang
   berpindah dari data ke bentuk - tidak ada perhitungan derajat yang tersebar di JS. */
.hero-ring{
  width:15px;height:15px;border-radius:50%;flex:none;
  background:conic-gradient(var(--ink) calc(var(--v,0) * 1%),rgba(36,26,17,.16) 0);
  -webkit-mask:radial-gradient(circle,transparent 46%,#000 47%);
  mask:radial-gradient(circle,transparent 46%,#000 47%);
}

/* Paragraf yang tersisa dijaga tetap PENDEK, bukan dihapus. Isinya masih berguna; yang
   tidak berguna adalah membiarkannya tumbuh jadi dinding. Batas baris memotong pada
   ukuran layar mana pun, termasuk yang belum ada saat ini ditulis. */
.launcher-lead{
  margin-top:14px;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  line-clamp:2;overflow:hidden;
}
.coach-body{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;
  line-clamp:4;overflow:hidden;
}

@media (max-width:620px){
  .hero-stats{gap:7px;margin:20px 0 12px}
  .hero-stat{padding:7px 11px}
  .hero-stat b{font-size:.94rem}
}

/* ==========================================================================
   Home berhenti terbaca sebagai artikel (m025-131)
   ==========================================================================
   OWNER, sambil menunjukkan layarnya: "masih terlihat seperti bacaan article."

   m025-130 sudah mengganti sapaan serif miring dengan kepingan angka, dan itu benar tapi
   TIDAK CUKUP - karena tepat di bawahnya masih berdiri elemen yang jauh lebih besar:
   judul Instrument Serif dua baris setinggi ~2,5rem, lalu paragraf pengantar di bawahnya,
   lalu kartu Coach berisi paragraf lagi. Kepingan angka kalah telak melawan tiga blok itu.

   Tiga hal yang membuat sebuah layar terbaca sebagai ARTIKEL, dan ketiganya ada di sini:
     - huruf SERIF berukuran display sebagai elemen terbesar di layar;
     - PARAGRAF mengalir - kalimat yang dibaca berurutan, bukan dipindai;
     - tidak ada BATAS antar-blok, sehingga semuanya terbaca sebagai satu kolom bacaan.

   Ketiganya dibalik:
     - judul serif jadi satu baris sans pendek; yang terbesar di layar kini TOMBOL;
     - paragraf pengantar dan paragraf Coach dihapus, bukan diperpendek. Panel Coach
       tinggal satu kalimat, persis yang OWNER tulis di papan edit;
     - strip Coach jadi kartu tersendiri dengan tepi dan bayangan padat, jadi mata
       membacanya sebagai TOMBOL BESAR, bukan sebagai alinea berikutnya.
   -------------------------------------------------------------------------- */

/* Sapaan tinggal satu baris. Sans, bukan serif; ukuran teks, bukan ukuran judul. */
.hero-line{
  font-family:var(--fz-body);font-size:1rem;line-height:1.5;font-weight:600;
  letter-spacing:-.01em;color:var(--ink);margin:2px 0 16px;max-width:38ch;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;
}
.hero-line span{font-weight:700}

/* Strip Coach: satu kalimat, satu tombol besar, satu tautan kecil. */
.coach-strip{
  display:grid;grid-template-columns:auto 1fr;gap:12px 13px;align-items:center;
  padding:16px 18px;border-radius:var(--radius-xl, 22px);
  background:linear-gradient(145deg, rgba(var(--surface-pure-rgb),.98), rgba(254,248,238,.96));
  border:1.5px solid rgba(234,88,12,.22);box-shadow:var(--shadow-md),0 6px 20px -4px rgba(234,88,12,.12);
}
.coach-strip-face{
  width:42px;height:42px;border-radius:50%;
  background:var(--yellow-soft);border:0;box-shadow:var(--shadow-sm);
  display:grid;place-items:center;--fz-i-line:var(--ink);
}
.coach-strip-face svg{width:24px;height:24px}
.coach-strip-say{min-width:0}
.coach-strip-say small{
  display:block;font-size:.6rem;letter-spacing:.13em;text-transform:uppercase;
  font-weight:700;color:var(--muted);margin-bottom:2px;
}
.coach-strip-say b{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;
  font-size:1.02rem;line-height:1.35;font-weight:700;letter-spacing:-.015em;color:var(--ink);
}
/* Tombolnya melintasi dua kolom: di layar ponsel inilah elemen terbesar di Home, dan
   memang harus begitu - yang paling besar di layar seharusnya yang paling ingin ditekan. */
.coach-strip-go{
  grid-column:1/-1;width:100%;min-height:54px;font-size:1.04rem;font-weight:700;
  border-radius:var(--radius-pill, 999px);
  background:linear-gradient(135deg,#EA580C,#C2410C);color:#fff;
  box-shadow:0 8px 24px -4px rgba(234,88,12,.38);
  transition:transform .15s ease,box-shadow .15s ease;
}
.coach-strip-go:active{transform:scale(.98)}
.coach-strip-more{
  grid-column:1/-1;justify-self:center;
  /* Hit area 101x22 sebelum ini - di bawah 44px minimum DIRECTION #6. Padding-nya
     yang tumbuh, bukan tekstunya, jadi tata letak Home tidak bergeser. */
  background:none;border:0;box-shadow:none;padding:10px 14px;min-height:44px;
  color:var(--accent);font-size:.78rem;font-weight:700;
}
.coach-strip-more:hover{background:none;box-shadow:none;transform:none}
.coach-strip-more svg{width:14px;height:14px}

/* Panel peluncur berhenti jadi dua kolom yang tinggi; ia kini setumpuk blok pendek. */
html.fiezel-ui-v6 .launcher-shell{
  grid-template-columns:1fr;grid-template-rows:auto;min-height:0;gap:16px;
  padding:clamp(16px,4vw,22px);
}
@media (min-width:900px){
  html.fiezel-ui-v6 .launcher-shell{grid-template-columns:minmax(0,1fr) minmax(280px,.7fr);align-items:center}
  .coach-strip-go{grid-column:1/-1}
}

/* ==========================================================================
   Logo topbar lahir seperti PAW (m025-131)
   ==========================================================================
   OWNER: "untuk logo fiezel di topbar buatkan animasi persis seperti animasi PAW."

   Persis, dan itu bukan sekadar meniru tampilannya: enam belas partikel di sini juga
   sudah berdiri di simpul HURUFNYA - ujung batang F, siku E, dua ujung Z, dua balok
   aksen - dan yang dianimasikan tetap perjalanan MENJAUH lalu KEMBALI. Alasannya sama
   seperti di PAW: partikel yang lahir acak lalu dituntun ke posisinya akan meleset dan
   terbaca sebagai kotoran, bukan sebagai huruf yang terbentuk.

   Satu perbedaan yang disengaja: durasinya 1 detik, bukan 0,92 detik. Wordmark jauh
   lebih lebar daripada marka PAW, jadi partikelnya menempuh jarak lebih jauh; memakai
   durasi yang sama akan membuatnya terlihat terburu-buru justru pada elemen yang paling
   ingin terlihat tenang.

   Jalannya SEKALI saja saat aplikasi dibuka - keputusan OWNER di papan edit: "Sekali saja
   waktu aplikasi pertama dibuka. Tidak diulang tiap pindah menu - biar tetap terasa
   spesial, bukan jadi kedipan."
   -------------------------------------------------------------------------- */

.fzw-spark{
  fill:var(--wordmark-ink-hi);
  transform-box:fill-box;transform-origin:50% 50%;
  opacity:0;
}
.fzw-mark{transform-box:view-box;transform-origin:500px 130px}

@media (prefers-reduced-motion:no-preference){
  .is-mark-born .fzw-spark{animation:fzwSpark 1s cubic-bezier(.22,.68,.28,1) var(--sd,0s) 1 both}
  @keyframes fzwSpark{
    0%{transform:translate(0,0) scale(.15);opacity:0}
    12%{opacity:1}
    30%{transform:translate(var(--sx,0px),var(--sy,-40px)) scale(1);opacity:1}
    76%{transform:translate(0,0) scale(.9);opacity:1}
    100%{transform:translate(0,0) scale(.25);opacity:0}
  }
  .is-mark-born .fzw-mark{animation:fzwForm 1s cubic-bezier(.3,1.06,.5,1) 1 both}
  @keyframes fzwForm{
    0%,54%{transform:scale(.72);opacity:0}
    74%{transform:scale(1.04);opacity:1}
    100%{transform:scale(1);opacity:1}
  }
}
@media (prefers-reduced-motion:reduce){
  .fzw-spark{display:none}
}

/* Global learner-level contract */
.active-level-control,.home-level-context{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line,#eadfce);border-radius:var(--radius-sm);background:var(--panel,#fff);color:var(--ink,#2E2724);cursor:pointer;box-shadow:none}
.active-level-control{flex:0 0 auto;flex-direction:column;align-items:flex-start;padding:10px 13px;min-width:118px;text-align:left}
.active-level-control span,.active-level-control small{font-size:.66rem;color:var(--muted,#746958);line-height:1.1}
.active-level-control strong{font-size:1rem;line-height:1.1;color:var(--accent,#9B3A4A)}
/* v6.1 (O4 §2.5): glow hover dihapus — umpan balik hover sudah dibawa border-color. */
.active-level-control:hover,.home-level-context:hover{border-color:var(--accent,#9B3A4A);transform:translateY(-1px)}
.home-level-context{padding:4px 9px;font-size:.68rem;font-weight:700;white-space:nowrap}
.level-picker-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px;margin:18px 0}
.level-picker-card{display:grid;gap:5px;min-height:88px;padding:13px;text-align:left;border:1px solid var(--line,#eadfce);border-radius:var(--radius-md);background:var(--panel,#fff);color:var(--ink,#2E2724);cursor:pointer}
.level-picker-card strong{font-size:1.15rem;color:var(--accent,#9B3A4A)}
.level-picker-card span{font-size:.72rem;line-height:1.35;color:var(--muted,#746958)}
.level-picker-card.is-active{border-color:var(--accent,#9B3A4A);background:color-mix(in srgb,var(--accent,#9B3A4A) 8%,var(--panel,#fff));box-shadow:0 0 0 2px color-mix(in srgb,var(--accent,#9B3A4A) 16%,transparent)}
.level-source-note,.level-scope-note,.grammar-level-note{display:flex;flex-wrap:wrap;gap:5px 10px;align-items:baseline;padding:12px 14px;margin:0 0 16px;border-radius:var(--radius-md);background:var(--panel-soft,#f8f1e7);color:var(--ink,#2E2724);font-size:.83rem}
.level-source-note{display:block;margin-top:10px}
.level-source-note b{color:var(--accent,#9B3A4A)}
.level-scope-note span,.grammar-level-note span,.grammar-level-note small{color:var(--muted,#746958)}
.grammar-level-note{display:grid;gap:4px}
.grammar-level-note b{color:var(--accent,#9B3A4A)}
.skill-level-note{margin-top:10px;font-size:.82rem;color:var(--muted,#746958)}
.skill-level-note b{color:var(--accent,#9B3A4A)}
@media(max-width:620px){
  .section-head{align-items:flex-start;flex-direction:column}
  .section-head .active-level-control{align-self:stretch;flex-direction:row;align-items:center;justify-content:space-between}
  .level-picker-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .home-level-context{font-size:.62rem}
}
/* m025-137: lesson yang prasyaratnya belum tuntas. Kartunya sengaja tetap terbaca -
   murid perlu melihat apa yang menunggunya di depan, bukan menemukan daftar yang kosong. */
.card.lesson-locked{opacity:.72}
/* warna sudah datang dari resep button:disabled; opacity dilepas supaya tidak dobel-pudar */
.card.lesson-locked .lesson-card-foot button[disabled]{cursor:not-allowed;opacity:1}
.lesson-lock-note{display:flex;gap:7px;align-items:flex-start;margin:8px 0 0;font-size:.78rem;line-height:1.4;color:var(--muted,#746958)}
.lesson-lock-note i{flex:none;width:14px;height:14px;margin-top:2px}
/* m025-138: kontrak ujian dan rubrik Writing. Batas kata sengaja dibuat menonjol -
   di IELTS, tulisan di bawah batas kena penalti sebelum isinya sempat dinilai. */
.writing-exam{display:grid;gap:3px;margin:0 0 10px;padding:11px 13px;border-radius:var(--radius-sm);background:var(--panel-soft,#f8f1e7);font-size:.8rem}
.writing-exam b{color:var(--accent,#9B3A4A)}
.writing-exam span{font-weight:600}
.writing-exam small{color:var(--muted,#746958);line-height:1.4}
.writing-focus{margin:6px 0 0;font-size:.78rem;color:var(--muted,#746958)}
.writing-rubric ul,.writing-checklist{display:grid;gap:8px;margin:10px 0 0;padding:0;list-style:none}
.writing-rubric li{display:grid;gap:2px;font-size:.8rem}
.writing-rubric li span{color:var(--muted,#746958)}
.writing-checklist li{display:grid;gap:2px;padding:9px 11px;border-radius:var(--radius-sm);border-left:3px solid var(--line,#eadfce);background:var(--panel-soft,#f8f1e7);font-size:.79rem}
.writing-checklist li span{color:var(--muted,#746958);line-height:1.45}
.writing-check.is-ok{border-left-color:#3f8f5f}
.writing-check.is-perhatikan{border-left-color:var(--accent,#9B3A4A)}
.writing-check.is-ai{border-left-color:#7a6cc4}
/* m025-139: jalur Reading berformat ujian. Kontraknya (panjang, jumlah soal, waktu)
   ditaruh di muka karena itulah yang membedakannya dari bacaan latihan biasa. */
.reading-exam{display:grid;gap:11px;margin:0 0 16px}
.reading-exam-set{display:grid;gap:4px;padding:12px 13px;border-radius:var(--radius-sm);background:var(--panel-soft,#f8f1e7)}
.reading-exam-set span{font-size:.75rem;font-weight:600;color:var(--accent,#9B3A4A)}
.reading-exam-set small{font-size:.74rem;line-height:1.45;color:var(--muted,#746958)}
.reading-exam-set button{justify-self:start;margin-top:5px}


/* ==========================================================================
   FASE 2 — komponen BARU dari design/redesign-v1/components (§9 hint, §10 audio,
   §13 field). Belum ada markup yang memanggilnya; resepnya ditulis di sini supaya
   layar Fase 3 tidak menulis ulang tiga kali dengan tiga nilai berbeda.
   ========================================================================== */
/* §9 panel petunjuk bertahap — nomor langkah, bukan paragraf jawaban */
.hintpanel{background:var(--panel);border:1.5px solid var(--line);border-radius:var(--radius-md);
  padding:14px 16px;display:grid;gap:10px}
.hint-step{display:flex;align-items:center;gap:10px;font-size:14px;color:var(--text)}
.hint-step .hint-num{width:24px;height:24px;border-radius:50%;display:grid;place-items:center;
  font-size:var(--fs-caption);font-weight:700;background:var(--panel-soft);color:var(--muted);
  border:1.5px solid var(--line)}
.hint-step.is-done .hint-num{background:var(--sun-soft);border-color:var(--sun);color:var(--text)}
.hint-step.is-current .hint-num{background:var(--text);border-color:var(--text);color:var(--on-core)}
.hint-step.is-locked{color:var(--muted)}
.hint-step.is-locked .hint-num{background:var(--panel-soft);color:var(--muted)}

/* §10 pemutar audio + equalizer */
.audioplayer{display:flex;align-items:center;gap:12px;background:var(--panel);
  border:1.5px solid var(--line);border-radius:var(--radius-lg);padding:12px 16px}
.eq{display:flex;align-items:flex-end;gap:3px;height:22px}
.eq i{width:4px;border-radius:2px;background:var(--sun);height:100%;
  animation:eq .9s var(--ease) infinite alternate}
.eq i:nth-child(2){animation-delay:.15s}
.eq i:nth-child(3){animation-delay:.3s}
.eq i:nth-child(4){animation-delay:.45s}
@keyframes eq{from{transform:scaleY(.55)}to{transform:scaleY(1)}}
@media (prefers-reduced-motion:reduce){.eq i{animation:none;transform:scaleY(.8)}}

/* §13 field — tinggi 48px, cincin fokus satu resep, state error/success by teks+warna */
.field{display:grid;gap:6px}
.field label{font-size:var(--fs-caption);font-weight:600;color:var(--muted)}
.field input,.field textarea,.field select{min-height:48px;padding:12px 14px;
  border:1.5px solid var(--line);border-radius:var(--radius-sm);background:var(--panel);
  color:var(--text);font:inherit}
.field input:focus-visible,.field textarea:focus-visible,.field select:focus-visible{
  outline:2px solid var(--focus-ring);outline-offset:2px;border-color:var(--focus-ring)}
.field.is-error input{border-color:var(--bad)}
.field.is-error .field-msg{color:var(--bad);font-size:var(--fs-caption)}
.field.is-success input{border-color:var(--good)}
.field.is-success .field-msg{color:var(--good);font-size:var(--fs-caption)}
.field input:disabled{background:var(--panel-soft);color:var(--text-disabled)}


/* ==========================================================================
   FASE 2 F2-15 — LANTAI 12px. DIRECTION Tipografi: "tak ada teks <12px".
   Blok ini APPEND dan keyed-by-selector, bukan tiga puluh suntingan tersebar:
   satu tempat untuk dibaca, satu tempat untuk dicabut. Pelanggar terverifikasi
   berkisar .6rem-.74rem (9,6-11,8px); tidak ada satu pun yang MENGECIL karena
   blok ini - yang terbesar sebelumnya 11,84px.
   ========================================================================== */
.version,
.stats small,.home-stats small,
.auth-legal,
.confidence-scale button,
.launcher-meta,
.mission-ring span,
.launch-card small,
.welcome-mark,.modal-mark,
.lesson-example>span,.lesson-card-foot>span,
.skill-badge,.skill-ring b,
.fz-coach-head small,
.tutor-turn-head,.tutor-card-head small,
.hero-stat small,
.coach-strip-say small,
.active-level-control span,.home-level-context,
.swipe-hint,
.setting-row small,
.endpoint-label,.setup-link,.consent-row,
.journey-week,.journey-week small,.journey-day small,.journey-skill small,
.journey-mission small,.journey-today small,.journey-goal small,
.journey-why,.journey-note,.journey-block span,.journey-skill span,.journey-recovery,
.fiezel-splash-tag,
.coach-level span{
  font-size:12px;
}
/* Dua pelanggar memaku ukurannya dengan !important, jadi lantainya harus sama keras. */
.notification-help,.report-state{font-size:var(--fs-caption)!important}
/* Label huruf besar yang membesar: tracking dirapatkan supaya tidak memaksa baris kedua. */
.launcher-meta,.skill-badge,.tutor-turn-head{letter-spacing:.08em}
.fiezel-splash-tag{letter-spacing:.11em}

/* ==========================================================================
   FASE 2 F2-14 — ikon state toast. Dua nilai di bawah adalah SATU-SATUNYA
   literal baru fase ini (asal: design/redesign-v1/components). Keduanya tinta
   di atas permukaan --core yang gelap, jadi mereka memang harus terang dan
   TIDAK boleh memakai --good/--bad (keduanya gelap, 1,3:1 di atas core).
   Ganti ke var() bila Fase 3 menambahkan --good-on-core/--bad-on-core.
   ========================================================================== */
.toast.is-good .toast-icon{color:#7ED9AE}
.toast.is-bad .toast-icon{color:#F0907B}

/* ==========================================================================
   FASE 2 F2-13 — .toggle (components.css §14). Belum ada markup pemanggil;
   settings di-reskin di Fase 3. Track 52x32, knob 25px, is-on = tinta + knob sun.
   ========================================================================== */
.toggle{position:relative;width:52px;height:32px;border-radius:var(--radius-pill);
  background:var(--line);border:0;cursor:pointer;transition:background var(--dur-s) var(--ease)}
.toggle::after{content:"";position:absolute;top:3.5px;left:4px;width:25px;height:25px;
  border-radius:50%;background:var(--panel);box-shadow:0 1px 3px rgba(36,26,17,.25);
  transition:transform var(--dur-s) var(--ease)}
.toggle.is-on{background:var(--text)}
.toggle.is-on::after{background:var(--sun);transform:translateX(19px)}
.toggle:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}

/* ==========================================================================
   FASE 2 — wajah display bulat pada TEKS DISPLAY BESAR (DIRECTION Tipografi).

   DEVIASI SADAR, dan ini batas yang dipilih dengan sengaja. Aturan display
   eksisting menyatukan .section-head h1 dengan .welcome-panel h2/.modal-panel h2/
   .fiezel-title dalam SATU selector, dan aturan itu dipaku oleh
   splash-choreography-test: wordmark + judul dialog harus tetap Instrument Serif
   berat 400. Memecah selector itu supaya .section-head h1 bisa pindah ke Fredoka
   berarti membongkar kontrak koreografi untuk keuntungan kosmetik di satu judul.
   Jadi judul-seksi tetap serif, dan Fredoka dipasang pada dua permukaan display
   yang TIDAK ikut aturan itu dan BENAR-BENAR ADA di markup: kata besar kartu
   kosakata (.word, 2,6rem) dan judul lesson grammar (.lesson-title, 1,55rem).
   Keduanya diperiksa di app.js, bukan diasumsikan - .hero h2 dan .empty-state h2
   sempat masuk daftar ini lalu dikeluarkan karena TIDAK ADA elemennya: .hero cuma
   punya turunan -line/-ring/-stat, dan .empty-state punya CSS tanpa pemanggil.
   Di dua ukuran itu kebulatan Fredoka terbaca sebagai kehangatan; di ukuran UI
   ia hanya jadi kabur.
   ========================================================================== */
/* m028-06 (R4 Pengaturan) — kelompok setting yang bisa dilipat + footer aksi sticky.
   Panel Pengaturan dulu 3.362 px dalam jendela 743 px: ±4,5 layar untuk sampai ke tombol
   Simpan. Pembungkusnya numpang .home-fold (satu bahasa visual dengan Home) dan hanya
   menambahkan padding isi; tinggi awal keadaan tertutup turun ke bawah 900 px. */
.settings-fold{margin:8px 0 0;text-align:left}
.settings-fold>summary{font-size:.9rem}
.settings-fold-body{padding:12px 14px 14px}
.settings-fold-body>.settings-list{margin-top:0}
.settings-fold-body>.card:first-child,.settings-fold-body>.report-settings:first-child{margin-top:0}
/* Kepala panel dibuat sekecil mungkin: judul modal utilitas tidak perlu setinggi judul
   halaman konten, dan setiap piksel di sini adalah piksel yang tidak dipakai setting. */
.settings-head{margin-bottom:2px}
.settings-head h2{font-size:1.35rem;margin:6px 0 4px}
.settings-head p{font-size:.82rem;line-height:1.45}
/* Isi kelompok dirapatkan - microcopy panjang (§3 reports/ui-baseline.md) yang paling
   banyak memakan tinggi, bukan kontrolnya. Ukuran sentuh 44px tidak ikut dikecilkan. */
.settings-fold-body .card,.settings-fold-body .report-settings{padding:14px}
.settings-fold-body p.muted{font-size:.78rem;line-height:1.45;margin:4px 0}
.settings-fold-body .account-card .actions{display:flex;gap:8px}
.settings-fold-body .account-card .actions button{flex:1;min-width:0}
.settings-fold-body>.settings-list{gap:0}
.settings-subfold{margin:10px 0 0;background:var(--panel-soft)}
.settings-subfold>summary{font-size:.84rem}
.settings-subfold .card{border:0;padding:0;background:transparent}
/* Aksi utama tidak boleh ikut tergulung: ia menempel di dasar panel yang bisa di-scroll.
   Latar dan garisnya diambil dari token tema yang sama dengan panelnya, bukan literal
   terang - kalau dipaku, teks tombol ikut hilang persis seperti akar bug m025-85.

   m025-165 AKAR BUG FOOTER MENIMPA "Lanjutan":
   1. margin-bottom NEGATIF (-32px / -26px). #modalPanel adalah scroller-nya sendiri, dan
      elemen sticky DIJEPIT di dalam content box induknya - bukan di padding box. Margin
      negatif itu memendekkan scrollHeight sebesar padding bawah panel, sehingga posisi
      alir footer jatuh 26px DI BAWAH batas jepitan sticky. Hasilnya bar tidak pernah bisa
      turun ke dasar: ia tertahan melayang di atas elemen terakhir dan menutupi ekor fold
      "Lanjutan" walau sudah digulir habis (terukur 10px iris di 390x844).
   2. Ukurannya. Footer memakai .modal-actions button{flex:1;min-width:120px} + padding
      tombol global 13px 18px, jadi "Simpan pengaturan" membungkus dua baris: tombol 70px,
      bar 95px. Itu blok, bukan taskbar.

   OBAT: margin bawah dinolkan (footer kembali jadi elemen alir terakhir -> jepitan sticky
   dan posisi alir berhimpit, iris 0 selamanya), tinggi dipatok setara pita .bottomnav
   (min-height 58px, padding 7px seperti padding pill nav), dan tombolnya diperlakukan
   seperti .nav: satu baris, 44px sasaran sentuh, tanpa membungkus. */
.modal-actions.settings-actions{
  position:sticky;bottom:0;z-index:6;
  display:flex;align-items:center;gap:8px;
  margin:14px -26px 0;
  padding:7px 26px calc(7px + env(safe-area-inset-bottom,0px));
  min-height:58px;box-sizing:border-box;
  background:var(--glass-solid,var(--panel));
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  border-top:1px solid var(--line);
  box-shadow:0 -6px 16px rgba(36,26,17,.07)
}
/* Tombol footer mengikuti ukuran tombol navigasi, bukan tombol aksi halaman: 44px sasaran
   sentuh tetap dihormati (kontrak a11y), tetapi paddingnya tidak lagi menumpuk di atasnya
   dan labelnya dipaksa satu baris supaya tinggi bar tidak pernah dua kali lipat. */
.modal-actions.settings-actions button{
  flex:1 1 0;min-width:0;min-height:44px;height:44px;
  padding:0 12px;font-size:.86rem;line-height:1.2;white-space:nowrap;
  border-radius:var(--radius-sm)
}
/* Audit 04-001: di 320px "Simpan pengaturan" (nowrap, tombol 122px) mencat teksnya KELUAR
   kotak dan menimpa "Batal". Di layar sesempit itu labelnya diizinkan membungkus DI DALAM
   tombolnya sendiri: dua baris .86rem masih muat di sasaran 44px, jadi kontrak m025-165
   (bar satu baris setinggi 58px) tetap utuh - teksnya saja yang tidak lagi kabur. */
@media (max-width:340px){.modal-actions.settings-actions button{white-space:normal;height:auto}}
/* Panel diberi dasar rata supaya bar benar-benar duduk di dasar modal, dan scroll-padding
   sebesar bar supaya elemen yang di-fokus/di-scroll-into-view tidak berhenti di baliknya. */
.modal-panel:has(.modal-actions.settings-actions){padding-bottom:0;scroll-padding-bottom:58px}
.settings-fold:last-of-type{margin-bottom:0}
@media(max-width:520px){
  .modal-actions.settings-actions{bottom:0;margin:12px -20px 0;padding:7px 20px calc(7px + env(safe-area-inset-bottom,0px));min-height:56px}
  .modal-panel:has(.modal-actions.settings-actions){scroll-padding-bottom:56px}
}

.word,
.lesson-title{
  font-family:var(--fz-display-round);
  font-weight:600;
  letter-spacing:-.01em;
}
/* m025-166 AKAR GANDA (ditemukan dua fixer secara independen): kurung tutup di atas ini
   HILANG sejak merge Fase 2/Fase 3. Seluruh ekor berkas (±240 baris blok FASE3 + semua
   gaya level guard) terbaca sebagai aturan bersarang di dalam ".word, .lesson-title" dan
   dibuang parser - itu sebabnya ikon Peta jadi 300px (aturan .map-row .mi svg 14px mati)
   dan animasi popup gerbang level tidak pernah jalan. Kurungnya kini ditutup; jangan
   dihapus lagi. */
/* ==========================================================================
   ===== FASE3 =====
   Blok terpisah di akhir berkas, dengan sengaja. Fase 2 sedang mengedit blok
   atas (palet :root, tombol, .option, nav bawah, kartu). Seluruh tambahan
   Fase 3 tinggal di bawah marker ini supaya dua rangkaian patch tidak pernah
   bertengkar atas baris yang sama; urutan cascade juga menguntungkan kita —
   restyle di sini menang tanpa perlu !important.
   ========================================================================== */
/* F17: token blok ini pindah ke :root tunggal di awal berkas. */

/* ---------- §9.2 toast: ikon + sejajar ----------
   Warna toast (permukaan --core, tinta --on-core) sudah dipasang Fase 2 di blok
   atas; yang ditambahkan di sini hanya tata letaknya supaya ikon dan teks duduk
   satu baris, dan teks panjang membungkus rata kiri alih-alih rata tengah. */
.toast{display:flex;align-items:center;gap:8px;text-align:left}
.toast .toast-mark{flex:0 0 auto;color:var(--sun)}

/* ---------- §1/§9.1 panel ANALYZING ----------
   Permukaan gelap yang sengaja: ia satu-satunya bidang di layar kuis yang bukan
   kertas, jadi murid tahu yang sedang bicara adalah mesinnya. Tinta --on-core di
   atas --core = 14,7:1; ukuran terkecil .core-eyebrow 12px (.75rem). */
.core-panel{position:relative;overflow:hidden;background:var(--core);border-radius:var(--radius-lg);padding:18px;color:var(--on-core)}
.core-panel .neural{position:absolute;inset:0;width:100%;height:100%;opacity:.5;pointer-events:none;color:var(--sun)}
.core-panel>div{position:relative}
.core-eyebrow{font-size:.75rem;font-weight:700;letter-spacing:.18em;color:var(--sun)}
.core-title{margin-top:6px;font-size:1rem;font-weight:700;color:var(--on-core)}
.core-sub{margin-top:5px;font-size:.82rem;line-height:1.5;color:var(--on-core-muted)}
.core-bar{position:relative;margin-top:14px;height:5px;border-radius:var(--radius-pill);background:rgba(253,250,243,.22);overflow:hidden}
.core-bar i{position:absolute;inset:0 auto 0 0;width:46%;border-radius:var(--radius-pill);background:linear-gradient(90deg,var(--sun),var(--sun-deep))}
.core-bar::after{content:"";position:absolute;inset:0 auto 0 0;width:18%;border-radius:var(--radius-pill);background:rgba(253,250,243,.35);animation:coreScan 1.6s var(--ease) infinite}
/* i15 2026-08-29 (audit 12-004): coreScan dulu menganimasikan `left` — layout ulang tiap
   frame, selamanya, di Home. Kini translateX di kanal kompositor. Visual identik: elemen
   selebar 18% kontainer dengan left:0 statis; left:-18%≡translateX(-100%), left:100%≡
   translateX(555.6%) (100/18 lebar elemen). */
@keyframes coreScan{from{transform:translateX(-100%)}to{transform:translateX(555.6%)}}
.core-panel :focus-visible{outline:2px solid var(--focus-ring-on-core);outline-offset:2px}
.core-analyzing{margin:12px 0}
/* Sapuan pemindai adalah satu-satunya gerak di panel ini, jadi ia yang dimatikan -
   panelnya sendiri tetap tampil supaya sebab-akibatnya tidak hilang. */
@media (prefers-reduced-motion:reduce){.core-bar::after{animation:none;display:none}}

/* ---------- §8/§9.3 aturan dock maskot ----------
   Gelembung pembimbing tetap tinggal di <body> dan tetap bisa diketuk di mana pun
   (kontrak m025-115). Yang berubah hanya di dua panggung latihan: sapaan otomatis
   dibungkam supaya tidak ada balon yang menutup soal, gelembungnya mengecil dan
   turun keluar dari kolom konten, dan elemen interaktif terakhir diberi ruang
   napas supaya selalu bisa digulir lepas dari bayangan gelembung.
   Z-index tidak diubah: .fz-coach-sheet dan #confidencePop tetap menang. */
body.fz-stage-quiz .fz-coach-peek,
body.fz-stage-sl .fz-coach-peek,
body.fz-stage-hub .fz-coach-peek,/* q16-P2-2: hub punya CTA dekat dasar layar juga */
body.fz-stage-map .fz-coach-peek,
body.fz-stage-writing .fz-coach-peek{display:none}
body.fz-stage-writing .fz-coach-bubble{display:none}/* v24-F2 2026-08-29: FAB 58px menutupi textarea Writing di 390 (42x58px) \u2014 layar mengarang bebas gangguan, coach tetap ada di view lain. */
/* i12/C5 2026-08-28 (O6 "satu Pau di Home"): di Home, Pau hero coach-strip adalah satu-satunya
   Pau; gelembung FAB + peek disembunyikan penuh (bukan diciutkan seperti sl/map). */
body.fz-stage-home .fz-coach-peek,
body.fz-stage-home .fz-coach-bubble{display:none}
/* i12/C2: chip celestial hanya bermakna di layar lega \u2014 desktop-only. */
@media(max-width:899px){.home-page .celestial-status{display:none}}
/* i12/C6: judul seksi Home tidak boleh membawa kotak fokus programatik.
   [i15 2026-08-29] Ditulis ulang agar lolos gerbang a11y "outline:none butuh pengganti":
   outline mati di level elemen, lalu :focus-visible mengembalikan cincin standar —
   fokus programatik (tabindex=-1) tetap tanpa kotak, fokus keyboard tetap terlihat. */
.home-section-head h2{text-wrap:balance;outline:none}
.home-section-head h2:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
body.fz-stage-quiz .fz-coach-bubble,
body.fz-stage-sl .fz-coach-bubble,
body.fz-stage-hub .fz-coach-bubble,
body.fz-stage-map .fz-coach-bubble{width:46px;height:46px;bottom:calc(92px + env(safe-area-inset-bottom))}/* v24-F1 2026-08-29: 88px membuat FAB menyerempet tab Peta 1px di 390 \u2014 dinaikkan 4px. */
body.fz-stage-quiz .fz-coach-bubble .fz-coach-face,
body.fz-stage-sl .fz-coach-bubble .fz-coach-face,
body.fz-stage-hub .fz-coach-bubble .fz-coach-face,
body.fz-stage-map .fz-coach-bubble .fz-coach-face{width:24px;height:24px}
/* Ruang bawah supaya kartu terakhir Peta Belajar bisa lewat di atas pita dok. */
body.fz-stage-map .app{padding-bottom:104px}
body.fz-stage-quiz .quiz-shell{padding-bottom:96px}

/* ---------- m028 fase4: gelembung pindah ke kanan-ATAS di panggung ber-panel-bawah ----------
   AKAR: mengecilkan gelembung tidak memindahkannya keluar dari lajur kanan-bawah, dan lajur
   itu sudah dipakai bar aksi yang dipaku ke dasar layar - .fsl-actions (z55, bottom 76) di
   Skills Lab dan panel NEXT SESSION di Peta. Terukur di 390x844: gelembung 46x46 menimpa
   ujung kanan tombol "Lanjut" 46x37 px, dan begitu subtitle (z70) atau voice-pill (z60)
   muncul giliran gelembungnya yang tertutup.
   OBAT: saat panggung ber-panel-bawah aktif, gelembung berpindah ke kanan-atas, di bawah
   topbar (sticky, tinggi 62px + offset 6px; 88px membebaskannya baik saat diam maupun saat
   menempel). Memakai bendera body-class yang SUDAH di-toggle renderInner() - nol perubahan JS,
   kontrak m025-115 (gelembung anak <body>) tidak tersentuh.
   fz-stage-quiz TIDAK ikut: tombol "Lanjut" kuis justru ada di kanan-ATAS (#quizNext di
   .quiz-topbar sticky), jadi memindahkannya ke atas di kuis hanya menukar satu tabrakan
   dengan tabrakan baru. Yang dianimasikan hanya transform+opacity - top/bottom tidak pernah
   ikut, supaya perpindahannya tidak memaksa layout ulang tiap frame. */
@media (max-width:767px){/* v24-F3 2026-08-29: relokasi kanan-atas hanya untuk layar sempit \u2014 di >=768 top:88px justru menimpa kontrol "Level belajar" (terukur 40x13/40x22px), sedangkan lajur kanan-bawah di 768 terbukti bersih (gutter nav 74px). */
body.fz-stage-sl .fz-coach-bubble,
body.fz-stage-map .fz-coach-bubble{
  bottom:auto;
  top:calc(88px + env(safe-area-inset-top,0px));
  animation:fzCoachRelocate .28s var(--ease-spring) both;
}
}
@keyframes fzCoachRelocate{
  from{opacity:0;transform:translateY(-10px) scale(.9)}
  to{opacity:1;transform:none}
}
@media (prefers-reduced-motion:reduce){
  body.fz-stage-sl .fz-coach-bubble,
  body.fz-stage-map .fz-coach-bubble{animation:none}
}
body.reduce-motion.fz-stage-sl .fz-coach-bubble,
body.reduce-motion.fz-stage-map .fz-coach-bubble{animation:none}

/* ---------- O2/i7 lesson-mode: sesi tanpa gangguan ----------
   Selama stage pelajaran aktif (body.fz-lesson-mode disetel HANYA oleh syncLessonMode
   di modul stage app.js - turunan murni stageStack) SEMUA krom global minggir; yang
   tersisa cuma header sesi minimal (.quiz-topbar / .topline). display:none dipilih atas
   visibility:hidden karena .topbar in-flow: ruangnya harus ikut hilang. */
body.fz-lesson-mode main.app>.topbar{display:none}
body.fz-lesson-mode .nav-scrim{display:none}
/* Aturan .bottomnav SENGAJA berdiri sendiri: ui-structure-test menggabungkan semua blok
   .bottomnav{...} dan menolak backdrop-filter - blok satu-properti ini lolos apa adanya. */
body.fz-lesson-mode .bottomnav{display:none}
/* padding bawah .app tidak perlu lagi menyisakan 118px untuk pill nav.
   main.app (bukan .app): html.fiezel-ui-v6 .app di tutor-v3.css dimuat SETELAH berkas ini
   dengan spesifisitas sama - selektor ini harus menang tanpa !important. */
body.fz-lesson-mode main.app{padding-bottom:calc(28px + env(safe-area-inset-bottom))}
/* Pau ganda: gelembung pembimbing menyingkir - kuis sudah punya Paw-nya sendiri
   (quiz-mascot / PawSlot). Kontrak m025-115 (anak <body>) tidak tersentuh. */
body.fz-lesson-mode .fz-coach-bubble,
body.fz-lesson-mode .fz-coach-peek{display:none}
/* ruang 96px untuk gelembung (aturan fz-stage-quiz di atas) tidak diperlukan lagi */
body.fz-lesson-mode.fz-stage-quiz .quiz-shell{padding-bottom:28px}
/* toast tidak lagi melayang 96px di atas nav yang sudah tidak ada */
body.fz-lesson-mode .toast{bottom:calc(24px + env(safe-area-inset-bottom))}
/* Header flashcards/ulangan (.topline) disatukan ke kontrak header sesi yang sama:
   sticky + memikul safe-area atas, karena topbar global yang dulu memikul notch hilang. */
body.fz-lesson-mode .topline{position:sticky;top:0;z-index:30;
  padding:max(10px,env(safe-area-inset-top)) 0 10px;margin-bottom:12px;
  background:rgba(var(--bg-rgb),.9);backdrop-filter:blur(14px)}

/* ---------- §2 kuis: benar / salah / pijakan ----------
   Banner benar-salah, kartu sebab, dan tip ingatan SUDAH ada 1:1 di reveal(); yang
   kurang cuma dua hal yang bisa dibaca dalam sekejap: mana jawaban yang benar, dan
   mana yang tadi dipilih. Keduanya dipasang sebagai pseudo-element - nol perubahan
   pada answer()/reveal(), jadi tidak ada kontrak markup yang bergeser. */
.option.correct::after,
.option.wrong::after{
  display:inline-flex;align-items:center;justify-content:center;margin-left:auto;margin-top:0;padding:3px 9px;border-radius:var(--radius-pill);
  font-size:.75rem;font-weight:700;letter-spacing:.08em;white-space:nowrap;flex:none
}
/* G12: Pertahankan tata letak baris (row), badge di sisi kanan - mencegah tinggi kartu melompat */
.option.correct,.option.wrong{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:12px}
.option.correct::after{content:"BENAR";background:var(--good);color:var(--on-core)}
.option.wrong::after{content:"PILIHANMU";background:var(--bad);color:var(--on-core)}
:lang(th) .option.correct::after{content:"ถูกต้อง"}
:lang(th) .option.wrong::after{content:"คำตอบของคุณ"}
/* Tanda netral .tried-tag disuntikkan secara dinamis & terlokalisasi di app.js; ::after dinonaktifkan agar tidak ada double badge */
.option.was-tried::after{display:none !important;content:none !important}
.option.was-tried:disabled{border-color:var(--line);background:var(--panel-soft);color:var(--muted)}

/* m025-429 — Scaffold Nudge Banner: tampil DI ATAS opsi saat salah pertama.
   Warna hangat (bukan merah agresif) supaya terasa dorongan, bukan hukuman.
   Animasi masuk dari atas: slide-in + fade, sekali saja. */
.scaffold-nudge{display:flex;align-items:center;gap:10px;padding:12px 16px;
  margin-bottom:10px;border-radius:var(--radius-md);font-size:.92rem;font-weight:600;
  line-height:1.5;color:var(--ink);background:var(--surface-tint);
  border:1px solid var(--sun);border-left:3px solid var(--sun);
  opacity:0;transform:translateY(-12px);
  animation:scaffold-nudge-in .4s cubic-bezier(.16,1,.3,1) .1s forwards}
.scaffold-nudge svg{width:18px;height:18px;flex:0 0 auto;color:var(--sun-deep)}
@keyframes scaffold-nudge-in{to{opacity:1;transform:translateY(0)}}

/* Glow pulse pada opsi yang masih bisa dipilih saat retry.
   Pulse halus supaya menarik mata tanpa mengganggu konsentrasi. */
.option.retry-available{border-color:var(--accent)!important;
  animation:retry-glow 2s ease-in-out .5s infinite;
  box-shadow:0 0 0 2px rgba(234,88,12,.12)}
@keyframes retry-glow{
  0%,100%{box-shadow:0 0 0 2px rgba(234,88,12,.12)}
  50%{box-shadow:0 0 0 5px rgba(234,88,12,.22)}}
/* Glow dihentikan begitu opsi diklik (was-tried menang atas retry-available) */
.option.was-tried.retry-available{animation:none;box-shadow:none;border-color:var(--line)!important}

/* Floating retry bar: mengganti tombol "Lanjut" yang disabled saat retry.
   Berbagi z-index dan posisi dengan .quiz-floating-bar. */
.quiz-floating-retry{justify-content:space-between;padding:10px 16px;gap:12px;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-pill,999px);
  box-shadow:0 4px 16px -2px rgba(36,26,17,.18);max-width:480px;margin:0 auto;width:calc(100% - 32px)}
.retry-bar-label{display:flex;align-items:center;gap:8px;font-weight:600;font-size:.88rem;
  color:var(--accent);white-space:nowrap}
.retry-bar-label svg{width:18px;height:18px;flex:0 0 auto}
.retry-giveup-btn{min-height:36px;padding:6px 14px;border-radius:var(--radius-sm);
  font-size:.8rem;font-weight:600;background:transparent;border:1px solid var(--line);
  color:var(--muted);cursor:pointer;white-space:nowrap;transition:background .15s ease}
.retry-giveup-btn:active{background:var(--panel-soft)}

/* Shake halus pada opsi salah — sekali, 400ms. */
@keyframes option-wrong-shake{
  0%,100%{transform:translateX(0)}
  15%,45%,75%{transform:translateX(-3px)}
  30%,60%,90%{transform:translateX(3px)}}
.option.was-tried{animation:option-wrong-shake .4s ease}

/* Rincian pengecoh dulu selalu terbentang. Pada soal empat pilihan itu empat paragraf
   tambahan tepat di bawah kesimpulan yang justru paling penting dibaca; sekarang ia
   terlipat dan dibuka kalau memang mau dibandingkan. */
.acc{margin-top:10px;border-top:1px dashed var(--line);padding-top:8px}
.acc>summary{cursor:pointer;font-size:.8rem;font-weight:700;color:var(--muted);list-style:none}
.acc>summary::-webkit-details-marker{display:none}
.acc>summary::after{content:"\2304";margin-left:6px;font-weight:700}
.acc[open]>summary::after{content:"\2303"}
.acc>summary:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px;border-radius:var(--radius-xs)}
.acc .distractor-breakdown{margin-top:2px;border-top:0;padding-top:0}

/* Tombol Lanjut yang terkunci: Fase 2 sudah membuat tintanya terbaca (4,8:1). Yang
   ditambahkan di sini adalah SEBABNYA - gembok, supaya "belum bisa" tidak perlu
   ditebak dari warna. Digambar lewat CSS mask agar markup draw() tetap utuh. */
.quiz-next:disabled::before{
  content:"";width:13px;height:13px;flex:0 0 auto;background:currentColor;
  -webkit-mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E") center/contain no-repeat
}

/* Kartu ajar-ulang dan pijakan: aksennya lepas dari marun kontrol dan pindah ke
   keluarga sun, sekeluarga dengan panel FIEZEL. Nama kelas tidak ada yang berubah -
   tests/tutor-reteach-card-test.js dan tests/tutor-classroom-regression-test.js memeriksa
   strukturnya, dan struktur itu memang tidak boleh bergeser. */
.tutor-turn,.tutor-card-why{border-left-color:var(--sun-deep)}
.tutor-card-why{background:var(--sun-soft)}
/* Wajah tutor dulu bidang --accent dengan tinta --accent-on-glass di atasnya: dua
   turunan marun yang sama, 1,3:1 - ikon topi wisudanya praktis tidak ada. Sekarang
   bidang sun dengan tinta ink, 11,4:1. */
.tutor-turn-face{background:var(--sun);color:var(--text)}
/* Penanda "Jeda mengajar" jadi bidang, bukan teks abu di antara teks abu lain: ia
   satu-satunya keterangan bahwa layar ini BUKAN soal. --info di atas --sun-soft 5,9:1. */
.quiz-teach-flag{padding:4px 10px;border-radius:var(--radius-pill);font-size:.75rem;background:var(--sun-soft);color:var(--info)}

/* ---------- §4 flashcard: chip level + "Kelas kata" ----------
   indonesianPartOfSpeech() sudah menerjemahkan kuncinya sejak lama, jadi ini bukan
   perbaikan kebocoran kunci mentah - ini soal keterbacaan. "A2 · Kata benda" sebagai
   satu baris eyebrow abu tidak memberi tahu bahwa yang kedua adalah KELAS KATA;
   dua chip dengan labelnya sendiri memberi tahu. */
.chips-row{display:flex;gap:7px;flex-wrap:wrap;justify-content:center}
.chip{display:inline-flex;align-items:center;min-height:24px;padding:3px 10px;border-radius:var(--radius-pill);font-size:.75rem;font-weight:600}
.chip-level{background:var(--sun-soft);color:var(--text);border:1px solid var(--sun-deep)}
.chip-cat{background:var(--panel-soft);border:1px solid var(--line);color:var(--muted)}
.chip-cat b{color:var(--text);font-weight:700}

/* ---------- §5 peta belajar satu kartu + panel NEXT SESSION ---------- */
.map-rows{display:grid;gap:13px}
.map-row{display:grid;grid-template-columns:22px 84px 1fr 40px;align-items:center;gap:10px}
.map-row .mi{width:22px;height:22px;display:grid;place-items:center;border-radius:var(--radius-xs);background:var(--sun-soft);color:var(--text)}
.map-row .mi svg{width:14px;height:14px}
.map-row .mn{font-weight:700;font-size:.86rem}
.map-row .bar{margin-top:0}
.map-row .mp{text-align:right;font-weight:800;font-size:.84rem;font-variant-numeric:tabular-nums}
/* Keterangan bukti pindah ke baris kedua di kolom batang: pada layar sempit ia tidak
   pernah ikut menyempitkan batangnya sendiri. */
.map-row .me{grid-column:3/5;font-size:.75rem;color:var(--muted);line-height:1.4}
.map-note{display:flex;align-items:center;gap:9px;margin:14px 0 0;font-size:.79rem;line-height:1.5;color:var(--muted)}
.map-note .coach-strip-face{flex:0 0 auto;width:28px;height:28px}

.next-session{margin-bottom:2px}
.core-actions{display:flex;flex-wrap:wrap;gap:9px;margin-top:14px}
.core-cta,.core-ghost{min-height:44px;padding:10px 18px;border-radius:var(--radius-md);font-weight:700;font-size:.86rem;cursor:pointer}
/* Bidang kuning dengan tinta ink di atasnya (11,4:1). Kuning tidak pernah jadi warna
   TEKS di sistem ini; di sini ia bidang, dan itu memang perannya. */
.core-cta{background:linear-gradient(135deg,var(--sun),var(--sun-deep));color:var(--text);border:1.5px solid var(--sun-deep)}
.core-ghost{background:var(--core-soft);border:1.5px solid var(--core-line);color:var(--on-core)}
/* Baris klaim OLM (2026-08-31). Tombol sanggah dulu memakai ukuran .core-ghost penuh
   (min-height 44, padding 10/18, font 700) di dalam kalimat berjalan - ia jadi objek
   paling berat di kartu, padahal ia aksi SEKUNDER yang jarang dipakai. Di dalam baris
   klaim ia dikecilkan jadi tautan-tombol: tetap 44px area sentuh lewat padding vertikal
   + margin negatif (C1 aksesibilitas tidak dikorbankan demi rapi), tapi bobot visualnya
   turun di bawah nama materi dan angkanya. */
/* Lipatan detail teknis di tab "Cara soal dipilih". Tertutup secara default:
   isinya nama modul internal dan kunci penyimpanan, bukan umpan balik belajar. */
.tech-details{margin:0}
.tech-details>summary{cursor:pointer;list-style:none;padding:13px 16px;border-radius:var(--radius-md);
  background:var(--surface-warm,rgba(0,0,0,.03));color:var(--muted);font-size:.86rem;font-weight:600;
  min-height:44px;display:flex;align-items:center;gap:8px}
.tech-details>summary::-webkit-details-marker{display:none}
.tech-details>summary::before{content:"\25B8";display:inline-block;transition:transform .15s ease}
.tech-details[open]>summary::before{transform:rotate(90deg)}
.tech-details>summary:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.tech-details-isi{display:grid;gap:12px;margin-top:12px}
@media (prefers-reduced-motion:reduce){.tech-details>summary::before{transition:none}}
.olm-claim{padding:7px 0;border-bottom:1px solid var(--line,rgba(0,0,0,.08))}
.olm-claim:last-of-type{border-bottom:0}
.olm-claim>span{flex:1 1 auto;min-width:0;color:var(--text);font-size:var(--fs-body,1rem)}
.olm-claim>b{flex:0 0 auto;font-variant-numeric:tabular-nums}
.olm-claim .olm-dispute{position:relative;flex:0 0 auto;min-height:0;padding:11px 10px;margin:-11px 0;
  background:none;border:0;font-size:.74rem;font-weight:600;text-decoration:underline;
  text-underline-offset:3px;color:var(--muted)}
.olm-claim .olm-dispute:hover{color:var(--text)}
/* Area sentuh 44px DIKEMBALIKAN lewat ::after, bukan lewat tinggi tombolnya sendiri:
   mengecilkan bobot visual tidak boleh sekalian mengecilkan sasaran jari. Kotaknya
   tidak ikut menata (position:absolute), jadi tinggi barisnya tetap 37px seperti yang
   terlihat, sementara yang bisa ditekan 44px. Diukur, bukan diasumsikan. */
.olm-claim .olm-dispute::after{content:"";position:absolute;left:0;right:0;top:50%;
  transform:translateY(-50%);height:44px}

/* D15 (audit D5-T4): --focus-ring-on-core didesain untuk permukaan gelap --core, tetapi
   tombol sanggah OLM (.core-ghost.olm-dispute) dirender di dalam card() PUTIH - kuning penuh
   di atas #FFFFFF hanya 1,56:1, gagal WCAG 1.4.11. Default kini --focus-ring (#A67A00 =
   3,89:1 di putih, 3,53:1 di panel-soft, tetap >=3:1); varian on-core (11,57:1 di --core)
   di-scope ke .core-panel, satu-satunya konteks yang memang membutuhkannya. */
.core-cta:focus-visible,.core-ghost:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.core-panel .core-cta:focus-visible,.core-panel .core-ghost:focus-visible{outline-color:var(--focus-ring-on-core)}

/* ---------- §6 layar selesai ----------
   Skor berhenti berwarna hijau: hijau adalah warna BENAR di sistem ini (banner, opsi),
   dan memakainya untuk skor 34% berarti mengucapkan "bagus" pada sesi yang justru perlu
   diulang. Angkanya jadi tinta biasa; yang merayakan adalah piala, maskot, dan bunyinya. */
.result-card .score{color:var(--text)}
/* i10 2026-08-28 (O5 §7): baris naratif hasil dibatasi lebar bacanya dan angka skor
   memakai digit tabular supaya count-up 0→n% tidak bergoyang lebarnya. */
.result-stage .muted{max-width:44ch;margin-left:auto;margin-right:auto}
.result-stage .score{font-variant-numeric:tabular-nums}
.ring-row{display:flex;align-items:center;justify-content:center;gap:14px}
.ring-row .coach-strip-face{flex:0 0 auto;width:52px;height:52px}
.result-actions{display:grid;grid-template-columns:1fr;gap:10px;margin-top:14px;width:100%}
@media(min-width:540px){.result-actions{grid-template-columns:1fr 1fr;max-width:440px;margin-left:auto;margin-right:auto}}
.result-actions button{min-height:46px;border-radius:999px;font-weight:700;font-size:.94rem;display:inline-flex;align-items:center;justify-content:center;gap:8px}
/* F1 placement: layar hasil tes penempatan menyebut levelnya secara eksplisit. */
.result-level{display:grid;gap:2px;justify-items:center;margin:10px 0 4px;padding:12px 14px;border-radius:var(--radius-md);background:var(--panel-soft,rgba(255,255,255,.06));border:1px solid var(--line,rgba(255,255,255,.12))}
.result-level-mark{font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;opacity:.7}
.result-level-name{font-size:1.9rem;line-height:1.1;font-weight:800}
.result-level-desc{font-size:.8rem;opacity:.78;text-align:center}
.result-bands{display:grid;gap:6px;justify-items:center;margin-bottom:6px}
.result-bands small{opacity:.7;font-size:.7rem;text-align:center}
.result-band-row{display:flex;flex-wrap:wrap;gap:6px;justify-content:center}
.result-band{font-size:.72rem;padding:3px 9px;border-radius:var(--radius-pill);border:1px solid var(--line,rgba(255,255,255,.14));opacity:.72}
.result-band-pass{opacity:1;font-weight:700;border-color:var(--accent,#5eead4);color:var(--accent,#5eead4)}
.result-actions .ghost{min-height:46px;background:transparent;border:1.5px solid var(--line);color:var(--muted)}

/* ---------- §7 pengaturan: sakelar + ikon ----------
   CSS-ONLY, nol JS. Sakelarnya digambar DI ATAS checkbox natif, jadi seluruh id
   (#settingReminders, #settingHaptics, #settingFeedbackSounds, #settingMotion),
   handler #settingsSave, label, dan role bawaan tetap utuh - pembaca layar tetap
   mendapat checkbox sungguhan, bukan div ber-aria. */
.setting-row{min-height:44px}
.setting-row input[type=checkbox]{
  appearance:none;-webkit-appearance:none;position:relative;
  width:50px;height:30px;flex:0 0 auto;border-radius:var(--radius-pill);
  background:var(--line);border:1.5px solid var(--line);cursor:pointer;
  transition:background var(--dur-s) var(--ease),border-color var(--dur-s) var(--ease)
}
.setting-row input[type=checkbox]::after{
  content:"";position:absolute;top:2px;left:2px;width:23px;height:23px;border-radius:50%;
  background:var(--panel);box-shadow:0 1px 4px rgba(36,26,17,.25);
  transition:transform var(--dur-s) var(--ease-spring)
}
.setting-row input[type=checkbox]:checked{background:var(--text);border-color:var(--text)}
.setting-row input[type=checkbox]:checked::after{transform:translateX(20px);background:var(--sun)}
.setting-row input[type=checkbox]:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px}
.setting-row input[type=checkbox]:disabled{background:var(--panel-soft);border-color:var(--line);cursor:not-allowed}
.setting-row input[type=checkbox]:disabled::after{background:var(--line-soft);box-shadow:none}
/* Audit #4 lagi: baris yang tidak bisa diubah tetap TERBACA, tinta yang berubah -
   bukan opacity. Tanpa dukungan :has() teks tetap warna normal, jadi kegagalan
   fitur ini bukan regresi keterbacaan. */
.setting-row:has(input:disabled) b,
.setting-row:has(input:disabled) small{color:var(--muted)}
/* Ikon baris pindah ke keluarga sun: marun --accent-strong di dalam kotak kecil
   membuat setiap baris pengaturan terbaca seperti peringatan. */
.setting-icon{background:var(--sun-soft);color:var(--text);border-radius:var(--radius-xs)}

/* ---- m028-06 LEVEL GUARD & UJIAN SKIP LEVEL --------------------------------------------
 *
 * Status level dibuat kelihatan, bukan disembunyikan: badge di kartu pemilih level, banner
 * jujur di Home saat mode percobaan atau saat terkunci, dan tangga verifikasi yang
 * menunjukkan pintu mana yang sedang kebuka. Semua warna memakai variabel tema yang sudah
 * ada supaya mode gelap dan kontras tinggi ikut benar tanpa aturan tambahan. */
.level-trust-badge{display:inline-block;justify-self:start;padding:3px 8px;border-radius:var(--radius-pill);font-size:.64rem;font-style:normal;font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.level-trust-badge.is-verified{background:color-mix(in srgb,var(--good,#3f7d4e) 16%,transparent);color:var(--good,#3f7d4e)}
.level-trust-badge.is-probation{background:color-mix(in srgb,var(--yellow-deep,#b8862b) 18%,transparent);color:var(--yellow-deep,#b8862b)}
.level-trust-badge.is-locked{background:color-mix(in srgb,var(--muted,#746958) 16%,transparent);color:var(--muted,#746958)}
.level-picker-card.is-locked{opacity:.62;cursor:not-allowed;border-style:dashed}
.level-lock-note{display:grid;gap:5px;padding:12px 14px;margin-top:12px;border-radius:var(--radius-md);border:1px solid color-mix(in srgb,var(--muted,#746958) 32%,transparent);background:var(--panel-soft,#f8f1e7);font-size:.8rem;line-height:1.45}
.level-lock-note.is-probation{border-color:color-mix(in srgb,var(--yellow-deep,#b8862b) 42%,transparent)}
.level-exam-cta{display:flex;flex-wrap:wrap;gap:10px 14px;align-items:center;justify-content:space-between;padding:13px 14px;margin-top:12px;border-radius:var(--radius-md);border:1px solid var(--line,#eadfce);background:var(--panel,#fff)}
.level-exam-cta div{display:grid;gap:3px}
.level-exam-cta span{font-size:.74rem;color:var(--muted,#746958)}
.level-exam-facts{display:grid;gap:6px;margin:12px 0;padding-left:18px;font-size:.8rem;line-height:1.45}
.level-trust-banner{display:grid;gap:10px;padding:15px 16px;margin:0 0 16px;border-radius:var(--radius-md);border:1px solid var(--line,#eadfce);background:var(--panel,#fff)}
.level-trust-banner.is-locked{border-color:color-mix(in srgb,var(--accent,#9B3A4A) 40%,transparent);background:color-mix(in srgb,var(--accent,#9B3A4A) 6%,var(--panel,#fff))}
.level-trust-banner.is-probation{border-color:color-mix(in srgb,var(--yellow-deep,#b8862b) 42%,transparent);background:color-mix(in srgb,var(--yellow-deep,#b8862b) 7%,var(--panel,#fff))}
.level-trust-head{display:grid;gap:4px}
.level-trust-head b{font-size:.98rem}
.level-trust-head span,.level-trust-count{font-size:.79rem;line-height:1.5;color:var(--muted,#746958)}
.level-trust-count{margin:0;font-weight:600;color:var(--ink,#2E2724)}
.level-trust-ladder{display:flex;flex-wrap:wrap;gap:8px;margin:0;padding:0;list-style:none}
.level-trust-ladder li{display:grid;gap:2px;min-width:82px;padding:8px 10px;border-radius:var(--radius-sm);border:1px solid var(--line,#eadfce);background:var(--panel-soft,#f8f1e7);font-size:.68rem;color:var(--muted,#746958)}
.level-trust-ladder li b{font-size:.88rem;color:var(--ink,#2E2724)}
.level-trust-ladder li.is-done{border-color:color-mix(in srgb,var(--good,#3f7d4e) 45%,transparent)}
.level-trust-ladder li.is-done b{color:var(--good,#3f7d4e)}
.level-trust-ladder li.is-open{border-color:color-mix(in srgb,var(--accent,#9B3A4A) 48%,transparent)}
.level-trust-ladder li.is-open b{color:var(--accent,#9B3A4A)}
.level-trust-actions{display:flex;flex-wrap:wrap;gap:8px}
/* m025-166 popup gerbang masuk level. Isinya HANYA transform+opacity - tidak ada properti
   layout yang dianimasikan, jadi tidak ada reflow per frame di ponsel murah. Pop masuk
   memakai var(--fz-spring) (pegas, terasa "menyapa"), isinya menyusul dengan var(--fz-out)
   supaya teks tidak ikut memantul. Murid yang minta gerak minimal, atau yang mematikan
   animasi di Pengaturan (kelas .is-static dari app.js), langsung mendapat bentuk akhirnya. */
.level-entry-pop{display:grid;gap:9px;justify-items:start;text-align:left;transform-origin:50% 8%;animation:fzLevelEntryPop .42s var(--fz-spring,cubic-bezier(.34,1.4,.4,1)) both}
.level-entry-pop>*{animation:fzLevelEntryRise .34s var(--fz-out,cubic-bezier(.22,.8,.28,1)) both}
.level-entry-pop .level-entry-face{animation-delay:.04s}
.level-entry-pop .modal-mark{animation-delay:.08s}
.level-entry-pop .level-entry-chip{animation-delay:.12s}
.level-entry-pop h2{margin:0;animation-delay:.16s;font-size:1.16rem;line-height:1.28}
.level-entry-pop .level-entry-line{margin:0;text-align:left;animation-delay:.2s;font-size:.86rem;line-height:1.5;color:var(--muted,#746958)}
.level-entry-pop .modal-actions{width:100%;animation-delay:.24s}
.level-entry-face{display:flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:50%;background:var(--panel-soft,#f8f1e7);border:1px solid var(--line,#eadfce)}
.level-entry-chip,.level-trust-chip{display:inline-block;padding:4px 10px;border-radius:var(--radius-pill);border:1px solid color-mix(in srgb,var(--yellow-deep,#b8862b) 40%,transparent);background:color-mix(in srgb,var(--yellow-deep,#b8862b) 14%,transparent);color:var(--yellow-deep,#b8862b);font-style:normal;font-size:.66rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase}
/* Audit 02-003: teks chip 10,56px memakai --yellow-deep di atas krem (±2:1) - melanggar
   aturan berkas ini sendiri: kuning adalah warna BIDANG, bukan warna teks. --info adalah
   SATU-SATUNYA kuning-tinta yang boleh jadi teks (lihat komentar token v6), dan ukurannya
   dinaikkan ke lantai 12px. Bidang chip (border/latar kuning tipis) tidak berubah. */
.level-trust-chip{justify-self:start;color:var(--info,#7A5F1B);font-size:.75rem}
.level-trust-chip-cta{justify-self:start;margin-top:4px;padding:7px 13px;border-radius:var(--radius-pill);border:1px solid color-mix(in srgb,var(--accent,#9B3A4A) 42%,transparent);background:transparent;color:var(--accent,#9B3A4A);font-size:.76rem;font-weight:700}
@keyframes fzLevelEntryPop{from{opacity:0;transform:scale(.9) translate3d(0,10px,0)}60%{opacity:1;transform:scale(1.01) translate3d(0,0,0)}to{opacity:1;transform:scale(1) translate3d(0,0,0)}}
@keyframes fzLevelEntryRise{from{opacity:0;transform:translate3d(0,7px,0)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .level-entry-pop,.level-entry-pop>*{animation:none!important;opacity:1;transform:none}
}
.level-entry-pop.is-static,.level-entry-pop.is-static>*{animation:none;opacity:1;transform:none}
.level-exam-verdict{padding:12px 14px;margin:10px 0;border-radius:var(--radius-md);font-size:.85rem;line-height:1.5}
.level-exam-verdict.is-pass{background:color-mix(in srgb,var(--good,#3f7d4e) 12%,transparent);color:var(--good,#3f7d4e)}
.level-exam-verdict.is-fail{background:color-mix(in srgb,var(--yellow-deep,#b8862b) 14%,transparent);color:var(--ink,#2E2724)}
@media (max-width:520px){.level-exam-cta{flex-direction:column;align-items:stretch}.level-exam-cta button{width:100%}}

/* ================================================================================
   P1 GAME LAYER (audit §14) — Jalur Lesson Bersimpul, Prasasti, Ritual Pembuka.
   Semua warna dari token merek Warm Paper yang sudah ada; semua gerak memakai
   token --dur/--ease dan dimatikan total pada prefers-reduced-motion.
   ================================================================================ */

/* ---- P1-1 Jalur Lesson Bersimpul ---------------------------------------------- */
.path-view-toggle{display:flex;justify-content:flex-end;margin:2px 0 10px}
.path-view-toggle button{font-size:.82rem;padding:8px 14px}
.lesson-path{list-style:none;margin:0;padding:4px 0 18px;position:relative}
.path-step{position:relative;display:grid;grid-template-columns:64px minmax(0,1fr) auto;gap:12px;align-items:center;padding:10px 0 22px}
/* Garis penghubung antar simpul: satu kolom di tengah cincin. Selesai = tinta hangat,
   terkunci = putus-putus redup — jalur terbaca bahkan tanpa warna (aksesibilitas). */
/* Audit 04-004: garis dekoratif ini menangkap hit-test dan membuat strip mati 3px di
   tengah setiap simpul (tap tepat di pusat node tidak membuka materi). pointer-events:none
   mengembalikan seluruh area ke tombolnya; ini murni dekorasi. */
.path-step::after{content:'';position:absolute;left:31px;top:66px;bottom:-6px;width:3px;border-radius:2px;background:var(--gold);opacity:.55;pointer-events:none}
.path-step.is-locked::after{background:none;border-left:3px dashed rgba(36,26,17,.18)}
.path-step:last-child::after{display:none}
.path-node{display:grid;place-items:center;width:64px;height:64px;padding:0;border:none;border-radius:50%;background:transparent;box-shadow:none}
.path-node:disabled{opacity:1;cursor:not-allowed}
.path-ring{display:grid;place-items:center;width:60px;height:60px;border-radius:50%;background:conic-gradient(var(--green) calc(var(--pm,0)*1%),#EFE3CE 0);transition:background var(--dur-m) var(--ease)}
.path-ring>b,.path-ring>i,.path-ring>svg{display:grid;place-items:center;width:46px;height:46px;border-radius:50%;background:var(--bg);color:var(--ink);font-size:1rem;box-shadow:inset 0 0 0 1px rgba(36,26,17,.08)}
.path-ring i{padding:12px}
.path-step.is-mastered .path-ring{background:var(--green)}
.path-step.is-mastered .path-ring>b,.path-step.is-mastered .path-ring>i{background:var(--green-soft);color:var(--green)}
.path-step.is-locked .path-ring{background:#EFE3CE}
.path-step.is-locked .path-ring>i{color:rgba(36,26,17,.42);background:#FBF4E4}
.path-step.is-locked .path-label b{color:rgba(36,26,17,.55)}
.path-step.is-current .path-ring>b{background:var(--accent-soft);color:var(--accent-strong)}
.path-label{min-width:0}
.path-label b{display:block;font-size:.95rem}
.path-label>span{display:block;font-size:.78rem;color:rgba(36,26,17,.62);margin-top:2px}
.path-label .lesson-lock-note{margin:8px 0 0}
.path-mascot{width:44px;justify-self:end;align-self:center}
.path-mascot :is(svg,img,canvas){width:44px;height:44px}
/* Node ujian emas di ujung jalur — tujuan jangka menengah selalu terlihat. */
.path-node-exam .path-ring{background:linear-gradient(140deg,var(--gold),#E7C878)}
.path-node-exam .path-ring>i{background:#FFF6DF;color:#8A6A24}
.path-step-exam .path-label b{color:#8A6A24}
/* Denyut halus node aktif: HANYA saat gerak diizinkan. */
@media (prefers-reduced-motion:no-preference){
  .path-step.is-current .path-node{animation:pathPulse 2.4s var(--ease) infinite}
  @keyframes pathPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}
}

/* ---- P1 Prasasti: galeri + momen ---------------------------------------------- */
.prasasti-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:10px;margin-top:10px}
.prasasti-badge{display:grid;justify-items:center;gap:6px;text-align:center;padding:14px 10px;border-radius:var(--radius-md);background:#FFFDF6;box-shadow:inset 0 0 0 1px rgba(36,26,17,.08)}
.prasasti-badge b{font-size:.82rem;line-height:1.25}
.prasasti-badge .prasasti-hint{font-size:.7rem;color:rgba(36,26,17,.55)}
.prasasti-icon{display:grid;place-items:center;width:52px;height:52px;border-radius:50%}
.prasasti-icon svg{width:28px;height:28px}
.prasasti-badge.is-earned .prasasti-icon{background:linear-gradient(140deg,#FFF2C9,#FCE3B0);color:#8A6A24;box-shadow:0 2px 8px rgba(201,162,75,.35)}
.prasasti-badge.is-earned b{color:var(--ink)}
/* Siluet: lencana yang belum terukir tetap terlihat bentuknya — tujuan, bukan rahasia. */
.prasasti-badge.is-locked{opacity:.72}
.prasasti-badge.is-locked .prasasti-icon{background:#F1EADB;color:rgba(36,26,17,.35)}
.prasasti-badge.is-locked b{color:rgba(36,26,17,.5)}
.fz-prasasti-moment{position:fixed;inset:0;z-index:96;display:grid;place-items:center;padding:22px;background:rgba(36,26,17,.34)}
.fz-prasasti-close{position:absolute;top:8px;right:8px;min-width:44px;min-height:44px}/* audit F13: modal lencana wajib punya tombol tutup */
.fz-prasasti-card{position:relative;width:min(340px,92vw);display:grid;justify-items:center;gap:10px;text-align:center;padding:26px 22px 20px;border-radius:var(--radius-lg);background:#FFFDF8;box-shadow:var(--shadow-lg)}
.fz-prasasti-hero{display:grid;justify-items:center;gap:6px}
.fz-prasasti-hero .prasasti-icon{width:72px;height:72px;background:linear-gradient(140deg,#FFF2C9,#FCE3B0);color:#8A6A24;box-shadow:0 3px 12px rgba(201,162,75,.4)}
.fz-prasasti-hero .prasasti-icon svg{width:38px;height:38px}
.fz-prasasti-hero b{font-size:1.1rem}
.fz-prasasti-hero p{margin:0;font-size:.86rem;color:rgba(36,26,17,.68)}
.fz-prasasti-note{margin:0;font-size:.74rem;color:rgba(36,26,17,.74)}/* q17-S3: 3.27:1 -> >=4.5:1 */
.fz-prasasti-moment.is-leaving{opacity:0;transition:opacity var(--dur-m) var(--ease)}
@media (prefers-reduced-motion:no-preference){
  .fz-prasasti-card{animation:riseIn var(--dur-m) var(--ease-spring) both}
}

/* ---- P1-2 Ritual Pembuka Harian ------------------------------------------------ */
.fz-ritual{position:fixed;inset:0;z-index:95;display:grid;place-items:end center;padding:0 16px 92px;background:rgba(36,26,17,.28)}
.fz-ritual-card{width:min(380px,94vw);display:grid;gap:8px;padding:22px 20px 18px;border-radius:var(--radius-lg);background:var(--bg);box-shadow:var(--shadow-lg)}
.fz-ritual-paw{width:48px;height:48px}
.fz-ritual-paw :is(svg,img,canvas){width:48px;height:48px}
.fz-ritual-hi{margin:0;font-size:1.16rem;font-weight:700}
.fz-ritual-streak{margin:0;display:flex;align-items:center;gap:6px;font-size:.84rem;color:var(--accent-strong)}
/* Audit 20-002: ikon api runtun tidak pernah diberi ukuran, jadi ia mekar ke 300px dan
   kartu ritualnya menggelembung. 20px sejajar dengan teks .84rem di sampingnya. */
.fz-ritual-streak .fz-i{width:20px;height:20px}
.fz-ritual-mark{letter-spacing:.14em;font-size:.66rem;color:rgba(36,26,17,.5);margin-top:4px}
.fz-ritual-blocks{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.fz-ritual-block{display:grid;gap:2px;padding:9px 12px;border-radius:var(--radius-sm);background:#FFFDF6;box-shadow:inset 0 0 0 1px rgba(36,26,17,.07)}
.fz-ritual-block b{font-size:.86rem}
.fz-ritual-block span{font-size:.74rem;color:rgba(36,26,17,.6)}
.fz-ritual-empty{margin:0;font-size:.84rem;color:rgba(36,26,17,.65)}
.fz-ritual-actions{display:flex;gap:8px;margin-top:8px}
.fz-ritual-actions .primary{flex:1}
.fz-ritual.is-leaving{opacity:0;transition:opacity var(--dur-m) var(--ease)}
@media (prefers-reduced-motion:no-preference){
  .fz-ritual-card{animation:riseIn var(--dur-m) var(--ease-spring) both}
  /* Reveal rencana ber-stagger 3×80ms sesuai spek P1-2. */
  .fz-ritual-block{animation:riseIn var(--dur-m) var(--ease) both;animation-delay:calc(var(--ri,0)*80ms)}
}

/* ==========================================================================
   R2 UX OVERHAUL RONDE 2 (permintaan owner, IMPLEMENTATION-R2-REPORT.md)
   ========================================================================== */
/* R2-1 chip Ujian Skip Level di puncak Grammar Hub. Lengket di bawah kepala layar supaya
   pintu ujiannya terlihat TANPA menggulir ke ujung jalur; node emas di ujung tetap ada. */
.grammar-hub-tools{
  position:sticky;top:8px;z-index:6;
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin:0 0 12px;
}
/* Latar dan tinta SAMA-SAMA token bertema (aturan kontras m025-85: jangan memaku salah
   satunya sebagai literal) — pasangan sun/text yang sudah diaudit di .primary. */
.exam-entry-chip{
  display:inline-flex;align-items:center;gap:10px;min-height:44px;
  padding:9px 14px;border-radius:var(--radius-md);text-align:left;
  background:var(--sun);
  border:1.5px solid var(--sun-deep);box-shadow:0 2px 0 var(--sun-deep);
  color:var(--text);
}
.exam-entry-chip>svg{width:18px;height:18px;flex:none}
.exam-entry-chip span b{display:block;font-size:.82rem;font-weight:700;letter-spacing:-.01em}
.exam-entry-chip span small{display:block;font-size:.66rem;font-weight:600;color:var(--text);opacity:.75}
.exam-entry-chip.is-passed{background:var(--good-soft,#DFF3E4)}
.grammar-hub-tools .path-view-toggle{margin:0}
@media(max-width:560px){
  .grammar-hub-tools{flex-wrap:wrap}
  .exam-entry-chip{flex:1 1 100%;justify-content:flex-start}
}

/* R2-2 tautan "Lewati materi": gerbang bukti, bukan aksi utama - gaya tautan kecil supaya
   jalur normal tetap terbaca sebagai jalan utama. */
.lesson-skip-link{
  display:inline-flex;align-items:center;gap:5px;min-height:44px;box-sizing:border-box;width:max-content;
  position:relative;
  margin-top:5px;padding:4px 8px;border-radius:var(--radius-xs);
  background:none;border:1px dashed rgba(36,26,17,.35);box-shadow:none;
  color:var(--muted);font-size:.7rem;font-weight:700;
}
/* Audit 04-003: tautan ini setinggi 24px - 45% di bawah sasaran sentuh 44px - dan
   berulang 16x per jalur. Perpanjangan hit-area transparan menaikkan kotak sentuh
   efektifnya ke 44px tanpa membesarkan tampilannya; ruang di atas (label) dan di bawah
   (padding 22px .path-step) tidak berisi target lain.
   Audit UI/UX 2026-08-30: -10px ternyata MASIH kurang. Kotaknya 23,x px (bukan 24 bulat),
   jadi 23,x + 20 = 41px terukur lewat elementFromPoint - tiga piksel di bawah lantai, dan
   angka itu yang dirasakan jempol, bukan angka di komentar. Dinaikkan ke 12px per sisi
   (=48px) supaya lantainya dilewati dengan margin, bukan dipepet. */
.lesson-skip-link::before{content:'';position:absolute;left:0;right:0;top:-12px;bottom:-12px}
.lesson-skip-link svg{width:12px;height:12px}
.lesson-skip-link:hover{background:var(--sun-soft);color:var(--text);transform:none;box-shadow:none}
/* Node terkunci: tombol node-nya disabled, tetapi tautan lewati TIDAK ikut redup -
   ia justru pintu yang sah dari keadaan terkunci. */
.path-step.is-locked .lesson-skip-link{opacity:1}

/* R2-3 kartu Classroom terkunci: tetap terlihat (fiturnya nyata dan sedang datang),
   tidak bisa diketuk, dan membawa label SEGERA - bukan kartu mati tanpa penjelasan. */
.launch-card.is-coming-soon{opacity:.62;cursor:not-allowed;box-shadow:none;transform:none}
.launch-card.is-coming-soon:hover{transform:none;box-shadow:none}
.coming-soon-tag{
  flex:none;padding:3px 8px;border-radius:var(--radius-pill);
  background:var(--sun-soft);border:1px solid rgba(36,26,17,.25);
  font-size:.58rem;font-weight:700;letter-spacing:.1em;color:var(--text);
}

/* R2-4 maskot DI ATAS panel soal, di semua tipe sesi. Kompak (52px), dekorasi murni
   (aria-hidden), dan tidak pernah menghalangi konten - reaksinya lewat pawReact yang
   sudah bergerbang reduced-motion. */
.quiz-mascot{display:flex;justify-content:center;margin:2px 0 10px}
.quiz-mascot:empty{display:none}
.quiz-mascot .coach-strip-face{width:52px;height:52px}
.quiz-mascot .coach-strip-mascot{width:34px;height:34px}

/* R2-6 keping gem di pita statistik hero. */
.hero-stat.is-gems{background:var(--good-soft,#DFF3E4)}
.hero-stat.is-gems svg{color:var(--good,#2E7D4F)}
/* R2-6: baris cincin misi di panel HARI INI (Peta Belajar → Ringkasan). */
.journey-ring-row{display:flex;align-items:center;gap:14px;margin:6px 0 10px}
.journey-ring-row p{margin:0;font-size:.78rem;line-height:1.5;color:var(--glass-muted)}

/* MERGE 28 Agu 2026: dua blok CSS independen bertemu di ujung berkas - lapisan game & UX
   dari hulu, dan pemberitahuan jatah/suara A8 dari jalur rollout Cloudflare. Selektornya
   tidak bersinggungan, jadi keduanya disimpan utuh; tidak ada yang dibuang. */
/* ===================================================== A8 · pemberitahuan jatah/suara =====
   Naskahnya di features/quota/quota-copy.js; di sini hanya bentuknya. Empat angka di bawah
   dijaga tests/quota-notice-a11y-test.js dan nggak boleh diturunkan tanpa mengubah gerbangnya:

   1. WARNA. Tinta --ink di atas bidang --panel-soft = 14,6:1, jauh di atas syarat 4,5:1 WCAG AA.
      Hex-nya ditulis eksplisit (bukan hanya var()) supaya gerbang bisa menghitung rasionya
      tanpa peramban; var() tetap dipakai sebagai nilai utama agar tema tunggal tetap berlaku.
   2. TARGET SENTUH 44px. min-height DAN min-width, keduanya eksplisit - 44px yang kebetulan
      lahir dari padding akan menyusut begitu ukuran huruf sistem berubah.
   3. TIDAK ADA ANIMASI HILANG SENDIRI. Nggak ada transition opacity berbatas waktu, nggak ada
      keyframe yang mengakhiri dengan opacity:0. Pemberitahuan ini menunggu murid, bukan
      sebaliknya - larangan toast 2.600 ms untuk pesan penting (cf-b8) ditegakkan di sini
      sebagai KETIADAAN jalan untuk menghilang.
   4. LEBAR 390px. Panelnya mengalir dalam satu kolom pada layar tersempit yang didukung; nggak
      ada baris tombol berdampingan yang bisa jatuh di bawah 44px. */
.fz-notice{display:flex;flex-direction:column;gap:8px;margin:0;padding:14px 16px;border-radius:var(--radius-md);
  background:var(--panel-soft,#F6F1EA);color:var(--ink,#2E2724);
  border:1px solid var(--yellow-deep,#EFDFB8);text-align:left}
.fz-notice-title{margin:0;font-size:1.02rem;line-height:1.3;color:var(--ink,#2E2724)}
.fz-notice-body{margin:0;font-size:.9rem;line-height:1.55;color:var(--ink,#2E2724)}
.fz-notice-note{margin:0;font-size:.82rem;line-height:1.5;color:var(--muted,#6E635C)}
.fz-notice-actions{display:flex;flex-direction:column;gap:8px;margin-top:4px}
.fz-notice-btn{min-height:44px;min-width:44px;width:100%;padding:11px 16px;border-radius:var(--radius-sm);
  border:1px solid var(--yellow-deep,#EFDFB8);background:var(--yellow,#F7EACB);
  color:var(--ink,#2E2724);font-weight:700;font-size:.9rem}
.fz-notice-btn:focus-visible{outline:3px solid var(--ink,#2E2724);outline-offset:2px}
/* Panel jatah. Selama pembayaran mati ia sengaja NGGAK punya satu pun elemen yang bisa
   ditekan - jadi nggak ada gaya tombol/tautan di sini, dan itu bukan kelupaan. */
.fz-plan{display:flex;flex-direction:column;gap:6px;padding:14px 16px;border-radius:var(--radius-md);
  background:var(--panel,#FFFFFF);color:var(--ink,#2E2724);border:1px solid var(--line,#EFE7DE);text-align:left}
.fz-plan-title{margin:0;font-size:1.02rem;line-height:1.3}
.fz-plan-line{margin:0;font-size:.88rem;line-height:1.55;color:var(--ink,#2E2724)}

/* ==========================================================================
   D15 (audit D5-S9/S10) — input cloze & tuntunan step-tutor (Fase 3, C5)
   ==========================================================================
   Dua komponen Fase 3 ini dirender app.js (mode cloze butir 2, step-tutor butir 6)
   tetapi belum punya satu aturan pun di sini - input cloze tampil dengan gaya bawaan
   peramban (font ±13px, border native) dan langkah tuntunan terbaca sebagai paragraf
   polos. Semuanya memakai token existing; tidak ada warna baru.
   -------------------------------------------------------------------------- */

/* Input cloze: satu-satunya kontrol ketik di layar kuis, jadi ia mengikuti resep
   .ask-box/.fiezel-field - font 16px (iOS tidak memperbesar layar saat fokus),
   tinggi >=48px nyaman di ponsel, border --line, cincin fokus --focus-ring. */
.cloze-entry{display:flex;align-items:stretch;gap:9px;margin:4px 0 2px}
.cloze-entry .primary{flex:0 0 auto}
.cloze-input{
  flex:1 1 auto;min-width:0;min-height:48px;padding:11px 14px;
  border:1.5px solid var(--line);border-radius:var(--radius-md);
  background:var(--panel);color:var(--text);
  font:inherit;font-size:16px;font-weight:600;letter-spacing:.01em;
}
.cloze-input::placeholder{color:var(--muted-soft);font-weight:500}
.cloze-input:focus-visible{outline:2px solid var(--focus-ring);outline-offset:2px;border-color:var(--focus-ring)}
/* Setelah dinilai, revealCloze menonaktifkan input - state terkunci dibedakan dari
   state kosong supaya murid tahu jawabannya sudah diterima, bukan hilang. */
.cloze-input:disabled{background:var(--panel-soft);border-color:var(--line);color:var(--muted)}
/* Hook state benar/salah - resep warna SAMA dengan .option.correct/.option.wrong
   supaya bahasa visualnya satu: hijau=benar, marun=salah. */
.cloze-input.correct{border-color:var(--good-bright);background:var(--good-soft);color:var(--text)}
.cloze-input.wrong{border-color:var(--bad);background:var(--bad-soft);color:var(--text)}
@media(max-width:420px){
  .cloze-entry{flex-wrap:wrap}
  .cloze-entry .primary{flex:1 1 100%}
}

/* Tuntunan step-tutor: 2-3 pertanyaan penuntun di anak tangga 'worked'. Latar lembut
   --surface-warm memisahkannya dari giliran tutor biasa, dan penomoran via CSS counter
   membuat 3 paragraf terbaca sebagai LANGKAH berurut, bukan esai. Nomor memakai pasangan
   sun-soft/info (5,42:1) dan teks langkah --ink di surface-warm (15,65:1). */
.tutor-steps{
  margin:12px 0 2px;padding:12px 14px;border-radius:var(--radius-sm);
  background:#FFF8EE !important;border:1.5px solid #FDE68A !important;
  counter-reset:tutor-step;
}
.tutor-steps .eyebrow{display:block;margin-bottom:9px;color:#78350F !important;font-weight:800 !important}
.tutor-step{
  counter-increment:tutor-step;
  position:relative;margin:0 0 9px;padding-left:33px;
  font-size:.9rem;line-height:1.6;color:#1C1917 !important;font-weight:600 !important;
}
.tutor-step:last-of-type{margin-bottom:0}
.tutor-step::before{
  content:counter(tutor-step);
  position:absolute;left:0;top:1px;
  display:grid;place-items:center;width:24px;height:24px;border-radius:50%;
  background:#FEF3C7 !important;border:1.5px solid #D97706 !important;
  color:#92400E !important;font-size:.75rem;font-weight:800;font-variant-numeric:tabular-nums;
}
.tutor-step-final{
  margin:11px 0 0;padding-top:10px;border-top:1px dashed #D97706;
  font-size:.94rem;line-height:1.6;font-weight:700;color:#78350F !important;
}

/* ============================================================
   [FASE 7] SLOT PAW PANEL — lapisan penempatan karakter di layar pelajaran.
   Sumber: pau-redesign/systems/12-lesson-layer.md (nama resmi fz-paw-* per
   errata code-plan §7.1). Markup datang dari features/mascot/fiezel-paw-slot.js.
   Invarian keras:
   C1  tembus-pointer mutlak — ketukan di atas PAW selalu tembus ke UI;
   C2  tidak ada piksel PAW di kotak konten terlindungi (peek dipotong kotak
       slotnya sendiri, above/side hidup di luar kartu);
   C3  nol CLS — ruang dipesan saat render (tinggi eksplisit / margin-top /
       kolom grid), reaksi & enter/exit tinggal di transform+opacity;
   C4  headroom reaksi ada DI DALAM kotak slot;
   C5  z-index <= 5, di bawah semua UI fixed: topbar kuis z30, gelembung
       pembimbing z41, subtitle z70, toast z80 — #quizNext selalu terjangkau;
   C7  slot hanya dipasang templat di permukaan krem/putih, bukan --sun.
   Ukuran tier milik CSS (media query 640/860/980 + landscape pendek), supaya
   rotasi di antara dua render tidak membuat ruang pesanan berubah-ubah.
   ============================================================ */
.fz-paw-slot{
  position:relative;pointer-events:none;z-index:1;
  display:flex;justify-content:center;align-items:flex-end;
  --fz-paw-size:88px;--fz-paw-headroom:20px;
}
.fz-paw-slot,.fz-paw-slot *{pointer-events:none!important}/* C1 mutlak */
.fz-paw-slot fiezel-mascot{
  flex:none;width:var(--fz-paw-size);
  height:calc(var(--fz-paw-size)*.9375);/* rasio viewBox rig 320x300 */
}

/* A — di atas panel: tinggi dipesan eksplisit saat render (C3/C4).
   88 di ponsel-lebar/tablet, 108 dari 860, 120 desktop (tangga §2e). */
.fz-paw-above{height:calc(var(--fz-paw-size)*.9375 + var(--fz-paw-headroom));margin-bottom:-2px}
@media (min-width:860px){.fz-paw-above{--fz-paw-size:108px}}
@media (min-width:980px){.fz-paw-above{--fz-paw-size:120px;--fz-paw-headroom:32px}}

/* P — peek: hanya puncak kepala+telinga muncul dari balik tepi atas kartu.
   Kotak slot MEMOTONG badan (overflow hidden) => tidak pernah ada piksel di
   atas isi kartu (C2), dan fzMEnterPeek "naik dari balik tepi" gratis.
   z-index 0: saat topbar sticky lewat di atasnya, kepala PAW yang mengalah. */
.fz-paw-peek{
  position:absolute;right:18px;top:calc(var(--fz-paw-size)*-.44);
  z-index:0;overflow:hidden;display:block;
  width:calc(var(--fz-paw-size)*1.25);height:calc(var(--fz-paw-size)*.44);
  --fz-paw-size:56px;--fz-paw-headroom:0px;
}
.fz-paw-peek fiezel-mascot{position:absolute;left:50%;top:0;transform:translate(-50%,0)}
/* HEADER SESI KUIS: KAPSUL, BUKAN SLAB (OWNER 2026-08-31: "perhatikan panel paling atas
   dan paling bawah, sangat jelek sekali").
   .quiz-topbar berdiri sejak lama sebagai bidang translusen selebar konten, tanpa
   border-radius, tanpa garis tepi, menempel di top:0 - jadi ia terbaca sebagai potongan
   kertas yang terpotong lurus di kedua sisi, bukan sebagai kontrol. Di layar sempit
   tingginya 71px dan tepi bawahnya berhenti mendadak tepat di atas maskot, membuat
   layarnya terbelah dua.
   Diperbaiki dengan meminjam resep yang SUDAH dipakai topbar utama aplikasi
   (tutor-v3.css: sticky, radius 18px, garis --glass-edge, bayangan lembut). Hasilnya satu
   bahasa visual di seluruh produk, bukan dua. Turun sedikit dari tepi (top:8px) supaya
   pembulatannya benar-benar terlihat saat menempel. */
body.fz-stage-quiz .quiz-topbar,
body.fz-lux.fz-stage-quiz .quiz-topbar {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  z-index: 500 !important;
  width: 100% !important;
  box-sizing: border-box !important;
  margin: 0 !important;
  padding: max(10px, env(safe-area-inset-top, 10px)) 16px 10px 16px !important;
  border-radius: 0 !important;
  background: rgba(253, 250, 243, 0.98) !important;
  backdrop-filter: blur(20px) !important;
  -webkit-backdrop-filter: blur(20px) !important;
  border-bottom: 1.5px solid #E2E8F0 !important;
  box-shadow: 0 2px 12px rgba(15, 23, 42, 0.05) !important;
}
@media(max-height:430px){
  body.fz-stage-quiz .quiz-topbar,
  body.fz-lux.fz-stage-quiz .quiz-topbar {
    top: 0 !important;
    padding: max(6px, env(safe-area-inset-top, 6px)) 12px 8px 12px !important;
    margin-bottom: 8px !important;
  }
}

/* PANEL TERAKHIR TIDAK MENEMPEL DI TEPI BAWAH LAYAR. Tanpa ini kartu tutor berakhir rata
   dengan tepi layar dan terbaca seperti isi yang terpotong, bukan yang selesai. */
body.fz-lesson-mode.fz-stage-quiz .quiz-shell{padding-bottom:calc(28px + env(safe-area-inset-bottom,0px))}
body.fz-stage-quiz .quiz-mascot{display:none !important}
body.fz-stage-quiz .quiz-shell:has(#feedback:not(.hidden)),
body.fz-stage-quiz .quiz-shell:has(.quiz-floating-bar.is-visible){padding-bottom:calc(96px + env(safe-area-inset-bottom,0px)) !important}

/* MASKOT KUIS DI PONSEL (OWNER 2026-08-31: "mascotnya terlalu kecil").
   Tangga ukuran bawaan 'above' adalah 88px - benar untuk layar kosong yang cuma butuh
   penanda, terlalu kecil untuk layar kuis yang punya ~400px ruang menganggur di
   bawahnya. Di panggung kuis ia naik mengikuti tinggi layar (min 108px, sampai 168px),
   jadi ia besar di ponsel tinggi dan tidak pernah menindas soal di ponsel pendek. */
/* PANGGUNG SOAL: MASKOT KIRI, SOAL DI GELEMBUNG KANAN (OWNER 2026-08-31: "semua sesi
   selain listening masih belum berubah").
   Susunan yang sama persis dengan sesi dengar, dan berlaku untuk SEMUA tipe kuis - vocab,
   grammar, reading, penempatan, ujian - karena semuanya melewati satu jalur cat yang sama.
   Maskot yang tadinya berdiri sendirian DI ATAS kartu kini duduk DI DALAMNYA, sejajar
   dengan soal, sehingga ia terbaca sebagai tokoh yang MENGUCAPKAN soalnya - bukan gambar
   yang kebetulan ditempel di atas panel. */
.quiz-stage{display:flex;align-items:center;gap:10px;margin:0 0 12px}
/* Lantai naik 96 -> 120px 2026-08-31. Diukur, bukan ditebak: 34% dari lebar-dalam
   kartu di ponsel 390px = 110,8px, dan 110,8 ada DI BAWAH ambang kombo 120px
   (19 SS6.2/SS6.5) - jadi bunga OF-03 yang diminta OWNER untuk sesi Tes diam-diam
   luruh dan hanya ranselnya yang terpasang. Persentasenya ikut naik ke 38% supaya
   angka minimum itu tidak jadi satu-satunya yang bekerja di layar lebih lebar.
   CATATAN kaskade: --fz-paw-size TIDAK berlaku di mode panggung - aturan width di
   sinilah yang menang, jadi menaikkan variabel itu di .quiz-shell tidak berefek. */
.quiz-stage .fz-paw-above{flex:0 0 auto;height:auto;margin:0;width:clamp(140px,38vw,172px);min-height:140px;max-height:175px;aspect-ratio:16/15;overflow:visible;background:transparent;border:none;box-shadow:none}
.quiz-stage .fz-paw-above fiezel-mascot{width:100%;height:100%;min-height:140px;overflow:visible;background:transparent;border:none;box-shadow:none}
.quiz-bubble{
  position:relative;flex:1 1 auto;min-width:0;
  padding:12px 14px;border:1.5px solid var(--line);border-radius:18px;background:var(--panel-soft);
  z-index:5;
}
.quiz-bubble .question{margin:0;font-size:clamp(1.02rem,4.4vw,1.24rem);line-height:1.4}
/* Ekor gelembung dari border transparan - ikut tema, nol aset tambahan. */
.quiz-bubble::before,.quiz-bubble::after{content:'';position:absolute;top:50%;transform:translateY(-50%);border:9px solid transparent}
.quiz-bubble::before{left:-19px;border-right-color:var(--line)}
.quiz-bubble::after{left:-16px;border-right-color:var(--panel-soft)}
@media (max-height:640px){.quiz-stage .fz-paw-above{width:clamp(120px,25%,140px);min-height:120px}.quiz-stage{margin-bottom:8px}}
/* Tablet 641px-979px: panggung rapi berdampingan, maskot tidak menimpa gelembung */
@media (min-width:641px) and (max-width:979px){
  .quiz-stage{display:flex;flex-direction:row;align-items:center;gap:18px;margin-bottom:14px}
  .quiz-stage .fz-paw-above{flex:0 0 156px;width:156px;height:156px;min-height:140px;max-height:165px;margin:0}
  .quiz-bubble{flex:1 1 auto;min-width:0;z-index:5}
}
/* Audit F11 (2026-09-23) & Mochi PWA: di bawah 640px soal kembali selebar kartu; maskot duduk
   DI ATAS gelembung di tengah kartu dengan ruang lega 140px-160px untuk Three.js mochi. */
@media (max-width:640px){
  .quiz-stage{flex-direction:column;align-items:center;gap:8px}
  .quiz-stage .fz-paw-above{width:clamp(140px,38vw,168px);height:clamp(140px,35vw,160px);min-height:140px;margin:0 auto}
  .quiz-bubble{width:100%}
  .quiz-bubble::before,.quiz-bubble::after{top:auto;left:50%;transform:translateX(-50%)}
  .quiz-bubble::before{top:-19px;border-right-color:transparent;border-bottom-color:var(--line)}
  .quiz-bubble::after{top:-16px;border-right-color:transparent;border-bottom-color:var(--panel-soft)}
}

/* 3D Volumetric Mochi Mascot Viewport */
.fz-mochi-viewport{
  position:absolute;top:0;left:0;width:100%;height:100%;
  overflow:visible;display:flex;align-items:center;justify-content:center;
  pointer-events:none;z-index:1;
}
.fz-mochi-viewport canvas{overflow:visible;display:block;pointer-events:none}
.fz-paw-slot:has(.fz-mochi-viewport),
.fsl-mascot-slot:has(.fz-mochi-viewport),
fiezel-mascot:has(.fz-mochi-viewport){overflow:visible!important}

/* URUTAN LAPIS: KARTU DI ATAS MASKOT.
   .fz-paw-slot memasang z-index:1 dan .fz-mascot .fz-svg memakai overflow:visible - jadi
   gambar maskot boleh melukis DI LUAR kotak layoutnya, dan karena z-index-nya lebih tinggi
   daripada kartu (auto), lukisan itu jatuh DI ATAS teks. Di layar tanpa aksesori lewatnya
   cuma 6px dan tidak terlihat; begitu Pau memakai topi, lewatnya jauh lebih besar dan ia
   menutupi "Benar, mantap!" beserta kalimat pembahasannya - dilaporkan owner dengan
   tangkapan layar.
   Diperbaiki di urutan lapis, BUKAN dengan memotong maskot (overflow:hidden akan memenggal
   telinga dan topinya) dan bukan dengan menebak tinggi aksesori yang bisa berubah kapan
   saja: kartu dinaikkan di atas maskot. Bagian bawah tokoh tersembunyi di balik tepi atas
   kartu - itu justru pose "berdiri di belakang kartu" yang memang dituju, dan teks tidak
   akan pernah tertimpa apa pun yang digambar maskot. */
.quiz-shell .fz-paw-above{--fz-paw-size:clamp(104px,19dvh,164px);--fz-paw-headroom:2px;margin-bottom:-6px;z-index:0}
body.fz-stage-quiz .quiz-shell>.card{position:relative;z-index:1}
/* Ponsel pendek: tokoh tetap hadir tapi tidak boleh mendorong pilihan jawaban keluar
   layar. 667px terukur meluber 12px pada tangga 26dvh, jadi tangganya diturunkan di sini,
   bukan lantai sasaran sentuh yang dipangkas. */
@media (max-height:740px){.quiz-shell .fz-paw-above{--fz-paw-size:clamp(88px,17dvh,128px)}
  .quiz-shell .options{gap:10px}.quiz-shell .options button{min-height:48px}}
@media (max-height:600px){.quiz-shell .fz-paw-above{--fz-paw-size:80px}}

/* Sisa ruang diberikan ke ISI, bukan dibiarkan menganggur: pilihan jawaban di layar kuis
   mendapat tinggi dan jarak sedikit lebih lega. Lantai 44px tidak diturunkan - ini
   menaikkan, bukan memampatkan. */
.quiz-shell .options{gap:12px}
.quiz-shell .options button{min-height:56px}

/* PEMBAHASAN TIDAK LAGI DIPAKSA JADI LEMBAR MENGAMBANG - DICABUT 2026-08-31.
   Di sini sempat berdiri aturan yang membuat #feedback dan #tutorTurn position:fixed di
   dasar layar, untuk memenuhi permintaan "penjelasan muncul sebagai popup". Itu SALAH,
   dan owner menemukannya sebagai bug di semua sesi: panelnya MENUTUPI pilihan jawaban
   yang masih ada di bawahnya. Terukur setelah dicabut-uji: tiga tombol jawaban tertimpa
   #tutorTurn di satu sesi vocab.
   Sebab kesalahannya, supaya tidak diulang: #tutorTurn BUKAN teks pembahasan yang pasif.
   Ia panel tutor yang punya kontrolnya sendiri ("Aku masih belum paham", tutor-turn-ask,
   #tutorStuck) dan berdiri DI DALAM alur kartu bersama pilihan jawaban yang masih hidup.
   Melayangkannya di atas alur itu berarti menutupi bagian yang masih dipakai murid -
   position:fixed mengeluarkan elemen dari aliran, jadi tidak ada yang memberi ruang
   untuknya dan tidak ada satu pun yang bergeser.
   Kalau permintaan "popup" itu dikerjakan ulang, ia harus dikerjakan di JS: memindahkan
   isinya ke lapisan dialog yang benar (openModal, yang sudah punya scrim dan pengurungan
   fokus) SETELAH pilihan jawaban tidak lagi relevan - bukan menggeser satu properti CSS
   pada elemen yang masih bertetangga dengan kontrol hidup. */

/* ruang telinga dipesan di kartu, bukan didorong setelah cat (C3) *//* ruang telinga dipesan di kartu, bukan didorong setelah cat (C3) */
.card.has-paw-peek{position:relative;margin-top:calc(56px*.44 + 8px)}
/* tier 48 di ponsel sempit & landscape pendek (tabel §2d) */
@media (max-width:420px){
  .fz-paw-peek{--fz-paw-size:48px}
  .card.has-paw-peek{margin-top:calc(48px*.44 + 8px)}
}
@media (orientation:landscape) and (max-height:479px){
  .fz-paw-peek{--fz-paw-size:48px}
  .card.has-paw-peek{margin-top:calc(48px*.44 + 8px)}
}

/* S — kolom samping desktop >=980: grid MEMESAN kolomnya (nol CLS). Topbar
   membentang dua kolom; kartu tetap di kolom isi; slot menempel sticky di
   bawah topbar (top:96px menjauhi zona topbar, C5). */
@media (min-width:980px){
  .quiz-shell.has-paw-side{display:grid;grid-template-columns:minmax(0,1fr) 164px;column-gap:16px;align-items:start}
  .quiz-shell.has-paw-side>*{grid-column:1}
  .quiz-shell.has-paw-side>.quiz-topbar{grid-column:1/-1}
  .quiz-shell.has-paw-side>.fz-paw-side{
    grid-column:2;grid-row:2/span 8;position:sticky;top:96px;
    --fz-paw-size:148px;--fz-paw-headroom:32px;
    align-items:flex-start;justify-content:center;height:auto;
  }
}
/* Rotasi/resize di tengah soal: anchor baru menunggu render berikutnya
   (§2d baris terakhir). Di bawah 980 grid-nya bubar sendiri; slot samping
   disembunyikan supaya tidak jatuh ke aliran blok di bawah kartu. */
@media (max-width:979px){.fz-paw-side{display:none}}

/* Kurangi-gerak, tiga lapis (OS / body.reduce-motion / .is-static dari
   preferensi in-app): maskot slot diam pada pose st-<pose> yang dicap markup;
   fiezel-paw-slot.js membekukannya via setState(pose,{hold:0}). */
@media (prefers-reduced-motion:reduce){.fz-paw-slot fiezel-mascot{animation:none}}
body.reduce-motion .fz-paw-slot fiezel-mascot,
.fz-paw-slot.is-static fiezel-mascot{animation:none}

/* Bayangan lantai & confetti tidak bermakna pada tier kecil yang terpotong
   (perluasan aturan crop lama fiezel-motion.css) — juga menjaga C4: tidak ada
   partikel yang lolos dari kotak peek. */
.fz-paw-peek fiezel-mascot .fz-shadow,
.fz-paw-peek fiezel-mascot .fz-confetti-layer{display:none}

/* ============================================================
   LAPISAN OUTFIT PAW (G5' — pau-redesign/systems/19-outfit-system.md).
   Milik subagent Outfit Layer. Item = geometri STATIS di grup jangkar
   fz-outfit-*; TANPA keyframe milik sendiri (gerak-mikro opsional 19 §4.2
   SENGAJA tidak dipakai -> aman-statis by construction, G9/19 §6.4).
   Warna item hidup di markup SVG (palet tertutup G1); tidak ada hex
   karakter baru di blok CSS ini. Kill switch: localStorage fzPawOutfits.
   ============================================================ */
/* pompom topi tidur (cy=8, r=11) menjulur 3px melewati tepi atas viewBox;
   saat berpakaian, svg dibiarkan meluap — crop tier kecil tetap milik
   wadahnya (fz-paw-peek dkk memotong di level container, bukan svg). */
fiezel-mascot.fz-has-outfit .fz-svg{overflow:visible}
/* pagar 3 lapis kurangi-gerak (OS / preferensi in-app / slot statis):
   apa pun yang kelak menempel di item outfit tidak boleh bergerak —
   item tetap TAMPIL dan statis (19 §6.4), tidak pernah disembunyikan. */
@media (prefers-reduced-motion:reduce){
  .fz-outfit-back *,.fz-outfit-head *,.fz-outfit-front *{animation:none!important;transition:none!important}
}
body.reduce-motion .fz-outfit-back *,body.reduce-motion .fz-outfit-head *,body.reduce-motion .fz-outfit-front *,
.fz-paw-slot.is-static .fz-outfit-back *,.fz-paw-slot.is-static .fz-outfit-head *,.fz-paw-slot.is-static .fz-outfit-front *{
  animation:none!important;transition:none!important}

/* ==================================================================== *
 * FASE-9 PERMUKAAN (impl-09): kelahiran gelembung + degradasi ukuran kecil
 * -------------------------------------------------------------------- *
 * Dua urusan yang sama-sama milik permukaan pemakai maskot:
 *   1. Kelahiran pop gelembung pembimbing pasca-onboarding (impl-04).
 *   2. Saringan parameter ekspresi untuk potongan kepala kecil (07 §5) -
 *      degradasi adalah saringan saat render, BUKAN artwork terpisah.
 * Semua transform di sini hanya scale/opacity - aman untuk gerbang G1.
 * ==================================================================== */

/* --- 1. Kelahiran gelembung (penerima 'fiezel-onboarding-paw-handoff') --
   is-prebirth dipasang JS BEGITU event serah terima tiba: gelembungnya
   disembunyikan dulu supaya yang dilihat murid adalah kelahiran, bukan
   gelembung yang ternyata sudah menunggu. transition:none mematikan
   transisi transform bawaan tombol agar scale(.2) terpasang seketika. */
.fz-coach-bubble.is-prebirth{opacity:0;transform:scale(.2);pointer-events:none;transition:none}
@keyframes fzBubbleBirth{
  0%{opacity:0;transform:scale(.2)}
  62%{opacity:1;transform:scale(1.08)}   /* overshoot pegas kecil - pop, bukan ledakan */
  100%{opacity:1;transform:scale(1)}
}
.fz-coach-bubble.is-paw-birth{animation:fzBubbleBirth .42s cubic-bezier(.34,1.56,.64,1) both}
/* Kurangi-gerak: kemunculan minimal fade (10 §2) - JS sudah memilih kelas fade,
   dua aturan di bawah adalah sabuk pengaman kalau kelas pop tetap terpasang. */
@keyframes fzBubbleBirthFade{from{opacity:0}to{opacity:1}}
.fz-coach-bubble.is-paw-birth-fade{animation:fzBubbleBirthFade .24s ease-out both}
@media (prefers-reduced-motion:reduce){
  .fz-coach-bubble.is-paw-birth{animation:fzBubbleBirthFade .24s ease-out both}
}
body.reduce-motion .fz-coach-bubble.is-paw-birth{animation:fzBubbleBirthFade .24s ease-out both}

/* --- 2a. Baris dengar/ucap 38px: potongan kepala 178%/-8% (12 §Small) ---
   Addon speaking-listening menampilkan BADAN PENUH 38px - pada ukuran itu
   wajah tidak terbaca dan melanggar tangga merek "head-first di bawah 58px".
   Addon bukan milik fase ini, jadi potongannya dipasang dari sini dengan
   selektor berspesifisitas lebih tinggi (menang tanpa peduli urutan muat).
   Angka 178%/-8% identik dengan pola kanonik di fiezel-motion.css. */
.fsl-mascot-slot{position:relative}
.fsl-mascot-slot:has(fiezel-mascot):not(:has(.fz-mochi-viewport)){overflow:hidden;background:var(--cream,#FDFAF3)}
.fsl-mascot-slot:has(.fz-mochi-viewport){
  overflow:visible!important;background:transparent!important;
  width:clamp(130px,30vw,160px);height:clamp(120px,28vw,150px);
  min-width:130px;min-height:120px;aspect-ratio:16/15;
}
.fsl-mascot-slot:has(.fz-mochi-viewport) fiezel-mascot.fsl-mascot{
  position:relative;left:0;top:0;width:100%;height:100%;
  transform:none;pointer-events:auto;overflow:visible;
}
.fsl-mascot-slot fiezel-mascot.fsl-mascot{
  position:absolute;left:50%;top:-8%;width:178%;height:auto;
  transform:translateX(-50%);
  pointer-events:none; /* klik harus jatuh ke kontrol pemutar, bukan maskot */
}
.fsl-mascot-slot fiezel-mascot .fz-svg{width:100%;height:100%}
.fsl-mascot-slot fiezel-mascot .fz-shadow,
.fsl-mascot-slot fiezel-mascot .fz-confetti-layer{display:none}

/* --- 2b. Set terkuantisasi 42px (07 §5) - semua potongan kepala kecil ----
   Wadah milik fase ini: strip "Kata FIEZEL" 42, cincin hasil 52, modal level
   56, catatan peta 28, gelembung 58/46, kepala panel 38, baris dengar 38/46.
   Yang DIBUANG di bawah 58px: kelopak bawah, condong kepala (lengan/ekor
   sudah di luar potongan). CSS `transform:none!important` menang atas atribut
   transform yang dipasang _applyTuple - itulah mekanisme saringannya. */
.coach-strip .coach-strip-face fiezel-mascot .fz-lid-low,
.ring-row .coach-strip-face fiezel-mascot .fz-lid-low,
.level-entry-face .coach-strip-face fiezel-mascot .fz-lid-low,
.map-note .coach-strip-face fiezel-mascot .fz-lid-low,
.fz-coach-bubble fiezel-mascot .fz-lid-low,
.fz-coach-avatar fiezel-mascot .fz-lid-low,
.fsl-mascot-slot fiezel-mascot .fz-lid-low{transform:none!important}
.coach-strip .coach-strip-face fiezel-mascot .fz-head,
.ring-row .coach-strip-face fiezel-mascot .fz-head,
.level-entry-face .coach-strip-face fiezel-mascot .fz-head,
.map-note .coach-strip-face fiezel-mascot .fz-head,
.fz-coach-bubble fiezel-mascot .fz-head,
.fz-coach-avatar fiezel-mascot .fz-head,
.fsl-mascot-slot fiezel-mascot .fz-head{transform:none!important;animation:none!important}
/* Alis fokus-rendah (thinking) dilewati pada set 42 - pada bingkai statis
   applyFace tidak ada kelas state, jadi aproksimasinya lewat st-thinking. */
.coach-strip .coach-strip-face fiezel-mascot.st-thinking .fz-brows,
.ring-row .coach-strip-face fiezel-mascot.st-thinking .fz-brows,
.level-entry-face .coach-strip-face fiezel-mascot.st-thinking .fz-brows,
.fz-coach-bubble fiezel-mascot.st-thinking .fz-brows,
.fz-coach-avatar fiezel-mascot.st-thinking .fz-brows,
.fsl-mascot-slot fiezel-mascot.st-thinking .fz-brows{opacity:0!important}

/* --- 2c. Set terkuantisasi 28px (07 §5) - HANYA catatan peta --------------
   Di 28px cuma lima bacaan jujur yang bertahan: content, excited/celebrating,
   surprised, calm/sleepy, attentive. Salurannya tinggal telinga + kelopak
   atas + mulut {smile, open, o} + blush; sisanya netral. Confused dan
   gentle-concern TIDAK PERNAH tampil di 28px - lihat pemetaan mulutnya. */
.map-note .coach-strip-face fiezel-mascot .fz-brows{opacity:0!important}
.map-note .coach-strip-face fiezel-mascot .fz-pupil{transform:none!important}
.map-note .coach-strip-face fiezel-mascot .fz-eyes{transform:none!important} /* gaze mati */
.map-note .coach-strip-face fiezel-mascot .fz-eye-open{transform:none!important} /* eye pop mati; swap happy-eye (opacity) tetap hidup */
.map-note .coach-strip-face fiezel-mascot .fz-acc{opacity:0!important;animation:none!important} /* keringat/air mata/zzz = bintik tak terbaca */
/* Mulut dikuantisasi ke {smile, open, o}. Mulut terlarang disembunyikan;
   bila justru mulut terlarang itulah yang aktif (style inline BUKAN "none"),
   smile dinaikkan sebagai bacaan pengganti. !important menang atas inline. */
.map-note .coach-strip-face fiezel-mascot :is(.fz-m-wave,.fz-m-flat,.fz-m-concern,.fz-m-sad){display:none!important}
.map-note .coach-strip-face fiezel-mascot:has(:is(.fz-m-wave,.fz-m-flat,.fz-m-concern,.fz-m-sad):not([style*="none"])) .fz-m-smile{display:block!important}

/* ============================================================================
   v6.1 CALM (O4 §2 + §4, 2026-08-28) — hirarki bayangan & tier kartu.
   Model elevasi: E0 konten dalam alur = TANPA bayangan; E1 --shadow-sm hanya
   untuk SATU keluarga permukaan istirahat per layar; E2 --shadow-md untuk
   chrome yang lepas dari alur (nav, launcher); E3 --shadow-lg di atas scrim.
   Saluran taktil (--lift-sun/--lift-edge) terpisah dan bukan elevasi.
   .feedback tidak pernah punya bayangan ambient — garis status inset di
   .feedback-success/error (di atas) adalah stripe status, BUKAN elevasi; tetap.
   .stats>div juga sudah bebas bayangan — biarkan begitu.
   ========================================================================= */
/* Tier kartu (O4 §4): quiet = tanpa bayangan+entrance, flat = benar-benar rata. */
.card.card-quiet{box-shadow:none;animation:none}
.card.card-flat{box-shadow:none;animation:none;border-color:var(--line)}
/* Grammar Hub: baris daftar dalam satu daftar, bukan kartu-kartu melayang. */
.grammar-grid .card{box-shadow:none;animation:none}
/* Panggung kuis: hanya kartu soal yang memegang E1; kartu lain (passage,
   tutor host, dsb.) turun ke E0 supaya layar soal berhenti bersaing. */
body.fz-stage-quiz .card{box-shadow:none}
body.fz-stage-quiz .card:has(#quizStem){box-shadow:var(--shadow-sm)}
/* Tier GHOST (O4 §8): .text-button diresmikan sebagai tingkat ketiga tombol —
   target sentuh 44px, tanpa border/bayangan, hover cukup bidang lembut. */
.text-button{min-height:44px;padding:var(--sp-2) var(--sp-3);border-radius:var(--radius-xs);
  font-size:var(--fs-small);font-weight:700}
.text-button:hover{background:var(--panel-soft)}
/* Hukum hirarki tipografi (O4 §5): DI DALAM pelajaran, judul halaman didemosi ke h2
   supaya soal (.question) dan .lesson-title yang memimpin — aturan display global
   di blok Fredoka tidak disentuh. */
body.fz-stage-quiz .section-head h1,
body.fz-stage-grammar-lesson .section-head h1{font-family:var(--fz-heading);font-weight:700;font-size:var(--fs-h2)}
/* ==========================================================================
   ===== FASE3 / W3-FONT — TIPOGRAFI THAI (semua aturan HANYA :lang(th)) =====
   Ditambahkan append-only di bawah marker FASE3 sesuai konvensi (style.css
   ±3227): cascade posisi akhir menang tanpa !important, dan nol byte aturan
   id yang ada disentuh — murid Indonesia tidak melihat perubahan apa pun.
   Dasar: AI-05 F01/F02 (webfont brand 0 glyph Thai, tanpa unicode-range),
   AI-05 F03 + AI-04 F06 (line-height ketat merusak tumpukan sara/wannayuk),
   AI-05 F04 (letter-spacing lebar memecah bentuk kata Thai), AI-04 F01
   (tanpa jaring pengaman pembungkusan kata).
   ========================================================================== */

/* Noto Sans Thai Looped — keputusan orkestrator (IMPL-BRIEF): wajah looped,
   subset self-host dari repo resmi google/fonts (lisensi OFL 1.1, salinan di
   assets/fonts/OFL-NotoSansThaiLooped.txt). Empat berat statis diinstansiasi
   dari VF resmi lalu di-subset (Thai U+0E00-0E7F + Latin dasar + tanda baca
   umum), ±40 KB per berat. unicode-range membatasi wajah ini ke blok Thai
   SAJA: huruf Latin/angka di kalimat campur tetap memakai wajah brand
   (AI-05 F02), dan peramban murid id TIDAK PERNAH mengunduh berkas ini
   karena deklarasinya baru aktif saat ada karakter Thai di layar
   (AI-05 F09 — itu sebabnya TIDAK ada preload statis di index.html;
   pengisian offline lewat manifest features/i18n/locale-assets-th.json). */
@font-face{font-family:'Noto Sans Thai Looped';font-style:normal;font-weight:400;font-display:swap;
  src:url('./assets/fonts/NotoSansThaiLooped-400.woff2') format('woff2');unicode-range:U+0E00-0E7F}
@font-face{font-family:'Noto Sans Thai Looped';font-style:normal;font-weight:500;font-display:swap;
  src:url('./assets/fonts/NotoSansThaiLooped-500.woff2') format('woff2');unicode-range:U+0E00-0E7F}
@font-face{font-family:'Noto Sans Thai Looped';font-style:normal;font-weight:600;font-display:swap;
  src:url('./assets/fonts/NotoSansThaiLooped-600.woff2') format('woff2');unicode-range:U+0E00-0E7F}
@font-face{font-family:'Noto Sans Thai Looped';font-style:normal;font-weight:700;font-display:swap;
  src:url('./assets/fonts/NotoSansThaiLooped-700.woff2') format('woff2');unicode-range:U+0E00-0E7F}

/* Token font di bawah locale th: wajah Thai disisipkan DI DEPAN stack brand.
   Karena unicode-range di atas, "di depan" hanya berarti karakter Thai yang
   mengambilnya — Latin lolos ke wajah brand berikutnya, jadi kartu dwibahasa
   (AI-05 F05) memakai brand untuk Inggris dan Noto Thai untuk Thai dalam satu
   baris. :root:lang(th) (0,2,0) menang atas :root (0,1,0); duplikat token di
   dalam .fiezel-splash/.fiezel-ob TIDAK ditimpa — zona splash byte-parity
   (AI-04 F10) tetap utuh dan memang tidak memuat konten Thai. */
:root:lang(th){
  --fz-display:'Noto Sans Thai Looped','FZ Instrument Serif',Georgia,'Times New Roman',serif;
  --fz-display-round:'Noto Sans Thai Looped','FZ Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --fz-heading:'Noto Sans Thai Looped','FZ Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --fz-body:'Noto Sans Thai Looped','FZ Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}

/* Lantai line-height Thai (AI-05 F03 / AI-04 F06): sara atas + tanda nada
   menumpuk sampai 3 tingkat; di bawah ±1.35 baris display saling tabrak dan
   terpangkas oleh leluhur overflow:hidden. Nilai Latin id TIDAK diubah.
   letter-spacing negatif juga dinolkan — tracking rapat membuat tanda nada
   menabrak glyph berikutnya (AI-05 F04 poin c). */
:lang(th) .launcher-copy h1,
:lang(th) .launcher-copy h1.login-message{line-height:1.4;letter-spacing:normal}
:lang(th) .hero h2{line-height:1.35;letter-spacing:normal}
:lang(th) .question{line-height:1.6;letter-spacing:normal;white-space:pre-line}
:lang(th) .option{line-height:1.6;letter-spacing:normal}
:lang(th) .section-head p{line-height:1.5}
:lang(th) .launch-card b{line-height:1.45;letter-spacing:normal}
:lang(th) .launch-card small{line-height:1.45}
:lang(th) .modal-panel,
:lang(th) .dialog,
:lang(th) .confidence-card,
:lang(th) .feedback,
:lang(th) .passage{line-height:1.62;letter-spacing:normal}
:lang(th) .feedback p,
:lang(th) .feedback-title,
:lang(th) .modal-panel p,
:lang(th) .modal-panel h2,
:lang(th) .modal-panel h3,
:lang(th) .confidence-verdict,
:lang(th) .reading-jump-btn,
:lang(th) .quiz-floating-next-btn{line-height:1.6;letter-spacing:normal;padding-top:2px;padding-bottom:2px}

/* Jaring pengaman pembungkusan (AI-04 F01/F02): Thai tanpa spasi antar-kata;
   segmentasi kamus peramban gagal pada nama/serapan panjang dan body punya
   overflow-x:hidden yang MENYEMBUNYIKAN blowout. break-word (bukan anywhere)
   supaya pemenggalan kamus tetap diutamakan; line-break:normal mengunci
   kebijakan pemenggalan lintas peramban. */
:lang(th) .question,:lang(th) .option,:lang(th) .card,:lang(th) .toast,
:lang(th) .coach-body,:lang(th) .hero-line,:lang(th) .launcher-lead,
:lang(th) .flash-face,:lang(th) .modal-panel,:lang(th) .section-head p,
:lang(th) .launch-card,:lang(th) .classroom-id{overflow-wrap:break-word;line-break:normal}

/* Micro-label (AI-05 F04): tracking lebar .1-.32em menyisipkan celah di dalam
   kata Thai (tanpa spasi antar-kata) dan menghancurkan bentuk kata; uppercase
   memang no-op untuk Thai jadi dibiarkan. .fiezel-splash-tag SENGAJA tidak
   disentuh — ia hidup di blok byte-parity splash (AI-04 F10) dan tagline
   splash tetap Latin (brand, bukan konten pelajar). */
:lang(th) .eyebrow,
:lang(th) .fiezel-stepper-eyebrow,
:lang(th) .core-eyebrow,
:lang(th) .launcher-meta,
:lang(th) .fiezel-ob-tag{letter-spacing:normal}
/* ============================== ONLINE / SOSIAL (SLOT 7) ==============================
   Lapisan sosial memakai token merek yang sudah ada (Warm Paper + --gold + --ink) —
   tidak ada palet baru. Semua interaksi = tombol/enum; tidak ada kolom teks bebas. */
.social-card h3{margin-bottom:6px}
.social-me{display:flex;align-items:center;gap:12px;margin:6px 0 10px}
.social-avatar{flex:0 0 auto;width:40px;height:40px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:1.05rem;color:var(--ink);background:linear-gradient(135deg,rgba(201,162,75,.35),rgba(201,162,75,.12));border:1.5px solid var(--gold)}
.social-stats{margin-top:8px}
.social-handle-status{min-height:1.2em;margin:4px 0 8px;font-size:.82rem}
.social-handle-status.social-ok{color:#2c7a3f;font-weight:600}
.social-code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:1.7rem;font-weight:700;letter-spacing:.35em;text-align:center;padding:14px 8px;margin:10px 0;border-radius:14px;border:1.5px dashed var(--gold);background:rgba(201,162,75,.08);color:var(--ink);user-select:all}
/* Ajakan pasang ke Home Screen sesudah undangan diterima di tab peramban (bukan aplikasi
   terpasang). Garis pemisah tipis di atasnya supaya tidak menyatu dengan tombol Duel di
   atasnya — ini langkah opsional berikutnya, bukan bagian dari keberhasilan menerima teman. */
.social-install-nudge{margin-top:14px;padding-top:14px;border-top:1px solid var(--line-soft)}
.social-chip{display:inline-block;padding:2px 9px;border-radius:999px;font-size:.72rem;font-weight:600;border:1px solid var(--gold);color:var(--ink);background:rgba(201,162,75,.12)}
.social-chips{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.social-friend{display:flex;align-items:center;gap:11px;padding:10px 0;border-bottom:1px solid rgba(36,26,17,.08)}
.social-friend:last-child{border-bottom:none}
.social-friend-body{flex:1;min-width:0}
.social-friend-body small{display:block;color:var(--ink-soft)}
.social-cheer-btn{flex:0 0 auto;padding:7px 12px;border-radius:12px;font-size:.82rem}
.social-sticker-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin:12px 0}
.social-sticker{display:flex;flex-direction:column;align-items:center;gap:4px;padding:12px 6px;border-radius:14px}
.social-sticker span{font-size:1.5rem;line-height:1}
.social-sticker small{font-size:.72rem}
.social-boardrow{display:flex;align-items:center;gap:10px;padding:9px 8px;border-radius:12px}
.social-boardrow+.social-boardrow{margin-top:4px}
.social-row-me{background:rgba(201,162,75,.16);border:1.5px solid var(--gold);font-weight:600}
.social-rank{flex:0 0 1.6em;text-align:right;font-variant-numeric:tabular-nums;color:var(--ink-soft)}
.social-board-handle{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.social-pb{font-variant-numeric:tabular-nums}
.social-empty{text-align:center;padding:18px 8px}
.social-countdown{display:flex;align-items:center;gap:6px}
.social-summary .modal-actions{margin-top:8px}

/* G15-07 (wave2): scope instrumen di bawah nama level hasil placement */
.result-level-scope{display:block;font-size:.72rem;font-weight:500;opacity:.75;margin-top:2px;letter-spacing:.01em}

/* ---------------------------------------------------------------------------------------
   CINCIN FOKUS HANYA UNTUK PAPAN TIK (m025-197 - laporan OWNER kedua)

   m025-196 memindahkan semua cincin dari `:focus` ke `:focus-visible` dan itu tidak cukup.
   Sebabnya ada di spesifikasi, bukan di kode ini: untuk KOLOM TEKS peramban MENCOCOKKAN
   `:focus-visible` walau fokusnya datang dari ketukan jari, karena kolom yang sedang
   menerima ketikan dianggap selalu layak diberi penanda. Hasilnya kotaknya tidak hilang -
   ia cuma berganti warna dari emas ke tinta. Pemilik melihatnya, dan ia benar.

   CSS sendirian tidak bisa membedakan "fokus karena jari" dari "fokus karena Tab".
   `features/ui/fiezel-zoom-lock.js` yang membedakannya lewat data-fz-input, dan aturan
   di bawah ini yang memakainya.

   `outline-color:transparent`, BUKAN `outline:none`: lebar dan offset cincin tetap ada,
   jadi tidak ada satu piksel pun yang bergeser saat mode berpindah - dan aturan
   a11y-test "setiap outline yang dimatikan punya penanda pengganti" tidak dilanggar,
   karena tidak ada outline yang dimatikan.

   `!important` dipakai sadar: ini kebijakan tingkat aplikasi yang harus menang atas
   setiap aturan komponen, sekarang dan yang ditulis nanti. Tanpa itu, komponen
   berikutnya yang menulis cincinnya sendiri akan diam-diam mengembalikan kotaknya.

   Kalau JS gagal dimuat, atribut tidak pernah ada, aturan ini tidak pernah cocok, dan
   cincin tetap muncul. Kegagalan jatuh ke sisi aman aksesibilitas.
   --------------------------------------------------------------------------------------- */
html[data-fz-input="touch"] :focus-visible{outline-color:transparent!important;box-shadow:none!important}
html[data-fz-input="touch"] :focus{outline-color:transparent!important}

/* ==========================================================================
   AKUN FIEZEL & AUTH UI (SLOT 10)
   ========================================================================== */
.fiezel-account-card{padding:14px;background:var(--panel);border:1px solid var(--line);border-radius:var(--radius-md);margin-bottom:8px}
.account-card-header{display:flex;align-items:flex-start;gap:12px;margin-bottom:12px}
.account-card-header h3{margin:0 0 4px 0;font-size:1.05rem;color:var(--text)}
.auth-tabs{display:flex;gap:6px;padding:4px;background:var(--panel-soft);border-radius:var(--radius-pill);margin:12px 0 16px}
.auth-tab{flex:1;padding:8px 12px;border-radius:var(--radius-pill);border:none;background:transparent;color:var(--muted);font-size:.88rem;font-weight:600;cursor:pointer;transition:all .2s ease;text-align:center}
.auth-tab.active{background:var(--panel);color:var(--text);box-shadow:0 1px 3px rgba(0,0,0,.08)}
.auth-form{display:flex;flex-direction:column;gap:12px;margin-top:8px}
.auth-field-label{display:flex;flex-direction:column;gap:4px;font-size:.85rem;font-weight:600;color:var(--text);text-align:left}
.auth-field-label input{padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--panel-soft);color:var(--text);font-size:.95rem}
/* m025-250: `:focus-visible`, bukan `:focus` telanjang (kebijakan app-interaction-policy-test E:
   penanda fokus yang terlihat tidak boleh menyala pada klik tetikus). Untuk kolom teks ini
   BUKAN perubahan perilaku: peramban memperlakukan input teks sebagai selalu focus-visible,
   termasuk saat diklik - jadi cincinnya tetap muncul persis seperti sebelumnya, dan yang
   hilang hanya pengecualian diam-diam terhadap kebijakan itu. */
.auth-field-label input:focus-visible{outline:2px solid var(--sun-deep);background:var(--panel)}
.auth-google{display:flex;flex-direction:column;align-items:center;gap:8px;margin:12px 0 4px}
/* Tombol resmi Google digambar skrip Google ke dalam kotak ini; tinggi minimum
   ada supaya isi modal tidak melompat saat tombolnya akhirnya tiba. */
.auth-google-btn{min-height:44px;display:flex;justify-content:center;align-items:center}
.auth-google-status{margin:0;font-size:.85rem;color:var(--muted);text-align:center;line-height:1.45}
.auth-google-note{margin:0;font-size:.78rem;color:var(--muted);text-align:center;line-height:1.45;max-width:34ch}
.auth-google-sep{display:flex;align-items:center;gap:10px;width:100%;margin-top:4px;color:var(--muted);font-size:.8rem}
.auth-google-sep::before,.auth-google-sep::after{content:'';flex:1;height:1px;background:var(--line,rgba(0,0,0,.12))}
.auth-error-box{padding:10px 12px;background:var(--accent-soft);border:1px solid var(--accent);border-radius:var(--radius-sm);color:var(--accent-strong);font-size:.85rem;line-height:1.4;text-align:left}
.badge-success{background:#dcfce7;color:#166534;padding:2px 8px;border-radius:var(--radius-pill);font-size:.8rem}
.badge-neutral{background:var(--panel-soft);color:var(--muted);padding:2px 8px;border-radius:var(--radius-pill);font-size:.8rem}


/* ---- Lonceng notifikasi topbar + lembar notifikasi (tugas guru, teman, undangan) ---- */
.notif-button{position:relative;overflow:visible}
.notif-button.has-new i,.notif-button.has-new svg{animation:notif-ring 1.4s ease-in-out 1}
@keyframes notif-ring{0%,100%{transform:rotate(0)}15%{transform:rotate(14deg)}30%{transform:rotate(-12deg)}45%{transform:rotate(8deg)}60%{transform:rotate(-4deg)}}
.notif-badge{position:absolute;top:-3px;right:-3px;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--red,#C94F3D);color:#fff;font-size:.68rem;font-weight:700;line-height:18px;text-align:center;box-shadow:0 0 0 2px var(--panel,#fff)}
.notif-badge.hidden{display:none}
.notif-sheet{text-align:left}
.notif-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:4px 0 12px}
.notif-head h2{margin:0;font-size:1.35rem}
.notif-readall{font-size:.8rem;padding:6px 10px}
.notif-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px;max-height:min(56vh,520px);overflow:auto;padding-right:2px}
.notif-section{font-size:.7rem;text-transform:uppercase;letter-spacing:.12em;font-weight:700;color:var(--muted);padding:8px 4px 0}
.notif-item{display:grid;grid-template-columns:40px 1fr;gap:10px 12px;align-items:start;padding:12px 14px;border-radius:var(--radius-lg,18px);background:#FFFFFF !important;border:1.5px solid #E2E8F0 !important;box-shadow:0 2px 4px rgba(0,0,0,0.05);transition:background-color .2s,transform .2s}
.notif-item.is-unread{background:#F8FAFC !important;border-color:#CBD5E1 !important}
.notif-item .notif-icon{width:40px;height:40px;border-radius:12px;display:grid;place-items:center;background:#F1F5F9;color:#0284C7;box-shadow:var(--shadow-sm)}
.notif-item.is-teacher .notif-icon{background:#FEF3C7;color:#D97706}
.notif-body{display:flex;flex-direction:column;gap:2px;min-width:0}
.notif-body b{font-weight:700;line-height:1.35;font-size:.95rem;color:#0F172A !important}
.notif-body small{color:#64748B !important;font-size:.78rem}
.notif-cta{grid-column:2;justify-self:start;display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:999px;border:0;background:#0284C7;color:#FFFFFF !important;font:inherit;font-size:.85rem;font-weight:700;cursor:pointer;transition:transform .15s,background-color .2s}
.notif-cta:hover{transform:translateY(-1px);background:#0369A1}
.notif-cta.is-ghost{background:transparent;color:#0F172A !important;border:1.5px solid #CBD5E1 !important}
.notif-cta.is-ghost:hover{background:#F1F5F9}
.notif-cta i,.notif-cta svg{width:1em;height:1em}
.notif-empty{display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center;color:var(--muted);padding:26px 12px;font-size:.92rem}
.notif-empty i,.notif-empty svg{width:32px;height:32px;opacity:.6}

/* =====================================================================================
   PALET CERIA PASTEL (permintaan owner 2026-09-04): Home klasik kembali (todayHome off,
   nav 5 tab) + warna pastel yang lebih hidup: kuning, merah muda, mint, lilac bergilir di
   kartu, chip, dan ikon. Tinta tetap coklat gelap supaya kontras aman.
   ===================================================================================== */
/* F17: token blok ini pindah ke :root tunggal di awal berkas. */
body{background:var(--bg)}
/* Judul seksi serif ramah */
.home-section-head h2,.today-title,.lf h1,.lf-card h2,.launcher-copy h1{font-family:var(--fz-heading);font-weight:700;letter-spacing:-.015em}
/* Kartu peluncur bergilir pastel (spesifisitas di atas html.fiezel-ui-v6 .launch-card) */
html body #app .launch-card{background:var(--pz-yellow);border-color:var(--pz-yellow-line);transition:transform .2s,box-shadow .2s,background-color .2s}
html body #app .launch-card:nth-child(4n+2){background:var(--pz-pink);border-color:var(--pz-pink-line)}
html body #app .launch-card:nth-child(4n+3){background:var(--pz-mint);border-color:var(--pz-mint-line)}
html body #app .launch-card:nth-child(4n+4){background:var(--pz-lilac);border-color:var(--pz-lilac-line)}
html body #app .learner-flow-launcher .learn-launch{background:linear-gradient(135deg,var(--pz-yellow) 0%,#F3E3C0 55%,#EFDFB8 100%)}
html body #app .launch-card:hover{transform:translateY(-2px);box-shadow:var(--shadow-md)}
html body #app .launch-card .launch-icon{background:rgba(255,255,255,.8);border-color:transparent;color:var(--pz-yellow-ink);box-shadow:var(--shadow-sm)}
html body #app .launch-card:nth-child(4n+2) .launch-icon{color:var(--pz-pink-ink)}
html body #app .launch-card:nth-child(4n+3) .launch-icon{color:var(--pz-mint-ink)}
html body #app .launch-card:nth-child(4n+4) .launch-icon{color:var(--pz-lilac-ink)}
html body #app .launch-card small{color:var(--muted)}
html body #app .launch-card .launch-icon.fz-launch-3d{background:transparent!important;border:none!important;box-shadow:none!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:center!important;filter:drop-shadow(0 4px 8px rgba(0,0,0,0.22))!important;width:44px!important;height:44px!important}
html body #app .launch-card .launch-icon.fz-launch-3d svg{width:100%!important;height:100%!important;display:block!important}
/* Empat skill inti: pastel lebih jenuh + ring berwarna */
.skill-listening{--skill-bg:var(--pz-yellow);--skill-line:var(--pz-yellow-line);--skill-ink:#F2B705}
.skill-speaking{--skill-bg:var(--pz-pink);--skill-line:var(--pz-pink-line);--skill-ink:#E0705F}
.skill-reading{--skill-bg:var(--pz-mint);--skill-line:var(--pz-mint-line);--skill-ink:#2E8B69}
.skill-writing{--skill-bg:var(--pz-lilac);--skill-line:var(--pz-lilac-line);--skill-ink:#7A62C4}
.skill-card{box-shadow:0 8px 24px -14px rgba(36,26,17,.35);transition:transform .2s,box-shadow .2s}
.skill-card:hover{transform:translateY(-2px)}
/* Chip statistik hero */
.hero-stats>*:nth-child(1){background:var(--pz-yellow)!important;border-color:var(--pz-yellow-line)!important}
.hero-stats>*:nth-child(2){background:var(--pz-mint)!important;border-color:var(--pz-mint-line)!important}
.hero-stats>*:nth-child(3){background:var(--pz-pink)!important;border-color:var(--pz-pink-line)!important}
.hero-stats>*:nth-child(4){background:var(--pz-lilac)!important;border-color:var(--pz-lilac-line)!important}
/* Kartu Today Plan / alur belajar */
.today-card,.lf-card{background:#fff;border:0;box-shadow:var(--shadow-md)}
.lf-plan-list li:nth-child(4n+1){background:var(--pz-yellow)}
.lf-plan-list li:nth-child(4n+2){background:var(--pz-pink)}
.lf-plan-list li:nth-child(4n+3){background:var(--pz-mint)}
.lf-plan-list li:nth-child(4n+4){background:var(--pz-lilac)}
.lf-plan-list li{border-radius:var(--radius-md);padding:12px 14px;margin:8px 0}
.lf-skill.is-strong{background:var(--pz-mint)}.lf-skill.is-growing{background:var(--pz-yellow)}.lf-skill.is-review{background:var(--pz-pink)}
.lf-goal{background:var(--pz-yellow);border-color:var(--pz-yellow-line)}.lf-goal:nth-child(2){background:var(--pz-mint);border-color:var(--pz-mint-line)}.lf-goal:nth-child(3){background:var(--pz-pink);border-color:var(--pz-pink-line)}.lf-goal:nth-child(4){background:var(--pz-lilac);border-color:var(--pz-lilac-line)}
/* Kartu sosial & notifikasi */
html body #app .social-home-launcher .launch-card{background:var(--pz-sky);border-color:var(--pz-sky-line)}
.social-home-launcher .launch-icon{color:var(--pz-sky-ink)}
.notif-item.is-teacher{background:var(--pz-yellow);border-color:var(--pz-yellow-line)}
.notif-item.is-social{background:var(--pz-mint);border-color:var(--pz-mint-line)}
.notif-item.is-invite{background:var(--pz-pink);border-color:var(--pz-pink-line)}
/* Nav bawah: pil putih, tab aktif tinta gelap dengan ikon emas */
.bottomnav{background:var(--glass-solid)}
/* Topbar: lonceng & pengaturan sebagai chip pastel */
.topbar .icon-button{background:#fff;border:0;box-shadow:var(--shadow-sm)}
.notif-button.has-new{background:var(--pz-yellow)}
/* m029 "Lembut": tombol utama pindah dari kuning terang ke aksen marun diredam.
   Kuning penuh cuma 1,5:1 di atas latar dan tidak pernah boleh jadi warna teks;
   aksen ini 6,8:1 di atas kertas, jadi label putih di atasnya aman. */
.primary{background:var(--accent);color:#fff;border-color:transparent}

/* ==========================================================================
   FIEZEL REDESIGN: Version B PAW Mascot Hero & Contextual Speech Bubble
   ========================================================================== */
.paw-hero-cockpit {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
  padding: 12px 14px;
  background: var(--panel);
  border: 1.5px solid var(--surface-edge);
  border-radius: var(--radius-xl, 22px);
  box-shadow: 0 4px 16px rgba(36, 26, 17, 0.05);
}
.paw-hero-avatar {
  flex: 0 0 60px;
  width: 60px;
  height: 60px;
  border-radius: var(--radius-lg, 18px);
  background: var(--sun-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 0 rgba(230, 168, 0, 0.4);
  position: relative;
  cursor: pointer;
  transition: transform var(--dur-s) var(--ease-spring);
}
.paw-hero-avatar:hover, .paw-hero-avatar:active {
  transform: scale(1.06) rotate(-2deg);
}
.paw-hero-avatar .fz-i {
  width: 40px;
  height: 40px;
}
.paw-speech-bubble {
  /* min-width:0 wajib: tanpa itu balon adalah flex-item yang menolak menyusut di bawah
     lebar min-content-nya, dan di 320px seluruh kokpit Home ikut melebar sampai halaman
     menggeser horizontal (gerbang T6 ui-render-audit). */
  flex: 1 1 0;
  min-width: 0;
  position: relative;
  background: var(--panel-soft, #FFFDF8);
  border: 1.5px solid var(--line);
  border-radius: 16px;
  padding: 10px 14px;
  text-align: left;
  cursor: pointer;
  transition: transform var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.paw-speech-bubble:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(36, 26, 17, 0.06);
}
.paw-speech-bubble::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 50%;
  transform: translateY(-50%) rotate(45deg);
  width: 12px;
  height: 12px;
  background: var(--panel-soft, #FFFDF8);
  border-left: 1.5px solid var(--line);
  border-bottom: 1.5px solid var(--line);
}
.paw-speech-bubble .paw-bubble-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 3px;
}
.paw-speech-bubble .paw-bubble-text {
  overflow-wrap: anywhere;
  font-size: 12px;
  line-height: 1.4;
  color: var(--muted);
  margin: 0;
}

/* ==========================================================================
   FIEZEL REDESIGN: Version C Components (Rings, Cockpit, Matrix, Classroom, Progress)
   ========================================================================== */
/* Daily Rhythm Progress Bar */
.today-rhythm-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 10px 0 14px;
  padding: 8px 12px;
  background: var(--panel-soft);
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-md);
  font-size: 12px;
}
.today-rhythm-bar .rhythm-track {
  flex: 1;
  height: 8px;
  background: var(--line);
  border-radius: 99px;
  overflow: hidden;
}
.today-rhythm-bar .rhythm-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--sun), var(--gold));
  border-radius: 99px;
  transition: width 0.4s var(--ease);
}

/* m025-375: panel "hasil latihanmu belum bisa dinilai" di Home (OWNER 2026-09-26). */
.fz-evidence-panel {
  margin: 10px 0 14px;
  padding: 12px 14px;
  background: var(--panel-soft);
  border: 1px solid var(--surface-edge);
  border-radius: var(--radius-md);
}
.fz-evidence-head {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--text);
}
.fz-evidence-body {
  margin: 6px 0 10px;
  font-size: 13px;
  line-height: 1.45;
}
/* Nama materi bisa panjang ("Waktu lampau yang jelas atau masih terhubung sekarang: ...");
   di baris sendiri, kalimat ajakannya tetap pendek dan terbaca sekali lirik. */
.fz-evidence-materi {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--muted);
}

/* Audit UI/UX Home 2026-09-27: kartu Home. */
/* Perubahan akurasi mingguan diwarnai menurut arahnya (dulu hijau mati untuk angka rekaan). */
.fz-stadium-card .fz-time-val.is-naik { color: #059669 !important; }
.fz-stadium-card .fz-time-val.is-turun { color: #DC2626 !important; }
/* Label di bawah angka dulu 9.5px - di bawah ukuran terbaca di ponsel. Selektor sengaja tiga
   kelas: mobile-edge-fit.css dimuat SESUDAH style.css dan `.fz-stadium-center-time .fz-date-val`
   (dua kelas) di sana menang pada spesifisitas yang sama. */
.fz-stadium-card .fz-stadium-center-time .fz-date-val { font-size: 11px !important; }
/* Ikon peluncur "Rencana belajar" dulu gelap di atas petak gelap (nyaris tak terlihat). */
.today-home-cockpit .launch-icon { color: var(--sun, #FFD94F); }
.today-home-cockpit .launch-icon .fz-line { stroke: currentColor; }
.today-home-cockpit .launch-icon .fz-fill { fill: currentColor; fill-opacity: .22; }
.fz-evidence-track {
  height: 8px;
  background: var(--line);
  border-radius: 99px;
  overflow: hidden;
}
.fz-evidence-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--sun), var(--gold));
  border-radius: 99px;
  transition: width 0.4s var(--ease);
}
.fz-evidence-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 10px;
  font-size: 12px;
  flex-wrap: wrap;
}
.fz-evidence-cta {
  min-height: 44px;
  padding: 0 16px;
  border-radius: 99px;
  border: 1px solid var(--surface-edge);
  background: var(--panel);
  color: var(--text);
  font-weight: 700;
  cursor: pointer;
}

/* Quick Practice Chips */
.quick-practice-section {
  margin-top: 18px;
}
/* PINTASAN BAHASA DI LAYAR DEPAN (m025-299).
   SENGAJA DI LUAR .quick-chips-grid dan TANPA kelas .quick-chip. Chip latihan di grid itu
   diwarnai lewat :nth-child(n); menaruh chip bahasa di dalamnya menggeser warna SETIAP chip
   sesudahnya - satu sisipan, empat kartu berubah rupa tanpa ada yang memintanya. Chip ini
   juga bukan latihan: ia mengganti seluruh kursus, jadi ia memang layak terbaca berbeda. */
.target-lang-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  width: 100%;
  margin: 0 0 10px;
  padding: 11px 12px;
  border-radius: var(--radius-lg);
  background: var(--pz-lilac, #efe9fb);
  border: 1.5px dashed var(--pz-lilac-line, #cbb9ee);
  cursor: pointer;
  text-align: left;
  transition: transform var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
}
.target-lang-chip:active { transform: translateY(1px); }
/* Aktif = garis penuh, bukan putus-putus: putus-putus berarti "tawaran", penuh berarti
   "sedang berjalan". Perbedaannya harus terbaca tanpa membaca tulisannya. */
.target-lang-chip.is-active {
  border-style: solid;
  box-shadow: 0 3px 0 var(--pz-lilac-line, #cbb9ee);
}
.target-lang-chip .chip-label { font-weight: 700; font-size: 13px; color: var(--text); }
.target-lang-chip .chip-sub { font-size: 11px; color: var(--muted); }

.quick-chips-grid {
  display: grid;
  /* minmax(0,...): chip berisi label nowrap, jadi kolom 1fr biasa menolak menyusut di 320px. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 10px;
}
.quick-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 12px 10px;
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: transform var(--dur-s) var(--ease), box-shadow var(--dur-s) var(--ease);
  text-align: left;
}
.quick-chip:nth-child(1) {
  background: var(--pz-yellow);
  border: 1.5px solid var(--pz-yellow-line);
  box-shadow: 0 3px 0 var(--pz-yellow-line);
}
.quick-chip:nth-child(1) .chip-label {
  color: var(--pz-yellow-ink);
}
.quick-chip:nth-child(2) {
  background: var(--pz-mint);
  border: 1.5px solid var(--pz-mint-line);
  box-shadow: 0 3px 0 var(--pz-mint-line);
}
.quick-chip:nth-child(2) .chip-label {
  color: var(--pz-mint-ink);
}
.quick-chip:nth-child(3) {
  background: var(--pz-pink);
  border: 1.5px solid var(--pz-pink-line);
  box-shadow: 0 3px 0 var(--pz-pink-line);
}
.quick-chip:nth-child(3) .chip-label {
  color: var(--pz-pink-ink);
}
.quick-chip:active {
  transform: translateY(2px);
  box-shadow: 0 0 0 transparent;
}
.quick-chip .chip-label {
  font-size: 12px;
  font-weight: 700;
}
.quick-chip .chip-sub {
  font-size: 10px;
  color: var(--muted);
}

/* Practice: Continue Learning Banner */
.continue-learning-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 16px;
  margin-bottom: 20px;
  background: linear-gradient(135deg, var(--pz-yellow) 0%, var(--pz-mint) 100%);
  border: 1.5px solid var(--pz-mint-line);
  border-radius: var(--radius-xl);
  box-shadow: 0 4px 14px rgba(31, 111, 87, 0.12), 0 2px 0 var(--pz-mint-line);
  cursor: pointer;
  text-align: left;
}
.continue-learning-card:active {
  transform: translateY(2px);
  box-shadow: 0 1px 0 var(--pz-mint-line);
}
.continue-card-body b {
  display: block;
  font-size: 14px;
  color: var(--text);
  margin-bottom: 4px;
}
.continue-card-body small {
  font-size: 11px;
  color: var(--muted);
}
.continue-card-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 99px;
  background: var(--sun);
  color: var(--text);
  font-weight: 700;
  font-size: 12px;
  box-shadow: 0 2px 0 var(--gold);
}

/* AI Weak-Spot Booster Card */
.ai-booster-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  margin-top: 18px;
  background: var(--pz-pink);
  border: 1.5px dashed var(--pz-pink-line);
  border-radius: var(--radius-lg);
  cursor: pointer;
  text-align: left;
}
.ai-booster-card:active {
  transform: translateY(1px);
}
.ai-booster-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  border-radius: 99px;
  /* Latar dipaku putih di bawah teks bertema = 1,08:1 saat Tema Malam (gerbang kontras
     m025-85). Token panel mengikuti tema, jadi lencana tetap terbaca di kedua tema. */
  background: var(--panel);
  color: var(--pz-pink-ink);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 4px;
}

/* School Tab */
.school-active-card {
  padding: 18px;
  background: var(--pz-sky);
  border: 1.5px solid var(--pz-sky-line);
  border-radius: var(--radius-xl);
  box-shadow: 0 4px 0 var(--pz-sky-line), var(--shadow-sm);
  margin-bottom: 16px;
  text-align: left;
}
.school-badge-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.school-code-input-card {
  padding: 24px 18px;
  background: var(--panel);
  border: 1.5px solid var(--surface-edge);
  border-radius: var(--radius-xl);
  text-align: center;
}
.school-code-digits {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin: 18px 0;
}
.school-code-digit {
  width: 44px;
  height: 52px;
  border: 2px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--bg);
  font-size: 22px;
  font-weight: 700;
  text-align: center;
  color: var(--text);
}

/* Progress: CEFR Roadmap */
.cefr-roadmap-card {
  padding: 18px;
  background: var(--panel);
  border: 1.5px solid var(--surface-edge);
  border-radius: var(--radius-xl);
  box-shadow: 0 4px 0 var(--surface-edge);
  margin-bottom: 18px;
  text-align: left;
}
.cefr-track-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
  margin: 24px 8px 12px;
}
.cefr-track-line::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 4px;
  background: var(--line);
  z-index: 1;
}
.cefr-step {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.cefr-dot {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--panel);
  border: 2px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
}
.cefr-step.passed .cefr-dot {
  background: var(--pz-mint);
  border-color: var(--pz-mint-line);
  color: var(--pz-mint-ink);
}
.cefr-step.active .cefr-dot {
  background: var(--pz-yellow);
  border-color: var(--pz-yellow-ink);
  color: var(--pz-yellow-ink);
  box-shadow: 0 0 0 4px var(--pz-yellow-line);
  transform: scale(1.15);
}
.cefr-step-label {
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
}
.cefr-step.active .cefr-step-label {
  color: var(--text);
  font-weight: 800;
}

/* 7-Day Activity Chart */
.weekly-activity-card {
  padding: 16px;
  background: var(--panel);
  border: 1.5px solid var(--surface-edge);
  border-radius: var(--radius-xl);
  box-shadow: 0 4px 0 var(--surface-edge);
  margin-bottom: 18px;
  text-align: left;
}
.weekly-bars {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 8px;
  height: 90px;
  padding: 10px 0 0;
  margin-top: 10px;
}
.weekly-bar-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  height: 100%;
  justify-content: flex-end;
}
.weekly-bar-pillar {
  width: 100%;
  max-width: 28px;
  background: var(--pz-mint);
  border-radius: 6px 6px 0 0;
  transition: height 0.4s var(--ease);
}
.weekly-bar-pillar.active {
  background: var(--sun);
  box-shadow: 0 2px 0 var(--pz-yellow-line);
}
.weekly-day-label {
  font-size: 10px;
  font-weight: 600;
  color: var(--muted);
}
.weekly-bar-col.today .weekly-day-label {
  font-weight: 800;
  color: var(--text);
}



/* Kartu permintaan teman (modal Terima/Tolak). Barisnya sengaja memakai token yang
   sama dengan .social-me supaya modal ini tidak jadi pulau gaya sendiri. */
.social-request-row{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--line)}
.social-request-row:last-child{border-bottom:0}
.social-request-who{flex:1 1 0;min-width:0;display:flex;flex-direction:column}
.social-request-who b{font-size:.95rem;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.social-request-who small{color:var(--muted)}
.social-request-acts{display:flex;align-items:center;gap:8px;flex:none}
.social-request-acts .primary{padding:8px 14px;min-height:40px}

/* ---------- Audit F16 (2026-09-23): Pengaturan di ponsel ----------
   Di 390px baris pengaturan ber-dropdown membagi lebar jadi tiga kolom: deskripsi turun satu
   kata per baris dan dropdown terpotong di tepi modal ("Bahasa Inggris — Ku…"). Di bawah
   480px barisnya ditumpuk: ikon + label di atas, kontrol selebar baris di bawahnya. Baris
   bersakelar (checkbox) tetap satu baris - sakelarnya kecil dan memang di kanan. */
@media (max-width:480px){
  .setting-row:has(> select){grid-template-columns:auto 1fr}
  .setting-row:has(> select)>select{grid-column:1/-1;width:100%;max-width:100%;min-width:0}
  .modal-actions.settings-actions button{min-width:0;height:auto;min-height:44px;white-space:normal;line-height:1.25;padding-inline:14px}
}

/* Audit F28 (2026-09-23): tiga aturan merek KelasKu dipindah dari teacher-shell.css karena
   layar murid juga memakainya; teacher-shell.css (72 KB) kini hanya dimuat di mode guru. */
.kelasku-brand{display:inline-flex;align-items:baseline;gap:8px;white-space:nowrap;line-height:1}
.kelasku-main{font-family:'FZ Instrument Serif',Georgia,serif;font-weight:700;font-size:1.18rem;color:#0F224A;letter-spacing:-0.02em}
.kelasku-tag{font-family:'FZ Plus Jakarta Sans',-apple-system,'Segoe UI',sans-serif;font-size:0.52rem;font-weight:500;color:#5B6B82;letter-spacing:0.02em;text-transform:none}

/* Audit F10 (2026-09-23): pasangan contoh salah/benar di intro materi. Tanda teks (\u2717/\u2713)
   membawa artinya - warna hanya penguat (kontrak non-warna). */
.lesson-contrast{display:grid;gap:6px;margin:10px 0 0}
.lesson-contrast span{display:block;padding:8px 12px;border-radius:var(--radius-sm);font-weight:600;line-height:1.45}
.lesson-contrast .is-wrong{background:var(--bad-soft);color:var(--bad);text-decoration:line-through;text-decoration-thickness:1px}
.lesson-contrast .is-right{background:var(--good-soft);color:var(--good)}

/* ==========================================================================
   m025-367 · LAYAR MASUK (features/auth/fiezel-auth-screen.js)
   Referensi owner: Welcome → Sign in → Sign up, kepala bermotif kontur topografi yang
   berakhir dengan gelombang. Diterjemahkan ke merek FIEZEL: bidang core gelap + kontur
   emas (bukan koral), wordmark + PAW di kepala, tombol utama = .primary aplikasi.
   Kepala MENGECIL dari Selamat datang → Masuk → Daftar, persis seperti referensinya.
   ========================================================================== */
body.fz-auth-open{overflow:hidden}
.fz-auth{position:fixed;inset:0;z-index:2147481950;display:flex;flex-direction:column;background:var(--bg,#FBF7F3);color:var(--text,#2E2724);overflow-y:auto;overscroll-behavior:contain;animation:fzAuthIn .32s cubic-bezier(.2,.8,.2,1) both}
.fz-auth.is-leaving{animation:fzAuthOut .24s ease both}
@keyframes fzAuthIn{from{opacity:0}to{opacity:1}}
@keyframes fzAuthOut{to{opacity:0;transform:translateY(8px)}}
.fz-auth-hero{position:relative;flex:0 0 auto;overflow:hidden;color:var(--fz-on-core,#FDFAF3);
  background:radial-gradient(120% 90% at 30% 0%,var(--fz-core-soft,#2A2126) 0%,var(--fz-core,#1B1418) 70%);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  padding:max(28px,calc(env(safe-area-inset-top) + 16px)) 20px 64px;transition:min-height .35s cubic-bezier(.2,.8,.2,1)}
.fz-auth-hero.is-welcome{min-height:58vh}
.fz-auth-hero.is-masuk{min-height:30vh}
.fz-auth-hero.is-daftar{min-height:22vh}
.fz-auth-topo{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0}
.fz-auth-topo path,
.fz-auth-topo line,
.fz-auth-topo circle{fill:none !important;stroke:rgba(255,199,0,.24) !important;stroke-width:1.1 !important;stroke-linecap:round !important;stroke-linejoin:round !important}
.fz-auth-topo .accent{stroke:rgba(255,215,0,.55) !important;stroke-width:1.4 !important}
.fz-auth-topo .whisper{stroke:rgba(255,199,0,.14) !important;stroke-width:0.95 !important}
.fz-auth-hero::after{content:"";position:absolute;left:50%;top:40%;width:min(80vw,340px);height:220px;transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;background:radial-gradient(closest-side,rgba(255,199,0,.22),rgba(255,199,0,0))}
.fz-auth-wave{position:absolute;left:0;right:0;bottom:-1px;width:100%;height:58px;z-index:2}
.fz-auth-wave path{fill:var(--bg,#FBF7F3)}
.fz-auth-brand{position:relative;z-index:1}
.fz-auth-brand .fiezel-wordmark{width:min(46vw,190px);display:block;margin:0 auto}
.fz-auth-hero.is-daftar .fiezel-wordmark{width:min(34vw,140px)}
.fz-auth-word{margin:0;font-family:var(--fz-heading);font-weight:800;font-size:2rem;letter-spacing:.04em}
.fz-auth-paw{position:relative;z-index:1;width:112px;height:112px;display:block}
.fz-auth .fz-auth-lang{position:absolute;z-index:3;top:max(14px,calc(env(safe-area-inset-top) + 6px));right:14px;display:flex;gap:2px;padding:3px;border-radius:999px;background:rgba(255,255,255,.1);backdrop-filter:blur(4px)}
.fz-auth .fz-auth-lang button{border:0;background:transparent;box-shadow:none;color:rgba(253,250,243,.78);font:inherit;font-size:.78rem;font-weight:700;padding:6px 11px;border-radius:999px;min-height:0;cursor:pointer}
.fz-auth .fz-auth-lang button.is-on{background:var(--fz-on-core,#FDFAF3);color:var(--fz-core,#1B1418)}
.fz-auth-body{position:relative;flex:1 0 auto;width:100%;max-width:460px;margin:0 auto;padding:6px 24px calc(28px + env(safe-area-inset-bottom));display:flex;flex-direction:column}
.fz-auth-title{margin:6px 0 14px;font-family:var(--fz-heading);font-size:2rem;line-height:1.1;letter-spacing:-.02em;color:var(--text,#2E2724)}
.fz-auth-title.is-underlined{display:inline-block;align-self:flex-start;text-decoration:underline;text-decoration-color:var(--accent,#9B3A4A);text-decoration-thickness:3px;text-underline-offset:7px;text-decoration-skip-ink:none}
.fz-auth-lead{margin:0;color:var(--muted,#6E635C);font-size:1rem;line-height:1.55;max-width:34ch}
.fz-auth-next-row{margin-top:auto;padding-top:28px;display:flex;justify-content:flex-end}
.fz-auth .fz-auth-next{display:inline-flex;align-items:center;gap:12px;border:0;background:transparent;box-shadow:none;color:var(--text,#2E2724);font:inherit;font-weight:700;font-size:1rem;padding:6px 4px 6px 10px;cursor:pointer}
.fz-auth-next-dot{width:48px;height:48px;border-radius:50%;display:grid;place-items:center;background:var(--accent,#9B3A4A);color:#fff;box-shadow:0 10px 22px -12px var(--accent,#9B3A4A)}
.fz-auth-i{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.fz-auth-next-dot .fz-auth-i{width:22px;height:22px}
.fz-auth-roles{display:flex;gap:4px;padding:4px;border-radius:14px;background:var(--line,#EFE7DE);margin:0 0 16px}
.fz-auth .fz-auth-role{flex:1;border:0;background:transparent;box-shadow:none;color:var(--muted,#6E635C);font:inherit;font-weight:700;font-size:.92rem;padding:10px;border-radius:10px;cursor:pointer;min-height:0}
.fz-auth .fz-auth-role.is-on{background:var(--panel,#fff);color:var(--text,#2E2724);box-shadow:0 4px 14px -10px rgba(0,0,0,.45)}
.fz-auth-google{min-height:44px;display:flex;justify-content:center;align-items:center;position:relative;width:100%}
.fz-auth-google[hidden]{display:none}
.fz-btn-google-native{width:100%;max-width:360px;height:44px;min-height:44px;border-radius:999px;background:#FFFFFF;border:1.5px solid #E4D9CC;display:flex;align-items:center;justify-content:center;gap:10px;font-family:inherit;font-weight:700;font-size:.92rem;color:#2E2724;cursor:pointer;transition:background .18s,border-color .18s,transform .1s,box-shadow .18s;box-shadow:0 2px 6px rgba(46,39,36,.06);padding:0 16px;user-select:none;-webkit-user-select:none}
.fz-btn-google-native:hover{background:#FAF6F0;border-color:#D3C4B3}
.fz-btn-google-native:active{transform:translateY(1px);box-shadow:0 1px 2px rgba(46,39,36,.06)}
.fz-btn-google-native .fz-google-svg{flex-shrink:0}
.fz-auth-or[hidden]{display:none}
.fz-auth-or{display:flex;align-items:center;gap:10px;margin:14px 0 4px;color:var(--muted,#6E635C);font-size:.8rem}
.fz-auth-or::before,.fz-auth-or::after{content:"";flex:1;height:1px;background:var(--line,#EFE7DE)}
.fz-auth-hint{margin:0 0 6px;color:var(--muted,#6E635C);font-size:.88rem;line-height:1.5}
.fz-auth-form{display:flex;flex-direction:column;gap:14px;margin-top:6px}
.fz-auth-field{display:flex;flex-direction:column;gap:6px}
.fz-auth-label{font-weight:700;font-size:.9rem;color:var(--text,#2E2724)}
.fz-auth-label small{font-weight:600;color:var(--muted,#6E635C)}
.fz-auth-input{display:flex;align-items:center;gap:10px;border-bottom:1.5px solid var(--line,#EFE7DE);padding:4px 0;color:var(--muted,#6E635C);transition:border-color .2s}
.fz-auth-input:focus-within{border-bottom-color:var(--accent,#9B3A4A);color:var(--accent,#9B3A4A)}
/* (0,3,1): harus menang atas `body.fz-lux input[type="text"]` (0,2,2) yang menggambar kotak putih. */
.fz-auth .fz-auth-input input[name]{flex:1;min-width:0;border:0;border-radius:0;background:transparent;box-shadow:none;font:inherit;font-size:1rem;color:var(--text,#2E2724);padding:8px 0;min-height:40px;outline:none}
.fz-auth .fz-auth-eye{border:0;background:transparent;box-shadow:none;color:var(--muted,#6E635C);padding:6px;min-height:0;cursor:pointer;border-radius:8px}
.fz-auth .fz-auth-eye[aria-pressed="true"]{color:var(--accent,#9B3A4A)}
.fz-auth-row{display:flex;justify-content:flex-end;margin-top:-4px}
.fz-auth .fz-auth-link{border:0;background:transparent;box-shadow:none;padding:4px 2px;min-height:0;font:inherit;font-weight:700;font-size:.86rem;color:var(--accent,#9B3A4A);cursor:pointer;text-decoration:none}
.fz-auth-note{margin:6px 0 0;font-size:.84rem;line-height:1.45;color:var(--muted,#6E635C);text-align:center}
.fz-auth-note:empty{display:none}
.fz-auth-note.is-info{text-align:left;background:var(--line,#EFE7DE);border-radius:12px;padding:10px 12px}
.fz-auth-error{margin:0;color:#A1302A;font-size:.86rem;font-weight:600;line-height:1.45}
.fz-auth-error:empty{display:none}
.fz-auth .fz-auth-submit{width:100%;margin-top:6px;padding:15px 20px;font-size:1rem}
.fz-auth-alt{margin:16px 0 0;text-align:center;color:var(--muted,#6E635C);font-size:.9rem}
.fz-auth-alt + .fz-auth-alt{margin-top:4px}
.fz-auth .fz-plain:focus-visible{outline:2px solid var(--accent,#9B3A4A);outline-offset:2px}
/* Penanda fokus kolom: garis bawah menebal (bukan kotak) supaya tetap sejalan dengan bentuk
   kolom bergaris. Selektornya SAMA dengan aturan outline:none di atas, jadi ia menang. */
.fz-auth .fz-auth-input input[name]:focus-visible{box-shadow:inset 0 -2px 0 var(--accent,#9B3A4A)}
@media (max-height:680px){.fz-auth-hero.is-welcome{min-height:48vh}.fz-auth-hero.is-masuk{min-height:24vh}.fz-auth-hero.is-daftar{min-height:18vh}.fz-auth-paw{width:84px;height:84px}}
@media (prefers-reduced-motion:reduce){.fz-auth,.fz-auth.is-leaving{animation:none}.fz-auth-hero{transition:none}}
/* m025-367 · langkah kursus di perkenalan: dua kartu lebar (bendera + nama + isi kursus). */
.fiezel-course-grid{display:grid;grid-template-columns:1fr;gap:10px;margin:14px 0 10px}
/* .fiezel-goal-card menumpuk isinya ke bawah (column) dan mengecilkan semua span ke 13px;
   kartu kursus butuh baris: bendera di kiri, judul + isi di kanan. */
.fiezel-ob .fiezel-course-card{flex-direction:row;align-items:center;justify-content:flex-start;gap:14px;text-align:left;padding:16px 18px}
.fiezel-ob .fiezel-course-card .fiezel-course-flag{flex:none;display:grid;place-items:center;width:52px;height:52px;border-radius:16px;background:var(--fz-soft,#F6EFE7);font-size:30px;line-height:1}
.fiezel-ob .fiezel-course-card .fiezel-course-text{display:flex;flex-direction:column;gap:3px;min-width:0;font-size:inherit}
.fiezel-ob .fiezel-course-card .fiezel-course-text b{font-size:1.05rem}
.fiezel-ob .fiezel-course-card .fiezel-course-text small{font-size:.84rem;font-weight:500;color:var(--fz-ink-muted,#6E635C);line-height:1.4}

/* ==========================================================================
   FIEZEL HOME DASHBOARD — SPORTS / LEAGUES REDESIGN (DARK + RADIANT ELECTRIC YELLOW)
   ========================================================================== */

html, body {
  --fz-sports-bg: #FAF8F5;
  --fz-sports-card-bg: #FFFFFF;
  --fz-sports-card-border: #E2E8F0;
  --fz-sports-yellow: #FFD21E;
  --fz-sports-yellow-hi: #FFE054;
  --fz-sports-yellow-lo: #FFB703;
  --fz-sports-yellow-ink: #2E1800;
  --fz-sports-yellow-glow: rgba(255, 210, 30, 0.4);
  --fz-sports-silver-hi: #FFFFFF;
  --fz-sports-silver-lo: #F1F5F9;
  --fz-sports-dark-hi: #FFFFFF;
  --fz-sports-dark-lo: #F8FAFC;
  --fz-sports-text-muted: #64748B;
}

/* Home Page Canvas & Shell Resets */
html:has(.home-today),
body:has(.home-today) {
  scroll-padding-bottom: calc(76px + env(safe-area-inset-bottom, 12px)) !important;
  background: #FAF8F5 !important;
  color: #0F172A !important;
}

body:has(.home-today) main.app {
  padding: 0 !important;
  margin: 0 auto !important;
  max-width: 100% !important;
  width: 100% !important;
  background: transparent !important;
}

body:has(.home-today) #globalSky,
html.has-home-today #globalSky {
  display: none !important;
}

.home-today {
  background: #FAF8F5 !important;
  color: #0F172A !important;
  min-height: auto !important;
  padding: 10px 10px calc(84px + env(safe-area-inset-bottom, 12px)) 10px !important;
  position: relative !important;
  box-sizing: border-box !important;
  width: 100% !important;
  max-width: 100% !important;
  overflow-x: clip !important;
  overflow-y: visible !important;
  scroll-padding-bottom: calc(80px + env(safe-area-inset-bottom, 12px)) !important;
}

.home-today .today-home-cockpit {
  width: 100% !important;
  max-width: 460px !important;
  margin: 0 auto !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 14px !important;
  box-sizing: border-box !important;
  padding: 0 !important;
}

/* ==========================================================================
   FIEZEL STUDENT DASHBOARD (Warm Obsidian & Educational Learning Cockpit)
   ========================================================================== */

/* Universal topbar is used across all screens including Home; hide duplicate in-page topbar */
.fz-home-topbar,
.fz-sports-topbar,
.today-home-cockpit .fz-home-topbar {
  display: none !important;
}

.fz-home-brand-wrap {
  display: inline-flex !important;
  align-items: center !important;
  cursor: pointer !important;
  outline: none !important;
  transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s ease !important;
  padding: 4px 0 !important;
}
.fz-home-brand-wrap:active {
  transform: scale(0.96) !important;
}
.fz-home-brand-wrap:focus-visible {
  outline: 2px solid var(--accent, #ffd700) !important;
  outline-offset: 2px !important;
}
.fz-home-brand-wrap svg.fiezel-wordmark {
  height: 28px !important;
  width: auto !important;
  max-width: 126px !important;
  display: block !important;
  filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.6)) !important;
}
.fz-home-wordmark-text {
  font-size: 22px !important;
  font-weight: 800 !important;
  letter-spacing: 0.06em !important;
  background: linear-gradient(135deg, #FFFBF3 0%, #FFD94F 100%) !important;
  -webkit-background-clip: text !important;
  -webkit-text-fill-color: transparent !important;
}

.fz-home-actions {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
}

html body:has(.home-today) .fz-home-action-btn,
body.fz-lux:has(.home-today) button.fz-home-action-btn,
body.fz-lang-ja:has(.home-today) button.fz-home-action-btn,
.fz-home-action-btn {
  width: 44px !important;
  height: 44px !important;
  border-radius: 50% !important;
  background: #18181D !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  box-shadow: none !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  color: #8E8E98 !important;
  cursor: pointer !important;
  padding: 0 !important;
  transition: all 0.2s ease !important;
  position: relative !important;
}
.fz-home-action-btn:hover {
  background: #242430 !important;
  color: #FFFFFF !important;
  border-color: rgba(255, 255, 255, 0.18) !important;
}
.fz-home-action-btn:active {
  transform: scale(0.94) !important;
}
.fz-home-action-btn svg,
.fz-home-action-btn i {
  width: 18px !important;
  height: 18px !important;
}

html body:has(.home-today) .fz-home-course-btn,
body.fz-lux:has(.home-today) button.fz-home-course-btn,
body.fz-lang-ja:has(.home-today) button.fz-home-course-btn,
.fz-home-course-btn {
  width: 44px !important;
  height: 44px !important;
  border-radius: 50% !important;
  background: #18181D !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  box-shadow: none !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 0 !important;
  color: #FFFFFF !important;
  cursor: pointer !important;
  transition: all 0.2s ease !important;
}
.fz-home-course-btn:hover {
  background: #242430 !important;
  border-color: var(--fz-sports-yellow, #FFD94F) !important;
}
.fz-home-course-btn .course-switch-flag {
  font-size: 18px !important;
  line-height: 1 !important;
}

/* Warm Greeting & Encouragement Header */
.fz-welcome-header {
  padding: 6px 4px 4px 4px !important;
}
.fz-welcome-greeting {
  font-size: 26px !important;
  font-weight: 800 !important;
  color: #FFFFFF !important;
  letter-spacing: -0.02em !important;
  line-height: 1.25 !important;
  margin-bottom: 6px !important;
}
.fz-welcome-name {
  background: linear-gradient(135deg, #FFE082 0%, #FFD94F 100%) !important;
  -webkit-background-clip: text !important;
  -webkit-text-fill-color: transparent !important;
}
.fz-welcome-quote {
  font-size: 13.5px !important;
  font-weight: 500 !important;
  color: #A3A3B0 !important;
  line-height: 1.5 !important;
  margin: 0 !important;
}

/* Learning Categories Pills Bar */
.fz-learning-pills-bar {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  overflow-x: auto !important;
  padding: 4px 0 10px 0 !important;
  scrollbar-width: none !important;
  -webkit-overflow-scrolling: touch !important;
}
.fz-learning-pills-bar::-webkit-scrollbar {
  display: none !important;
}

html body:has(.home-today) .fz-learning-pill,
body.fz-lux:has(.home-today) button.fz-learning-pill,
body.fz-lang-ja:has(.home-today) button.fz-learning-pill,
.fz-learning-pill {
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 9999px !important;
  padding: 9px 18px !important;
  font-size: 13.5px !important;
  font-weight: 600 !important;
  white-space: nowrap !important;
  cursor: pointer !important;
  box-shadow: none !important;
  transition: all 0.2s cubic-bezier(0.2, 0.8, 0.2, 1) !important;
  background: #18181E !important;
  color: #7A7A84 !important;
  flex-shrink: 0 !important;
}
.fz-learning-pill:hover {
  background: #22222C !important;
  color: #FFFFFF !important;
}
html body:has(.home-today) .fz-learning-pill.is-active,
body.fz-lux:has(.home-today) button.fz-learning-pill.is-active,
body.fz-lang-ja:has(.home-today) button.fz-learning-pill.is-active,
.fz-learning-pill.is-active {
  background: rgba(255, 215, 0, 0.15) !important;
  color: #FFE082 !important;
  font-weight: 700 !important;
  border-color: rgba(255, 215, 0, 0.45) !important;
  box-shadow: 0 2px 14px rgba(255, 215, 0, 0.15) !important;
}

/* Educational Cards */
.fz-edu-card {
  border-radius: 26px !important;
  overflow: hidden !important;
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.6) !important;
  border: 1.5px solid rgba(255, 255, 255, 0.1) !important;
  transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.22s ease !important;
  position: relative !important;
  background: #14141A !important;
  padding: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 0 !important;
}
.fz-edu-card:hover {
  transform: translateY(-2px) !important;
  box-shadow: 0 20px 44px rgba(0, 0, 0, 0.7) !important;
}
.fz-edu-card + .fz-edu-card {
  margin-top: 14px !important;
}

/* Card Themes */
.fz-card-primary {
  background: linear-gradient(180deg, #1D1B22 0%, #121116 100%) !important;
  border-color: rgba(255, 199, 0, 0.3) !important;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55), 0 0 28px rgba(255, 199, 0, 0.08) !important;
}
.fz-card-neutral {
  background: linear-gradient(180deg, #181920 0%, #111216 100%) !important;
  border-color: rgba(52, 211, 153, 0.22) !important;
}
.fz-card-obsidian {
  background: linear-gradient(180deg, #191B24 0%, #111218 100%) !important;
  border-color: rgba(96, 165, 250, 0.22) !important;
}

.fz-edu-card-content {
  padding: 22px 20px 20px 20px !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 12px !important;
  cursor: pointer !important;
}

.fz-edu-badge-row {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  gap: 8px !important;
}

.fz-edu-tag {
  display: inline-flex !important;
  align-items: center !important;
  gap: 6px !important;
  padding: 5px 12px !important;
  border-radius: 9999px !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  letter-spacing: 0.05em !important;
  text-transform: uppercase !important;
}
.fz-edu-tag.is-primary {
  background: rgba(255, 199, 0, 0.14) !important;
  color: #FFD43B !important;
  border: 1px solid rgba(255, 199, 0, 0.35) !important;
}
.fz-edu-tag.is-emerald {
  background: rgba(16, 185, 129, 0.14) !important;
  color: #34D399 !important;
  border: 1px solid rgba(16, 185, 129, 0.35) !important;
}
.fz-edu-tag.is-gold {
  background: rgba(59, 130, 246, 0.14) !important;
  color: #60A5FA !important;
  border: 1px solid rgba(59, 130, 246, 0.35) !important;
}

.fz-edu-level-badge,
.fz-edu-sub-badge {
  font-size: 11px !important;
  font-weight: 700 !important;
  color: #9E9EA8 !important;
  background: rgba(255, 255, 255, 0.06) !important;
  padding: 4px 10px !important;
  border-radius: 9999px !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
}

.fz-edu-title {
  font-size: 19px !important;
  font-weight: 800 !important;
  color: #FFFFFF !important;
  letter-spacing: -0.01em !important;
  line-height: 1.25 !important;
  margin: 0 !important;
}

.fz-edu-desc {
  font-size: 13px !important;
  font-weight: 450 !important;
  color: #9E9EA8 !important;
  line-height: 1.48 !important;
  margin: 0 !important;
}

.fz-edu-stats-row {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  flex-wrap: wrap !important;
  margin-top: 2px !important;
}

.fz-edu-stat-item {
  display: inline-flex !important;
  align-items: center !important;
  gap: 5px !important;
  background: rgba(255, 255, 255, 0.05) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  padding: 6px 12px !important;
  border-radius: 10px !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  color: #C5C5D0 !important;
}
.fz-edu-stat-item.is-reward {
  background: rgba(255, 199, 0, 0.1) !important;
  border-color: rgba(255, 199, 0, 0.28) !important;
  color: #FFE082 !important;
  font-weight: 700 !important;
}

.fz-edu-primary-btn {
  width: 100% !important;
  padding: 13px 18px !important;
  background: linear-gradient(135deg, #FFE048 0%, #FFB800 100%) !important;
  color: #0F0E11 !important;
  font-size: 14px !important;
  font-weight: 800 !important;
  border-radius: 14px !important;
  border: none !important;
  cursor: pointer !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  box-shadow: 0 4px 16px rgba(255, 184, 0, 0.25) !important;
  transition: transform 0.15s ease, box-shadow 0.15s ease !important;
  margin-top: 4px !important;
}
.fz-edu-primary-btn:active {
  transform: scale(0.98) !important;
}

.fz-edu-secondary-btn {
  width: 100% !important;
  padding: 12px 18px !important;
  background: rgba(255, 255, 255, 0.06) !important;
  color: #E2E8F0 !important;
  font-size: 13.5px !important;
  font-weight: 700 !important;
  border-radius: 14px !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
  cursor: pointer !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  transition: all 0.15s ease !important;
  margin-top: 4px !important;
}
.fz-edu-secondary-btn:hover {
  background: rgba(255, 255, 255, 0.1) !important;
  color: #FFFFFF !important;
  border-color: rgba(255, 255, 255, 0.2) !important;
}
.fz-edu-secondary-btn:active {
  transform: scale(0.98) !important;
}

/* Force .today-card to adhere to edge-to-edge sculpted card */
html body #app .today-card.fz-edu-card,
html body #app section.today-card.fz-edu-card {
  padding: 0 !important;
  border: 1.5px solid rgba(255, 199, 0, 0.3) !important;
  background: linear-gradient(180deg, #1D1B22 0%, #121116 100%) !important;
  max-width: 100% !important;
  width: 100% !important;
  margin: 0 !important;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55), 0 0 28px rgba(255, 199, 0, 0.08) !important;
  border-radius: 26px !important;
  overflow: hidden !important;
}

/* Collapsible Details Drawer */
.fz-card-drawer {
  background: #101015 !important;
  border-top: 1px solid rgba(255, 255, 255, 0.08) !important;
  padding: 0 !important;
}

.fz-drawer-toggle {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  padding: 12px 18px !important;
  font-size: 11.5px !important;
  font-weight: 800 !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
  color: #A3A3B0 !important;
  cursor: pointer !important;
  user-select: none !important;
  list-style: none !important;
  background: rgba(255, 255, 255, 0.03) !important;
  transition: all 0.2s ease !important;
}
.fz-drawer-toggle::-webkit-details-marker {
  display: none !important;
}
.fz-drawer-toggle:hover {
  background: rgba(255, 255, 255, 0.06) !important;
  color: #FFFFFF !important;
}
.fz-drawer-arrow {
  font-size: 14px !important;
  transition: transform 0.2s ease !important;
  color: #FFE082 !important;
}
details[open] .fz-drawer-arrow {
  transform: rotate(180deg) !important;
}

.fz-drawer-inner {
  padding: 16px 18px 20px 18px !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 12px !important;
  background: #101015 !important;
}

.fz-drawer-inner .today-head {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  margin-bottom: 2px !important;
}

.fz-drawer-inner .today-title {
  font-size: 20px !important;
  font-weight: 800 !important;
  color: #FFFFFF !important;
  margin: 0 !important;
  line-height: 1.2 !important;
}

.fz-drawer-inner .today-lead {
  font-size: 13px !important;
  color: #94A3B8 !important;
  margin: 0 !important;
}

.fz-drawer-inner .today-isi-head {
  font-size: 12px !important;
  font-weight: 800 !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
  color: #A3A3B0 !important;
  margin: 4px 0 0 0 !important;
}

.fz-drawer-inner .today-blocks {
  list-style: none !important;
  padding: 0 !important;
  margin: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
}

.fz-drawer-inner .today-blocks li {
  background: #181820 !important;
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  border-radius: 14px !important;
  padding: 10px 14px !important;
  font-size: 13px !important;
  color: #E2E8F0 !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 2px !important;
}

.fz-drawer-inner .today-blocks li b {
  font-weight: 700 !important;
  color: #FFFFFF !important;
}

.fz-drawer-inner .today-blocks li span {
  font-size: 11px !important;
  color: #94A3B8 !important;
}

.fz-drawer-inner .today-rhythm-bar {
  background: #181820 !important;
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  border-radius: 12px !important;
  padding: 10px 14px !important;
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  font-size: 12px !important;
  color: #E2E8F0 !important;
}

.fz-drawer-inner .rhythm-track {
  flex: 1 !important;
  height: 8px !important;
  background: rgba(255, 255, 255, 0.1) !important;
  border-radius: 9999px !important;
  overflow: hidden !important;
}

.fz-drawer-inner .rhythm-fill {
  height: 100% !important;
  background: linear-gradient(90deg, #FFB800, #FFE048) !important;
  border-radius: 9999px !important;
}

.fz-sports-cta {
  width: 100% !important;
  margin-top: 10px !important;
  background: linear-gradient(180deg, #FFE054 0%, #FFB703 100%) !important;
  color: #2E1800 !important;
  border-radius: 18px !important;
  padding: 15px 20px !important;
  font-weight: 800 !important;
  font-size: 14.5px !important;
  border: 2px solid #D97706 !important;
  box-shadow: 0 5px 0 #D97706, 0 12px 24px rgba(255, 183, 3, 0.35) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  cursor: pointer !important;
  transition: transform 0.15s ease !important;
}
.fz-sports-cta:active {
  transform: scale(0.98) !important;
}

/* Quick Chips & Flow in Sports Dark theme */
.home-today .quick-practice-section {
  background: #14141A !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 24px !important;
  padding: 20px !important;
  margin-top: 10px !important;
}

.home-today .quick-practice-title {
  color: #FFFFFF !important;
  font-size: 18px !important;
  font-weight: 800 !important;
}

.home-today .quick-practice-hint {
  color: #8E8E98 !important;
}

.home-today .quick-chips-grid {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: 10px !important;
  margin-top: 14px !important;
}

.home-today .quick-chip {
  background: #1C1C24 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 16px !important;
  box-shadow: none !important;
  padding: 12px 10px !important;
  color: #FFFFFF !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 4px !important;
}
.home-today .quick-chip .chip-label {
  color: #FFFFFF !important;
  font-weight: 800 !important;
  font-size: 12px !important;
}
.home-today .quick-chip .chip-sub {
  color: #8E8E98 !important;
  font-size: 10px !important;
}

/* Totally eliminate PAW avatar & speech bubble cockpit */
.home-today .paw-hero-cockpit,
.today-home-cockpit > .paw-hero-cockpit,
.paw-hero-cockpit,
.paw-speech-bubble,
.paw-hero-avatar,
.paw-bubble-title,
.paw-bubble-text,
.paw-mascot,
.lesson-mascot,
.fz-paw-slot {
  display: none !important;
  visibility: hidden !important;
  pointer-events: none !important;
  opacity: 0 !important;
  height: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
}

/* ==========================================================================
   ANCHORED LUXURY TACTILE CLAY FLOATING BOTTOM NAVIGATION BAR (6 TABS)
   ========================================================================== */
html body nav.bottomnav,
html body .bottomnav,
html body.fz-lux nav.bottomnav,
html body.fz-lux .bottomnav,
html body.fz-lang-ja nav.bottomnav,
html body.fz-lang-ja .bottomnav,
html.fiezel-ui-v6 nav.bottomnav,
html.fiezel-ui-v6 .bottomnav,
body:has(.home-today) nav.bottomnav,
body:has(.home-today) .bottomnav,
.home-today ~ .bottomnav {
  position: fixed !important;
  top: auto !important;
  bottom: 0 !important;
  left: 0 !important;
  right: 0 !important;
  width: 100% !important;
  max-width: 100% !important;
  transform: none !important;
  margin: 0 !important;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom, 0px)) !important;
  background: linear-gradient(180deg, #FFFDF0 0%, #FEF08A 100%) !important;
  border-radius: 0 !important;
  border: none !important;
  border-top: 1.5px solid rgba(255, 255, 255, 0.95) !important;
  box-shadow: inset 0 1.5px 2px #FFFFFF, inset 0 -2px 3px rgba(217, 119, 6, 0.12), 0 -4px 20px rgba(180, 83, 9, 0.10) !important;
  height: calc(62px + env(safe-area-inset-bottom, 0px)) !important;
  min-height: calc(62px + env(safe-area-inset-bottom, 0px)) !important;
  max-height: calc(72px + env(safe-area-inset-bottom, 0px)) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: space-around !important;
  gap: 2px !important;
  z-index: 1000 !important;
  box-sizing: border-box !important;
  overflow: visible !important;
}

/* Sliding Liquid Pill Indicator */
.nav-active-pill,
#navActivePill {
  position: absolute !important;
  top: 6px !important;
  height: 50px !important;
  border-radius: 9999px !important;
  background: linear-gradient(180deg, #FFFFFF 0%, #FEF08A 65%, #FDE047 100%) !important;
  border: 1px solid rgba(255, 255, 255, 0.95) !important;
  box-shadow: inset 0 2px 3px #FFFFFF, inset 0 -1.5px 2px rgba(217, 119, 6, 0.3), 0 4px 12px rgba(217, 119, 6, 0.22) !important;
  pointer-events: none !important;
  z-index: 1 !important;
  box-sizing: border-box !important;
  transition: transform 0.32s cubic-bezier(0.25, 1, 0.5, 1), width 0.28s cubic-bezier(0.25, 1, 0.5, 1), opacity 0.2s ease !important;
  will-change: transform, width !important;
  left: 0;
  width: 0;
  opacity: 0;
}


/* Ensure body and app container have sufficient bottom padding so content is never covered by bottomnav */
main.app,
.view-container,
#app {
  padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px)) !important;
}

/* Hide bottomnav when listening modal or detail sheet is active or in lesson mode */
body:has(#listeningPanelModal.open) .bottomnav,
body:has(.listening-modal.open) .bottomnav,
body:has(#jlptDetailSheet.open) .bottomnav,
body.fz-lesson-mode nav.bottomnav,
body.fz-lesson-mode .bottomnav {
  display: none !important;
}

html body.fz-lang-ja nav.bottomnav .nav,
html body.fz-lang-ja .bottomnav .nav,
html body nav.bottomnav .nav,
html body .bottomnav .nav,
html body.fz-lux nav.bottomnav .nav,
html body:has(.home-today) .bottomnav .nav {
  border-radius: 9999px !important;
  flex: 1 1 0 !important;
  min-width: 0 !important;
  width: auto !important;
  height: 100% !important;
  min-height: 48px !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 2px !important;
  color: #78350F !important;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 4px 1px !important;
  transition: color 0.18s ease, transform 0.12s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
  cursor: pointer !important;
  overflow: visible !important;
  box-sizing: border-box !important;
  transform: none !important;
}

/* Kill older pseudo-elements like yellow oval pill ::after */
html body nav.bottomnav .nav::after,
html body .bottomnav .nav::after,
nav.bottomnav .nav::after,
.bottomnav .nav::after {
  display: none !important;
}

html body.fz-lang-ja nav.bottomnav .nav span,
html body.fz-lang-ja .bottomnav .nav span,
html body nav.bottomnav .nav span,
html body .bottomnav .nav span,
nav.bottomnav .nav span,
.bottomnav .nav span {
  display: block !important;
  font-size: 10px !important;
  font-weight: 700 !important;
  letter-spacing: -0.01em !important;
  color: #78350F !important;
  opacity: 0.75 !important;
  line-height: 1.2 !important;
  text-align: center !important;
  white-space: nowrap !important;
  margin-top: 1px !important;
  overflow: visible !important;
  transition: color 0.18s ease, font-weight 0.18s ease, opacity 0.18s ease !important;
}

html body.fz-lang-ja nav.bottomnav .nav .fz-i,
html body.fz-lang-ja .bottomnav .nav .fz-i,
html body nav.bottomnav .nav .fz-i,
html body .bottomnav .nav .fz-i,
nav.bottomnav .nav .fz-i,
.bottomnav .nav .fz-i {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  width: 22px !important;
  height: 22px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  --fz-i-fill: transparent !important;
  --fz-i-line: #78350F !important;
  margin-top: 0 !important;
  opacity: 0.70 !important;
  filter: none !important;
  transition: filter 0.2s ease, opacity 0.18s ease !important;
}

html body.fz-lang-ja nav.bottomnav .nav svg,
html body.fz-lang-ja .bottomnav .nav svg,
html body nav.bottomnav .nav svg,
html body .bottomnav .nav svg,
html body .bottomnav .nav i,
nav.bottomnav .nav svg,
nav.bottomnav .nav i,
.bottomnav .nav svg,
.bottomnav .nav i {
  width: 20px !important;
  height: 20px !important;
  stroke: #78350F !important;
  stroke-width: 1.8 !important;
  fill: none !important;
  opacity: 0.70 !important;
}

html body.fz-lang-ja nav.bottomnav .nav.active,
html body.fz-lang-ja .bottomnav .nav.active,
html body nav.bottomnav .nav.active,
html body .bottomnav .nav.active,
html body.fz-lux nav.bottomnav .nav.active,
html body:has(.home-today) .bottomnav .nav.active {
  background: transparent !important;
  color: #78350F !important;
  border-radius: 9999px !important;
  border: none !important;
  box-shadow: none !important;
  transform: none !important;
}

/* Fallback before pill synchronizes */
.bottomnav:not(.pill-synced) .nav.active {
  background: linear-gradient(180deg, #FFFFFF 0%, #FEF08A 65%, #FDE047 100%) !important;
  border: 1px solid rgba(255, 255, 255, 0.95) !important;
  box-shadow: inset 0 2px 3px #FFFFFF, inset 0 -1.5px 2px rgba(217, 119, 6, 0.3), 0 4px 12px rgba(217, 119, 6, 0.22) !important;
}

html body.fz-lang-ja nav.bottomnav .nav.active span,
html body.fz-lang-ja .bottomnav .nav.active span,
html body nav.bottomnav .nav.active span,
html body .bottomnav .nav.active span,
nav.bottomnav .nav.active span,
.bottomnav .nav.active span {
  color: #78350F !important;
  opacity: 1 !important;
  font-weight: 800 !important;
  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8) !important;
}

html body.fz-lang-ja nav.bottomnav .nav.active .fz-i,
html body.fz-lang-ja .bottomnav .nav.active .fz-i,
html body nav.bottomnav .nav.active .fz-i,
html body .bottomnav .nav.active .fz-i,
nav.bottomnav .nav.active .fz-i,
.bottomnav .nav.active .fz-i {
  --fz-i-fill: #FEF08A !important;
  --fz-i-line: #92400E !important;
  opacity: 1 !important;
  filter: drop-shadow(0 1px 2px rgba(255, 255, 255, 0.8)) !important;
}

html body.fz-lang-ja nav.bottomnav .nav.active svg,
html body.fz-lang-ja .bottomnav .nav.active svg,
html body nav.bottomnav .nav.active svg,
html body .bottomnav .nav.active svg,
nav.bottomnav .nav.active svg,
.bottomnav .nav.active svg {
  stroke: #92400E !important;
  stroke-width: 2.2 !important;
  opacity: 1 !important;
  filter: drop-shadow(0 1px 2px rgba(255, 255, 255, 0.8)) !important;
}

/* KelasKu emerald active */
html body nav.bottomnav .nav[data-view="classroom"].active,
html body .bottomnav .nav[data-view="classroom"].active,
nav.bottomnav .nav[data-view="classroom"].active,
.bottomnav .nav[data-view="classroom"].active {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  color: #065F46 !important;
}

html body nav.bottomnav .nav[data-view="classroom"].active span,
html body .bottomnav .nav[data-view="classroom"].active span,
nav.bottomnav .nav[data-view="classroom"].active span,
.bottomnav .nav[data-view="classroom"].active span {
  color: #065F46 !important;
  opacity: 1 !important;
  font-weight: 800 !important;
  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.8) !important;
}

html body nav.bottomnav .nav[data-view="classroom"].active .fz-i,
html body .bottomnav .nav[data-view="classroom"].active .fz-i,
nav.bottomnav .nav[data-view="classroom"].active .fz-i,
.bottomnav .nav[data-view="classroom"].active .fz-i {
  --fz-i-fill: #A7F3D0 !important;
  --fz-i-line: #047857 !important;
  opacity: 1 !important;
  filter: drop-shadow(0 1px 2px rgba(255, 255, 255, 0.8)) !important;
}

html body nav.bottomnav .nav[data-view="classroom"].active svg,
html body .bottomnav .nav[data-view="classroom"].active svg,
nav.bottomnav .nav[data-view="classroom"].active svg,
.bottomnav .nav[data-view="classroom"].active svg {
  stroke: #047857 !important;
  stroke-width: 2.2 !important;
  opacity: 1 !important;
  filter: drop-shadow(0 1px 2px rgba(255, 255, 255, 0.8)) !important;
}

/* Tactile press feedback on touch */
html body nav.bottomnav .nav:active,
html body .bottomnav .nav:active,
html body nav.bottomnav .nav.active:active,
html body .bottomnav .nav.active:active,
html body.fz-lux nav.bottomnav .nav:active,
html body.fz-lux .bottomnav .nav:active,
html body.fz-lang-ja nav.bottomnav .nav:active,
html body.fz-lang-ja .bottomnav .nav:active,
html body:has(.home-today) .bottomnav .nav:active,
html body:has(.home-today) .bottomnav .nav.active:active {
  transform: scale(0.92) !important;
  transition: transform 0.08s cubic-bezier(0.2, 0, 0, 1) !important;
}

html body nav.bottomnav .nav.active .fz-i,
html body .bottomnav .nav.active .fz-i {
  animation: none !important;
}

/* ==========================================================================
   UNIFIED DAYLIGHT TACTILE CLAY DESIGN SYSTEM — HARMONIZED ACROSS ALL PANELS
   (HOME, LATIHAN, KELASKU, PROGRES, PROFIL / ONLINE & SUBVIEWS)
   ========================================================================== */

/* 1. Global Viewport & Ambient Background Canvas */
html,
body,
body.scene-day,
body.scene-night,
body.fz-lux,
body.fz-lang-ja,
html.fiezel-ui-v6 body {
  background-color: #FAF8F5 !important;
  color: #0F172A !important;
}

#globalSky {
  display: none !important;
}

main.app {
  background: transparent !important;
  color: #0F172A !important;
}

#app {
  background: transparent !important;
  color: #0F172A !important;
}

/* Page containers */
section.fade,
.classroom-page,
.home-page {
  background: #FAF8F5 !important;
  color: #0F172A !important;
  min-height: auto !important;
  padding-bottom: calc(80px + env(safe-area-inset-bottom, 12px)) !important;
}

/* Bottom Nav Scrim */
.nav-scrim {
  background: linear-gradient(180deg, transparent 0%, rgba(250, 248, 245, 0.85) 60%, #FAF8F5 100%) !important;
}

/* 2. Universal Tactile Clay Daylight Topbar */
header.topbar {
  background: var(--bgDay, #FDFAF3) !important;
  backdrop-filter: blur(20px) !important;
  -webkit-backdrop-filter: blur(20px) !important;
  border: none !important;
  border-bottom: none !important;
  box-shadow: none !important;
  position: sticky !important;
  top: 0 !important;
  z-index: 100 !important;
  min-height: 52px !important;
  padding: 8px 16px !important;
}

.topbar-brand-fiezel,
#topBrandWrap {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}

#topBrandWrap[style*="display: none"],
#topBrandWrap[style*="display:none"] {
  display: none !important;
}

.topbar-brand-fiezel .fiezel-wordmark-text,
#topBrandWrap .fiezel-wordmark-text {
  font-family: 'Plus Jakarta Sans', sans-serif !important;
  font-size: 23px !important;
  font-weight: 800 !important;
  color: #0F172A !important;
  letter-spacing: -0.025em !important;
  line-height: 1 !important;
}

.topbar-brand-fiezel .fiezel-brand-tag,
#topBrandWrap .fiezel-brand-tag {
  font-family: 'Plus Jakarta Sans', sans-serif !important;
  font-size: 10px !important;
  font-weight: 800 !important;
  color: #92400E !important;
  background: #FEF3C7 !important;
  border: 1px solid #FDE68A !important;
  padding: 2px 7px !important;
  border-radius: 6px !important;
  text-transform: uppercase !important;
  letter-spacing: 0.04em !important;
  line-height: 1.2 !important;
}

.topbar .brand-button {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

.topbar .brand svg.fiezel-wordmark {
  filter: none !important;
}

.topbar .brand svg.fiezel-wordmark text,
.topbar .brand svg.fiezel-wordmark path,
.topbar .brand svg.fiezel-wordmark rect,
.topbar .brand svg.fiezel-wordmark g {
  --wordmark-ink-hi: #0F172A !important;
  --wordmark-ink-lo: #1E293B !important;
  --wordmark-accent-hi: #FFD21E !important;
  --wordmark-accent-lo: #D97706 !important;
}

#fzTopMark #fztIv stop:first-child { stop-color: #0F172A !important; }
#fzTopMark #fztIv stop:last-child { stop-color: #1E293B !important; }
#fzTopMark #fztGo stop:first-child { stop-color: #FFD21E !important; }
#fzTopMark #fztGo stop:last-child { stop-color: #D97706 !important; }

.topbar .icon-button {
  background: #FFFFFF !important;
  border: 2px solid #E2E8F0 !important;
  color: #0F172A !important;
  box-shadow: 0 3px 0 #CBD5E1 !important;
  transition: all 0.2s ease !important;
}

.topbar .icon-button:hover {
  background: #F8FAFC !important;
  color: #0F172A !important;
  border-color: #CBD5E1 !important;
}

.topbar .btn-course-selector,
.topbar #fzCourseSwitchBtn {
  background: #FFFFFF !important;
  border: 2px solid #E2E8F0 !important;
  border-radius: 9999px !important;
  padding: 6px 14px !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-family: 'Plus Jakarta Sans', sans-serif !important;
  font-size: 13px !important;
  font-weight: 800 !important;
  color: #0F172A !important;
  box-shadow: 0 3px 0 #CBD5E1 !important;
  cursor: pointer !important;
  white-space: nowrap !important;
  height: 36px !important;
  min-height: 36px !important;
  width: auto !important;
  min-width: auto !important;
  flex-shrink: 0 !important;
  line-height: 1 !important;
  transition: all 0.12s ease !important;
  overflow: visible !important;
}

#fzCourseSwitchBtn[style*="display: none"],
#fzCourseSwitchBtn[style*="display:none"] {
  display: none !important;
}

#topGamifyCluster[style*="display: none"],
#topGamifyCluster[style*="display:none"] {
  display: none !important;
}

.topbar .btn-course-selector:hover,
.topbar #fzCourseSwitchBtn:hover {
  transform: translateY(-1px) !important;
  box-shadow: 0 4px 0 #CBD5E1 !important;
  border-color: #CBD5E1 !important;
}

.topbar .btn-course-selector:active,
.topbar #fzCourseSwitchBtn:active {
  transform: translateY(2px) !important;
  box-shadow: 0 1px 0 #CBD5E1 !important;
}

.topbar .btn-course-selector .course-switch-flag,
.topbar #fzCourseSwitchBtn .course-switch-flag {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: auto !important;
  height: auto !important;
  flex-shrink: 0 !important;
}

.topbar .btn-course-selector .course-switch-flag svg,
.topbar #fzCourseSwitchBtn .course-switch-flag svg {
  width: 18px !important;
  height: 13px !important;
  border-radius: 2px !important;
  display: block !important;
  object-fit: cover !important;
  box-shadow: 0 0 1px rgba(0, 0, 0, 0.4) !important;
}

.topbar .btn-course-selector .course-switch-label,
.topbar #fzCourseSwitchBtn .course-switch-label {
  display: inline-block !important;
  font-family: 'Plus Jakarta Sans', sans-serif !important;
  font-size: 13px !important;
  font-weight: 800 !important;
  color: #0F172A !important;
  white-space: nowrap !important;
  line-height: 1 !important;
}

.topbar .course-switch-label {
  color: #0F172A !important;
  font-weight: 800 !important;
}

/* 3. Section Headers across all Views (Latihan, Progress, Profile, etc.) */
.section-head {
  padding: 18px 4px 14px 4px !important;
}

.section-head h1 {
  color: #0F172A !important;
  font-weight: 800 !important;
  letter-spacing: -0.02em !important;
  font-size: 1.85rem !important;
  line-height: 1.15 !important;
}

.section-head p {
  color: #64748B !important;
  font-size: 0.95rem !important;
  margin-top: 4px !important;
}

/* Level Control Button in Section Head */
.active-level-control {
  background: #FFFFFF !important;
  border: 2px solid #E2E8F0 !important;
  color: #0F172A !important;
  border-radius: 14px !important;
  box-shadow: 0 4px 0 #CBD5E1 !important;
  transition: all 0.2s ease !important;
}

.active-level-control:hover {
  background: #F8FAFC !important;
  border-color: #CBD5E1 !important;
}

.active-level-control span {
  color: #64748B !important;
}

.active-level-control strong {
  color: #D97706 !important;
  font-weight: 800 !important;
}

.active-level-control small {
  background: #F1F5F9 !important;
  color: #0F172A !important;
  border-radius: 6px !important;
}

/* 4. Universal Cards across App */
html body:has(.home-today) .card,
body.fz-lux .card,
.social-card,
.progress-card {
  background: #FFFFFF !important;
  border: 2px solid #E2E8F0 !important;
  border-radius: 20px !important;
  color: #0F172A !important;
  box-shadow: 0 6px 0 #CBD5E1, 0 14px 28px rgba(15, 23, 42, 0.05) !important;
  padding: 20px !important;
}

.card h2,
.card h3,
.card strong,
.card b {
  color: #0F172A !important;
}

.card p.muted,
.card small,
.card .muted {
  color: #64748B !important;
}

.card hr {
  border: 0 !important;
  border-top: 1px solid rgba(255, 255, 255, 0.08) !important;
  margin: 12px 0 !important;
}

/* 5. LATIHAN (Practice View): Luxury 3D Cards */
html body #app .learning-launcher .launch-card,
html body #app .launch-card,
.learning-launcher .launch-card,
.launch-card {
  background: linear-gradient(145deg, #181824 0%, #121218 100%) !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  border-radius: 18px !important;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
  padding: 16px 14px !important;
  color: #FFFFFF !important;
  transition: all 0.24s cubic-bezier(0.16, 1, 0.3, 1) !important;
}

html body #app .learning-launcher .launch-card:hover,
.learning-launcher .launch-card:hover {
  transform: translateY(-3px) scale(1.01) !important;
  border-color: rgba(255, 224, 46, 0.4) !important;
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.6), 0 0 16px rgba(255, 224, 46, 0.15) !important;
}

html body #app .learning-launcher .launch-card b,
.learning-launcher .launch-card b {
  color: #FFFFFF !important;
  font-weight: 800 !important;
  font-size: 15px !important;
  letter-spacing: -0.01em !important;
}

html body #app .learning-launcher .launch-card small,
.learning-launcher .launch-card small {
  color: #8E8E98 !important;
  font-size: 11.5px !important;
  line-height: 1.35 !important;
}

html body #app .learning-launcher .launch-card .launch-icon,
.learning-launcher .launch-card .launch-icon {
  background: rgba(255, 255, 255, 0.06) !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  color: #FFE02E !important;
  border-radius: 14px !important;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25) !important;
}

html body #app .learning-launcher .launch-card .launch-icon.fz-launch-3d,
.learning-launcher .launch-card .launch-icon.fz-launch-3d {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.4)) !important;
}

html body #app .learning-launcher .launch-card i[data-lucide="arrow-up-right"],
html body #app .learning-launcher .launch-card svg,
.learning-launcher .launch-card i[data-lucide="arrow-up-right"] {
  color: #FFE02E !important;
}

/* Learner Flow & AI Booster Cards */
.learner-flow-launcher .learn-launch {
  background: linear-gradient(145deg, #231E16 0%, #151410 100%) !important;
  border: 1px solid rgba(255, 224, 46, 0.3) !important;
  color: #FFFFFF !important;
  border-radius: 20px !important;
}

.ai-booster-card,
.continue-learning-card {
  background: #14141B !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  border-radius: 20px !important;
  color: #FFFFFF !important;
}

/* 6. KELASKU (Classroom Hub / #fzClassHub) */
#fzClassHub,
.classroom-page {
  color: #FFFFFF !important;
}

.ch {
  --ch-bg: #14141B !important;
  --ch-soft: #1B1B24 !important;
  --ch-line: rgba(255, 255, 255, 0.08) !important;
  --ch-text: #FFFFFF !important;
  --ch-muted: #8E8E98 !important;
  --ch-accent: #FFE02E !important;
  --ch-ink: #FFFFFF !important;
  color: #FFFFFF !important;
}

.ch-student {
  padding-bottom: 0 !important;
}

.ch-head h1,
.ch-h2 {
  color: #FFFFFF !important;
  font-weight: 800 !important;
}

.ch-kicker {
  color: #FFE02E !important;
}

.ch-sub,
.ch-muted {
  color: #8E8E98 !important;
}

.ch-tabs {
  background: #121218 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 9999px !important;
  padding: 4px !important;
}

.ch-tab {
  color: #8E8E98 !important;
  border-radius: 9999px !important;
}

.ch-tab.is-active {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
  box-shadow: 0 4px 14px rgba(255, 224, 46, 0.35) !important;
}

.ch-card,
.ch-link-card,
.ch-kpi {
  background: #14141B !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 20px !important;
  color: #FFFFFF !important;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important;
}

.ch-card h2,
.ch-card h3 {
  color: #FFFFFF !important;
}

.ch-card.ch-empty {
  background: #14141B !important;
  border: 1px dashed rgba(255, 255, 255, 0.15) !important;
}

.ch-btn.is-primary {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
  border: none !important;
  box-shadow: 0 4px 16px rgba(255, 224, 46, 0.35) !important;
}

.ch-btn.is-ghost {
  background: #181822 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  color: #FFFFFF !important;
}

.ch-form input {
  background: #181822 !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
  color: #FFFFFF !important;
  border-radius: 9999px !important;
}

/* 7. PROGRES (Progress View): Tabs, Stats & Charts */
.progress-tabs {
  background: #121218 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 9999px !important;
  padding: 4px !important;
  display: flex !important;
  gap: 6px !important;
  overflow-x: auto !important;
  scrollbar-width: none !important;
  -webkit-overflow-scrolling: touch !important;
  margin-bottom: 16px !important;
}

.progress-tabs::-webkit-scrollbar {
  display: none !important;
}

.progress-tab {
  background: transparent !important;
  color: #8E8E98 !important;
  border: none !important;
  box-shadow: none !important;
  border-radius: 9999px !important;
  padding: 9px 18px !important;
  font-size: 0.88rem !important;
  font-weight: 700 !important;
  cursor: pointer !important;
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1) !important;
  white-space: nowrap !important;
  flex: 0 0 auto !important;
}

.progress-tab:not(.active) {
  box-shadow: none !important;
}

.progress-tab:hover:not(.active) {
  color: #FFFFFF !important;
  background: rgba(255, 255, 255, 0.06) !important;
  box-shadow: none !important;
}

.progress-tab.active {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
  box-shadow: 0 4px 14px rgba(255, 224, 46, 0.35) !important;
}

.progress-grid {
  display: flex !important;
  flex-direction: column !important;
  gap: 14px !important;
}

.prasasti-fold summary {
  cursor: pointer !important;
  user-select: none !important;
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
}

.prasasti-fold summary h3 {
  margin: 0 !important;
}

.prasasti-fold summary i[data-lucide="chevron-down"] {
  transition: transform 0.25s ease !important;
}

.prasasti-fold[open] summary i[data-lucide="chevron-down"] {
  transform: rotate(180deg) !important;
}

.stats {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  display: grid !important;
  grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)) !important;
  gap: 10px !important;
}

.stats.progress-stats {
  grid-template-columns: repeat(2, 1fr) !important;
}

@media (min-width: 520px) {
  .stats.progress-stats {
    grid-template-columns: repeat(4, 1fr) !important;
  }
}

.stats > div {
  background: #181824 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 16px !important;
  padding: 14px 12px !important;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35) !important;
  display: flex !important;
  flex-direction: column !important;
  justify-content: center !important;
  text-align: center !important;
}

.stats.progress-stats > div.stat-gem-span {
  grid-column: span 2 !important;
  flex-direction: row !important;
  align-items: center !important;
  justify-content: space-between !important;
  padding: 11px 18px !important;
  background: linear-gradient(135deg, rgba(255, 215, 0, 0.12), rgba(255, 199, 0, 0.04)) !important;
  border: 1px solid rgba(255, 215, 0, 0.3) !important;
}

@media (min-width: 520px) {
  .stats.progress-stats > div.stat-gem-span {
    grid-column: span 4 !important;
  }
}

.stats.progress-stats > div.stat-gem-span small {
  margin: 0 !important;
  color: #FFD700 !important;
  font-weight: 700 !important;
  letter-spacing: 0.06em !important;
  font-size: 12px !important;
}

.stats.progress-stats > div.stat-gem-span strong {
  margin: 0 !important;
  color: #FFFFFF !important;
  font-size: 1.25rem !important;
}

.stats small {
  color: #8E8E98 !important;
  font-size: 11px !important;
  text-transform: uppercase !important;
  letter-spacing: 0.04em !important;
  line-height: 1.25 !important;
}

.stats strong {
  color: #FFFFFF !important;
  font-size: 1.15rem !important;
  line-height: 1.2 !important;
  font-weight: 800 !important;
  margin-top: 6px !important;
  word-break: normal !important;
}

.map-row {
  background: #181822 !important;
  border: 1px solid rgba(255, 255, 255, 0.06) !important;
  border-radius: 14px !important;
  padding: 10px 14px !important;
  margin-bottom: 8px !important;
  color: #FFFFFF !important;
}

.map-row .mn {
  color: #FFFFFF !important;
  font-weight: 700 !important;
}

.map-row .mp {
  color: #FFE02E !important;
  font-weight: 800 !important;
}

.map-row .me {
  color: #8E8E98 !important;
}

.bar,
.meter .bar {
  background: rgba(255, 255, 255, 0.08) !important;
  border-radius: 9999px !important;
}

.bar i,
.meter .bar i {
  background: linear-gradient(90deg, #FFD42D 0%, #FFE848 100%) !important;
  box-shadow: 0 0 10px rgba(255, 224, 46, 0.45) !important;
  border-radius: 9999px !important;
}

.diag-grid div {
  background: #181822 !important;
  border: 1px solid rgba(255, 255, 255, 0.07) !important;
  border-radius: 12px !important;
  padding: 10px 12px !important;
  color: #FFFFFF !important;
}

.diag-grid b {
  color: #8E8E98 !important;
  font-size: 11px !important;
  text-transform: uppercase !important;
}

.timeline-row {
  border-bottom: 1px solid rgba(255, 255, 255, 0.07) !important;
  padding: 8px 0 !important;
  color: #E4E4E7 !important;
}

/* 8. PROFIL / ONLINE VIEW */
#onlineRoot,
.social-card {
  color: #FFFFFF !important;
}

.arena-launch {
  background: linear-gradient(145deg, #1F1B2E 0%, #13121E 100%) !important;
  border: 1px solid rgba(167, 139, 250, 0.3) !important;
  border-radius: 18px !important;
}

.arena-launch b {
  color: #FFFFFF !important;
}

.arena-launch small {
  color: #A78BFA !important;
}

.arena-launch .launch-icon {
  background: rgba(124, 58, 237, 0.25) !important;
  color: #A78BFA !important;
}

/* 9. MODALS & SETTINGS PANELS */
body.fz-lux .modal-panel,
body:has(.home-today) .modal-panel,
body.fz-lux #modalPanel,
body:has(.home-today) #modalPanel {
  background: #14141C !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 24px !important;
  color: #FFFFFF !important;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.85) !important;
}

body.fz-lux .modal-panel h2,
body:has(.home-today) .modal-panel h2,
body.fz-lux #modalPanel h2,
body:has(.home-today) #modalPanel h2,
.modal-panel h2,
.modal-panel h3 {
  color: #FFFFFF !important;
}

.modal-panel p,
#modalPanel p,
.modal-panel .muted,
#modalPanel .muted {
  color: #94A3B8 !important;
}

.modal-panel .text-button,
#modalPanel .text-button,
.modal-panel .notif-readall,
.modal-panel [data-testid="notif-close"] {
  color: #FFDE43 !important;
  font-weight: 700 !important;
}

.modal-panel .text-button:hover,
#modalPanel .text-button:hover {
  color: #FFFFFF !important;
  background: rgba(255, 255, 255, 0.08) !important;
}

/* Recovery kontras: tombol "Tolak" pada kartu permintaan teman (di atas kartu putih #F8FAFC ganti teks kuning jadi slate 500/600 #64748B, kontras > 5:1 AA) */
.modal-panel #connectRequestsList .text-button,
#modalPanel #connectRequestsList .text-button,
.modal-panel .social-request-row .text-button,
#modalPanel .social-request-row .text-button,
.social-request-acts .text-button,
#connectRequestsList .text-button {
  color: #64748B !important;
  background: transparent !important;
}

.modal-panel #connectRequestsList .text-button:hover,
#modalPanel #connectRequestsList .text-button:hover,
.modal-panel .social-request-row .text-button:hover,
#modalPanel .social-request-row .text-button:hover,
.social-request-acts .text-button:hover,
#connectRequestsList .text-button:hover {
  color: #334155 !important;
  background: #E2E8F0 !important;
}

.modal-panel .notif-item.is-teacher,
.modal-panel .notif-item.is-teacher .notif-body b,
.modal-panel .notif-item.is-teacher b {
  color: #2D2214 !important;
}

.modal-panel .notif-item.is-teacher .notif-body small,
.modal-panel .notif-item.is-teacher small {
  color: #5C4825 !important;
}

.modal-panel .notif-item.is-social,
.modal-panel .notif-item.is-social .notif-body b,
.modal-panel .notif-item.is-social b {
  color: #0A3825 !important;
}

.modal-panel .notif-item.is-social .notif-body small,
.modal-panel .notif-item.is-social small {
  color: #1C583E !important;
}

.modal-panel .notif-item.is-invite,
.modal-panel .notif-item.is-invite .notif-body b,
.modal-panel .notif-item.is-invite b {
  color: #4A1226 !important;
}

.modal-panel .notif-item.is-invite .notif-body small,
.modal-panel .notif-item.is-invite small {
  color: #782944 !important;
}

.modal-panel .notif-item .notif-cta {
  background: #14141C !important;
  color: #FFDE43 !important;
  border: 1px solid rgba(255, 222, 67, 0.3) !important;
}

.modal-panel .notif-item .notif-cta:hover {
  background: #222230 !important;
  color: #FFFFFF !important;
}

.settings-fold {
  background: #181822 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 16px !important;
  margin-bottom: 8px !important;
}

.settings-fold summary {
  color: #FFFFFF !important;
  font-weight: 700 !important;
}

/* Universal Primary Button */
button.primary,
.primary {
  background: linear-gradient(180deg, #FFDE43 0%, #FFB800 100%) !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
  border: none !important;
  box-shadow: 0 4px 18px rgba(255, 184, 0, 0.4) !important;
}

button.primary:hover,
.primary:hover {
  transform: translateY(-1px) !important;
  box-shadow: 0 6px 22px rgba(255, 184, 0, 0.5) !important;
}

/* 10. JLPT LISTENING MODAL & DETAIL SHEET
   Dikelola oleh features/speaking-listening/jlpt-listening.css (Tactile Travertine) */

/* ==========================================================================
   11. GRAMMAR VIEW & LESSON PATH HIGH-CONTRAST (DARK LUXURY ATHLETIC)
   ========================================================================== */
.path-step .path-label,
body.fz-lux .path-label,
body .path-label {
  background: #14141B !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35) !important;
  color: #FFFFFF !important;
  border-radius: 18px !important;
}

.path-step .path-label b,
body.fz-lux .path-label b,
body .path-label b {
  color: #FFFFFF !important;
  font-weight: 700 !important;
}

.path-step .path-label > span,
body.fz-lux .path-label > span,
body .path-label > span {
  color: #94A3B8 !important;
}

.path-step .path-label .lesson-lock-note,
.lesson-lock-note {
  color: #CBD5E1 !important;
}

.path-step.is-locked .path-label,
body.fz-lux .path-step.is-locked .path-label,
body .path-step.is-locked .path-label {
  background: #111116 !important;
  border-color: rgba(255, 255, 255, 0.05) !important;
  opacity: 0.85 !important;
}

.path-step.is-locked .path-label b,
body.fz-lux .path-step.is-locked .path-label b {
  color: #94A3B8 !important;
}

.path-step.is-locked .path-label > span,
body.fz-lux .path-step.is-locked .path-label > span {
  color: #64748B !important;
}

.path-step.is-current .path-label,
body.fz-lux .path-step.is-current .path-label,
body .path-step.is-current .path-label {
  border: 2px solid #FFE02E !important;
  box-shadow: 0 0 20px rgba(255, 224, 46, 0.25), 0 4px 16px rgba(0, 0, 0, 0.4) !important;
}

.path-step.is-current .path-label b {
  color: #FFFFFF !important;
}

.path-node,
body.fz-lux .path-node {
  background: #181824 !important;
  border: 2px solid rgba(255, 255, 255, 0.12) !important;
  color: #FFFFFF !important;
}

.path-ring > b,
.path-ring > i,
.path-ring {
  color: #FFFFFF !important;
}

.path-ring-gold {
  background: #FFE02E !important;
  color: #0A0A0E !important;
}

/* Grammar Lesson Detail Page */
.grammar-lesson-page {
  background: #FAF8F5 !important;
  color: #0F172A !important;
}

.grammar-lesson-card {
  background: #FFFFFF !important;
  border: 2px solid #E2E8F0 !important;
  border-radius: 20px !important;
  box-shadow: 0 6px 0 #CBD5E1 !important;
  color: #0F172A !important;
}

.lesson-bubble {
  background: #1C1C28 !important;
  border: 1px solid rgba(255, 224, 46, 0.3) !important;
  border-radius: 18px !important;
  color: #FFFFFF !important;
}

.lesson-bubble b {
  color: #FFE02E !important;
  font-weight: 800 !important;
}

.lesson-bubble::before {
  border-right-color: rgba(255, 224, 46, 0.3) !important;
}

.lesson-bubble::after {
  border-right-color: #1C1C28 !important;
}

.lesson-stage p {
  color: #E2E8F0 !important;
}

html body:has(.home-today) .lesson-example,
body.fz-lux .lesson-example {
  background: #181824 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 16px !important;
  color: #FFFFFF !important;
}

.lesson-example > span {
  color: #F59E0B !important;
  font-weight: 800 !important;
}

.lesson-example h3 {
  color: #FFFFFF !important;
  font-weight: 700 !important;
}

.lesson-example p {
  color: #CBD5E1 !important;
}

.lesson-example p strong {
  color: #FFE02E !important;
}

.lesson-contrast .is-wrong {
  background: rgba(239, 68, 68, 0.18) !important;
  color: #FCA5A5 !important;
  border: 1px solid rgba(239, 68, 68, 0.3) !important;
}

.lesson-contrast .is-right {
  background: rgba(16, 185, 129, 0.18) !important;
  color: #6EE7B7 !important;
  border: 1px solid rgba(16, 185, 129, 0.3) !important;
}

.feedback-memory-box,
.feedback .memory-tip {
  display: block !important;
  background: rgba(245, 158, 11, 0.12) !important;
  border: 1px solid rgba(245, 158, 11, 0.35) !important;
  border-radius: 14px !important;
  padding: 12px 16px !important;
  margin: 14px 0 !important;
  text-align: left !important;
}

.feedback-memory-header {
  display: flex !important;
  align-items: center !important;
  gap: 7px !important;
  margin-bottom: 8px !important;
}

.feedback-memory-header svg,
.feedback-memory-header i,
.feedback .memory-tip i[data-lucide="lightbulb"],
.feedback .memory-tip svg {
  width: 17px !important;
  height: 17px !important;
  color: #FBBF24 !important;
  flex-shrink: 0 !important;
}

html body .card .feedback-memory-kicker,
html body .card div > span.feedback-memory-kicker,
html body .feedback-memory-kicker,
.feedback-memory-kicker {
  font-size: 0.72rem !important;
  font-weight: 800 !important;
  letter-spacing: 0.08em !important;
  text-transform: uppercase !important;
  color: #FBBF24 !important;
  line-height: 1 !important;
}

html body .card .feedback-memory-content,
html body .card .feedback-memory-content span,
html body .card div > span.feedback-memory-content,
html body .card div > .feedback-memory-content span,
html body .feedback-memory-content,
html body .feedback-memory-content span,
.feedback-memory-content,
.feedback-memory-content span,
.feedback .memory-tip span {
  font-size: 0.92rem !important;
  line-height: 1.55 !important;
  color: #F8FAFC !important;
  display: block !important;
}

html body .card .feedback-memory-content strong,
html body .feedback-memory-content strong,
.feedback-memory-content strong,
.feedback .memory-tip strong {
  color: #FEF08A !important;
  font-weight: 700 !important;
}

.feedback-memory-content .memory-bullet,
.feedback .memory-tip .memory-bullet {
  display: block !important;
  margin: 4px 0 !important;
  color: #F8FAFC !important;
}

html body #feedback p,
html body .feedback p {
  color: #F8FAFC !important;
}

[data-theme="light"] .card-light .feedback-memory-box,
[data-theme="light"] .card-light .feedback .memory-tip,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback-memory-box,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback .memory-tip {
  background: #FEF3C7 !important;
  border-color: #FDE68A !important;
}

[data-theme="light"] .card-light .feedback-memory-kicker,
[data-theme="light"] .card-light .feedback-memory-header svg,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback-memory-kicker,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback-memory-header svg {
  color: #78350F !important;
}

[data-theme="light"] .card-light .feedback-memory-content,
[data-theme="light"] .card-light .feedback-memory-content span,
[data-theme="light"] .card-light .feedback .memory-tip span,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback-memory-content,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback-memory-content span,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback .memory-tip span {
  color: #1E293B !important;
}

[data-theme="light"] .card-light .feedback-memory-content strong,
[data-theme="light"] .card-light .feedback .memory-tip strong,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback-memory-content strong,
body:not(.theme-dark):not(.fz-lux) .card-light .feedback .memory-tip strong {
  color: #78350F !important;
}

.skill-page-topbar button,
.skill-back-btn {
  background: #181824 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  color: #FFFFFF !important;
}

.skill-help-dot {
  background: #181824 !important;
  color: #FFE02E !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
}

/* ==========================================================================
   12. QUIZ & PRACTICE SCREENS (DAYLIGHT TACTILE CLAY)
   ========================================================================== */
.quiz-shell,
.stage-shell {
  background: #FAF8F5 !important;
  color: #0F172A !important;
}

body.fz-lux .quiz-topbar,
body:has(.home-today) .quiz-topbar,
.stage-header {
  background: #FFFFFF !important;
  border-bottom: 2px solid #E2E8F0 !important;
  color: #0F172A !important;
  margin-bottom: 16px !important;
}

.quiz-topbar span,
.quiz-progress span,
.stage-counter {
  color: #0F172A !important;
  font-weight: 800 !important;
}

.quiz-topbar em,
.quiz-progress em {
  color: #64748B !important;
}

.quiz-exit {
  background: #181824 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  color: #FFFFFF !important;
}

.quiz-exit-label {
  color: #FFFFFF !important;
}

.passage.passage-reading {
  background: #14141B !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  border-radius: 18px !important;
  color: #E2E8F0 !important;
}

.passage.passage-reading .eyebrow {
  color: #FFE02E !important;
  font-weight: 800 !important;
}

.passage.passage-reading h3 {
  color: #FFFFFF !important;
  font-weight: 800 !important;
}

.passage.passage-reading p {
  color: #CBD5E1 !important;
}

.quiz-bubble,
.speech-bubble {
  background: #181824 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 18px !important;
  color: #FFFFFF !important;
}

.quiz-bubble h2.question,
.quiz-bubble p,
.quiz-bubble span {
  color: #FFFFFF !important;
}

.quiz-bubble .question-instruction,
.quiz-stage .question-instruction,
.speech-bubble .question-instruction,
.quiz-shell .question-instruction,
.card .question-instruction,
.question .question-instruction,
.question-instruction {
  display: inline-block !important;
  font-size: 0.75rem !important; /* 12px kicker/eyebrow distinct from 18px+ question stem */
  font-weight: 700 !important;
  color: #94A3B8 !important; /* Secondary text color (Slate 400), WCAG AAA 7.3:1 contrast on #181824 */
  letter-spacing: 0.07em !important;
  text-transform: uppercase !important;
  margin-bottom: 10px !important;
  line-height: 1.35 !important;
  padding: 3px 8px !important;
  border-radius: 6px !important;
  background: rgba(148, 163, 184, 0.12) !important;
}

/* Light mode for question-instruction only on true light surfaces */
body:not(.theme-dark):not(.fz-lux) .card-light .question-instruction,
body:not(.theme-dark):not(.fz-lux) .card:not(.quiz-bubble):not(.quiz-stage) .question-instruction {
  color: #475569 !important; /* Slate 600, high contrast on light backgrounds */
  background: rgba(100, 116, 139, 0.1) !important;
}

/* Inside dark quiz bubble/stage, instruction is ALWAYS light Slate 300 */
.quiz-bubble .question-instruction,
.quiz-stage .question-instruction,
.speech-bubble .question-instruction {
  color: #CBD5E1 !important;
  background: rgba(255, 255, 255, 0.1) !important;
}

.quiz-bubble .question-main,
.quiz-stage .question-main,
.speech-bubble .question-main,
.quiz-shell .question-main,
.card .question-main,
.question .question-main,
.question-main {
  display: block !important;
  font-size: clamp(1.2rem, 1.15rem + 1.2vw, 1.55rem) !important;
  font-weight: 700 !important;
  color: #FFFFFF !important;
  line-height: 1.45 !important;
  letter-spacing: -0.01em !important;
}

/* Light mode for question-main only on true light surfaces */
body:not(.theme-dark):not(.fz-lux) .card-light .question-main,
body:not(.theme-dark):not(.fz-lux) .card:not(.quiz-bubble):not(.quiz-stage) .question-main {
  color: #0F172A !important;
}

/* Inside dark quiz bubble/stage, main question is ALWAYS pure White */
.quiz-bubble .question-main,
.quiz-stage .question-main,
.speech-bubble .question-main {
  color: #FFFFFF !important;
}

/* Target Word / Error Token Highlight in Sentence Correction & Stem */
.target-word,
.question-main .target-word,
.question .target-word,
.quiz-bubble .target-word,
.quiz-bubble .question-main .target-word,
.quiz-stage .target-word,
mark.target-word,
.stem-target-word,
.syntax-target,
.syntax-error {
  display: inline-block !important;
  background: rgba(245, 158, 11, 0.28) !important;
  color: #FEF3C7 !important;
  font-style: italic !important;
  text-decoration: underline !important;
  text-decoration-color: #FBBF24 !important;
  text-decoration-thickness: 2.5px !important;
  text-underline-offset: 4px !important;
  border-bottom: 2px solid #F59E0B !important;
  border-radius: 4px !important;
  padding: 1px 6px !important;
  font-weight: 700 !important;
}

body:not(.theme-dark):not(.fz-lux) .card-light .target-word,
body:not(.theme-dark):not(.fz-lux) .card:not(.quiz-bubble):not(.quiz-stage) .target-word {
  color: #92400E !important; /* Amber 800, high contrast on light */
  background: rgba(245, 158, 11, 0.18) !important;
  text-decoration-color: #D97706 !important;
  border-bottom: 2px solid #D97706 !important;
}

.quiz-bubble .target-word,
.quiz-stage .target-word,
.speech-bubble .target-word {
  color: #FEF3C7 !important;
  background: rgba(245, 158, 11, 0.32) !important;
  text-decoration-color: #FBBF24 !important;
  border-bottom-color: #F59E0B !important;
}

.stage-furigana, .furigana {
  color: #F87171 !important;
}

.stage-kanji, .kanji-lead {
  color: #FFFFFF !important;
}

.stage-romaji, .romaji {
  color: #CBD5E1 !important;
}

/* Quiz Option Buttons */
.quiz-shell button.option,
.stage-options button.option,
button.option {
  background: #181824 !important;
  border: 1.5px solid rgba(255, 255, 255, 0.1) !important;
  border-radius: 16px !important;
  color: #FFFFFF !important;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25) !important;
}

button.option:hover {
  background: #222232 !important;
  border-color: #FFE02E !important;
}

button.option.is-selected {
  background: #222232 !important;
  border-color: #FFE02E !important;
}

button.option.is-correct,
button.option.correct {
  background: rgba(16, 185, 129, 0.22) !important;
  border-color: #10B981 !important;
  color: #FFFFFF !important;
}

button.option.is-wrong,
button.option.wrong {
  background: rgba(239, 68, 68, 0.22) !important;
  border-color: #EF4444 !important;
  color: #FFFFFF !important;
}

button.option .badge {
  background: #252536 !important;
  color: #FFFFFF !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
}

button.option.is-correct .badge {
  background: #10B981 !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
}

button.option.is-wrong .badge {
  background: #EF4444 !important;
  color: #FFFFFF !important;
}

/* Feedback Bottom Sheet / Card */
html body:has(.home-today) .feedback,
body.fz-lux .feedback,
.feedback-card {
  background: #14141C !important;
  border-top: 1px solid rgba(255, 255, 255, 0.15) !important;
  color: #FFFFFF !important;
  box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.6) !important;
}

.feedback h3,
.feedback strong,
.feedback p,
.feedback span {
  color: #FFFFFF !important;
}

.feedback.is-correct,
.feedback-card.is-correct {
  background: #0E241B !important;
  border-color: #10B981 !important;
}

.feedback.is-correct h3,
.feedback.is-correct p,
.feedback.is-correct strong,
.feedback.is-correct span {
  color: #ECFDF5 !important;
}

.feedback.is-wrong,
.feedback-card.is-wrong {
  background: #281216 !important;
  border-color: #EF4444 !important;
}

.feedback.is-wrong h3,
.feedback.is-wrong p,
.feedback.is-wrong strong,
.feedback.is-wrong span {
  color: #FEF2F2 !important;
}

/* ==========================================================================
   13. VOCAB & FLASHCARD HIGH-CONTRAST (Warm Cream Edition)
   ========================================================================== */
.flashcard-stage,
.flashcard-topbar {
  background: #FFFDF8 !important;
  border-bottom: 1.5px solid #EDE4D3 !important;
  color: #1E1B18 !important;
}

.flashcard-topbar span,
.flashcard-topbar button,
.flashcard-counter {
  color: #1E1B18 !important;
  font-weight: 800 !important;
}

.flashcard-card,
.vocab-card {
  background: #FFFDF8 !important;
  border: 1.5px solid #EDE4D3 !important;
  border-radius: 20px !important;
  color: #1E1B18 !important;
  box-shadow: 0 10px 28px -6px rgba(135, 105, 65, 0.10) !important;
}

.vocab-card .part-of-speech,
.flashcard-pos {
  background: #F5EFEB !important;
  border: 1px solid #E5D9CE !important;
  color: #6B5E54 !important;
  border-radius: 9999px !important;
}

.vocab-card .part-of-speech span,
.flashcard-pos span {
  color: #2D241E !important;
  font-weight: 700 !important;
}

.flashcard-hint,
.vocab-note,
.flashcard-note {
  color: #8E7B6C !important;
  font-weight: 600 !important;
}

/* ==========================================================================
   14. PROGRESS, PRASASTI & CALENDAR HIGH-CONTRAST
   ========================================================================== */
.fz2-week-pill {
  background: #1E1E2A !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  color: #FFE02E !important;
  font-weight: 700 !important;
}

.fz2-week-grid span,
.calendar-grid span,
.weekdays span,
.day-label {
  color: #CBD5E1 !important;
  font-weight: 600 !important;
}

.day-box,
.fz2-day-box {
  background: #181824 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
  color: #FFFFFF !important;
}

.day-box.is-active,
.fz2-day-box.is-active {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
}

.prasasti-badge,
.prasasti-badge.is-locked {
  background: #14141B !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  border-radius: 16px !important;
  color: #FFFFFF !important;
}

.prasasti-badge b,
.prasasti-badge.is-locked b {
  color: #FFFFFF !important;
  font-weight: 700 !important;
}

.prasasti-badge p,
.prasasti-badge.is-locked p,
.prasasti-badge small {
  color: #94A3B8 !important;
}

.prasasti-badge.is-unlocked {
  border-color: rgba(255, 224, 46, 0.4) !important;
  box-shadow: 0 0 16px rgba(255, 224, 46, 0.15) !important;
}

.prasasti-badge.is-unlocked b {
  color: #FFE02E !important;
}

/* ==========================================================================
   15. KELASKU / CLASSROOM HUB HIGH-CONTRAST
   ========================================================================== */
.ch-tab {
  background: #181822 !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  color: #CBD5E1 !important;
}

.ch-tab.is-active {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
}

.ch-card p,
.ch-card small,
.ch-muted {
  color: #A1A1AA !important;
}

.ch-form input {
  background: #181822 !important;
  border: 1px solid rgba(255, 255, 255, 0.15) !important;
  color: #FFFFFF !important;
}

/* ==========================================================================
   16. JLPT LISTENING MODAL & DETAIL SHEET HIGH-CONTRAST
   ========================================================================== */
.jlpt-opt-btn {
  background: #1A1A26 !important;
  border: 1px solid rgba(255, 255, 255, 0.09) !important;
  color: #FFFFFF !important;
}

.jlpt-opt-btn:hover {
  background: #242436 !important;
  border-color: rgba(255, 224, 46, 0.4) !important;
}

.jlpt-opt-btn .jlpt-opt-ja {
  color: #FFFFFF !important;
  font-weight: 700 !important;
}

.jlpt-opt-btn .jlpt-opt-id {
  color: #CBD5E1 !important;
}

.jlpt-opt-btn .jlpt-opt-badge {
  background: #252536 !important;
  color: #FFFFFF !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
}

.jlpt-opt-btn.correct {
  background: rgba(16, 185, 129, 0.22) !important;
  border-color: #10B981 !important;
}

.jlpt-opt-btn.correct .jlpt-opt-badge {
  background: #10B981 !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
}

.jlpt-opt-btn.correct .jlpt-opt-ja {
  color: #FFFFFF !important;
}

.jlpt-opt-btn.correct .jlpt-opt-id {
  color: #A7F3D0 !important;
}

.jlpt-opt-btn.wrong {
  background: rgba(239, 68, 68, 0.22) !important;
  border-color: #EF4444 !important;
}

.jlpt-opt-btn.wrong .jlpt-opt-badge {
  background: #EF4444 !important;
  color: #FFFFFF !important;
}

.jlpt-opt-btn.wrong .jlpt-opt-ja {
  color: #FFFFFF !important;
}

.jlpt-opt-btn.wrong .jlpt-opt-id {
  color: #FECACA !important;
}

.jlpt-tab-chip {
  background: #1E1E2A !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  color: #CBD5E1 !important;
}

.jlpt-tab-chip.active {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
}

.jlpt-tab-chip.active span {
  color: #0A0A0E !important;
}

.jlpt-turn-bubble {
  background: #1A1A26 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  color: #FFFFFF !important;
}

.jlpt-bubble-ja {
  color: #FFFFFF !important;
}

.jlpt-bubble-ro {
  color: #CBD5E1 !important;
}

.jlpt-bubble-id {
  color: #94A3B8 !important;
}

/* JLPT speaker chip styles are governed by jlpt-listening.css personas */

.jlpt-sheet-subtitle {
  color: #CBD5E1 !important;
}

.jlpt-vocab-card-item,
.jlpt-vocab-item {
  background: #1A1A26 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  color: #FFFFFF !important;
}

.jlpt-vocab-ja {
  color: #FFFFFF !important;
  font-weight: 700 !important;
}

.jlpt-vocab-ro {
  color: #FFE02E !important;
}

.jlpt-vocab-meaning,
.jlpt-vocab-id {
  color: #CBD5E1 !important;
}

.jlpt-explain-article {
  background: #1A1A26 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  color: #FFFFFF !important;
}

.jlpt-explain-article h3,
.jlpt-explain-article-title {
  color: #FFE02E !important;
}

.jlpt-explain-article p,
.jlpt-explain-article span {
  color: #CBD5E1 !important;
}

.jlpt-download-box {
  background: #181824 !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  color: #CBD5E1 !important;
}

.jlpt-download-box a {
  color: #FFE02E !important;
}

.jlpt-key-card {
  background: #0E241B !important;
  border: 1px solid #10B981 !important;
  color: #FFFFFF !important;
}

.jlpt-key-card span,
.jlpt-key-card div {
  color: #ECFDF5 !important;
}

.jlpt-lvl-btn {
  background: #181822 !important;
  color: #CBD5E1 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
}

.jlpt-lvl-btn.active {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
  border-color: #FFE02E !important;
}

.jlpt-primary-play-btn {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
  border: none !important;
  box-shadow: 0 4px 14px rgba(255, 224, 46, 0.35) !important;
}

.jlpt-jees-chip {
  background: #252536 !important;
  color: #CBD5E1 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
}

.jlpt-sheet-trigger-btn {
  background: #181824 !important;
  color: #CBD5E1 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
}

.jlpt-sheet-trigger-btn:hover {
  background: #222232 !important;
  color: #FFFFFF !important;
}

.jlpt-nav-pill {
  background: #181824 !important;
  color: #FFFFFF !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
}

body .fz2-day span,
.fz2-day span {
  color: #CBD5E1 !important;
  font-weight: 700 !important;
}

body .fz2-day i,
.fz2-day i {
  background: #181824 !important;
  border: 1px solid rgba(255, 255, 255, 0.1) !important;
}

body .fz2-day i.is-on,
.fz2-day i.is-on {
  background: #FFE02E !important;
  border-color: #FFE02E !important;
  box-shadow: 0 0 12px rgba(255, 224, 46, 0.4) !important;
}

body .fz2-day i.is-today,
.fz2-day i.is-today {
  border: 2px dashed #FFE02E !important;
}

.continue-learning-card b {
  color: #FFFFFF !important;
  font-weight: 800 !important;
}

.continue-learning-card small {
  color: #CBD5E1 !important;
}

.continue-learning-card .continue-card-btn {
  background: #FFE02E !important;
  color: #0A0A0E !important;
  font-weight: 800 !important;
}

.learning-launcher h3,
.learning-launcher h2 {
  color: #FFFFFF !important;
}

/* ==========================================================================
   17. ABSOLUTE TOTAL ERADICATION OF PAW CHAT BUBBLES & CARTOON MASCOTS
   ========================================================================== */
.fz-coach-bubble,
.fz-coach-peek,
.fz-coach-sheet,
button.fz-coach-bubble,
.has-mascot.fz-coach-bubble,
.coach-strip,
.paw-hero-cockpit,
.paw-speech-bubble,
.paw-hero-avatar,
.paw-bubble-title,
.paw-mascot,
.lesson-mascot,
.fz-paw-slot {
  display: none !important;
  visibility: hidden !important;
  pointer-events: none !important;
  opacity: 0 !important;
}

/* ==========================================================================
   ONBOARDING REFINEMENTS: FLAG SVG, TOPO TEXTURE, ANIMATED PAW MASCOT
   ========================================================================== */
/* Bendera SVG: Tajam, proporsional, dan konsisten di semua platform */
.fiezel-flag-svg {
  display: inline-block;
  vertical-align: middle;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
  border: 1px solid rgba(0, 0, 0, 0.08);
  overflow: hidden;
  flex-shrink: 0;
}
.fiezel-goal-card .fiezel-language-flag {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: 0 !important;
  line-height: 1;
}
.fiezel-goal-card .fiezel-language-flag .fiezel-flag-svg {
  width: 38px;
  height: 26px;
}
.fiezel-course-flag {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: 0 !important;
  line-height: 1;
}
.fiezel-course-flag .fiezel-flag-svg {
  width: 38px;
  height: 26px;
}

/* Tekstur topografi emas pada header onboarding (.fiezel-ob-reveal) seperti Auth Login */
.fiezel-ob-reveal {
  background: radial-gradient(120% 90% at 30% 0%, var(--fz-core-soft, #2A2126) 0%, var(--fz-core, #1B1418) 70%) !important;
}
.fiezel-ob-reveal .fz-auth-topo {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  pointer-events: none !important;
  z-index: 0 !important;
}
.fiezel-ob-reveal .fz-auth-topo path,
.fiezel-ob-reveal .fz-auth-topo line,
.fiezel-ob-reveal .fz-auth-topo circle {
  fill: none !important;
  stroke: rgba(255, 199, 0, 0.24) !important;
  stroke-width: 1.1 !important;
  stroke-linecap: round !important;
  stroke-linejoin: round !important;
}
.fiezel-ob-reveal .fz-auth-topo .accent {
  stroke: rgba(255, 215, 0, 0.55) !important;
  stroke-width: 1.4 !important;
}
.fiezel-ob-reveal .fz-auth-topo .whisper {
  stroke: rgba(255, 199, 0, 0.14) !important;
  stroke-width: 0.95 !important;
}
.fiezel-ob-reveal .fiezel-wordmark,
.fiezel-ob-reveal .fiezel-ob-word,
.fiezel-ob-reveal .fiezel-ob-tag {
  position: relative !important;
  z-index: 1 !important;
}

/* Maskot PAW Onboarding: WAJIB TAMPIL & BERGERAK SEPERTI SEMULA */
.fiezel-ob-mascot {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  visibility: visible !important;
  opacity: 1 !important;
}
.fiezel-ob-mascot fiezel-mascot,
.fiezel-ob-mascot .fiezel-ob-paw,
.fiezel-ob-mascot .fz-mascot {
  display: inline-block !important;
  visibility: visible !important;
  opacity: 1 !important;
  pointer-events: auto !important;
}
.fiezel-stage-art {
  display: flex !important;
  flex-direction: row !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 12px !important;
  min-height: 0 !important;
  width: 100% !important;
}

/* ==========================================================================
   DUOLINGO-GRADE EDGE-TO-EDGE FULL-WIDTH APP SHELL OVERHAUL
   ========================================================================== */

/* 1. Viewport & App Container */
@media (max-width: 768px) {
  html {
    overflow-x: clip !important;
    overflow-y: auto !important;
    background: #FAF8F5 !important;
    -webkit-overflow-scrolling: touch;
  }
  body {
    overflow-x: clip !important;
    overflow-y: visible !important;
    background: #FAF8F5 !important;
  }

  main.app,
  .app,
  body.fz-lux .app {
    max-width: 100% !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 0 calc(84px + env(safe-area-inset-bottom)) 0 !important;
    box-sizing: border-box !important;
  }

  /* Mobile edge-to-edge layout: zero lateral void across all panels */
  #app {
    padding-left: 0 !important;
    padding-right: 0 !important;
    width: 100% !important;
    max-width: 440px !important;
    margin: 0 auto !important;
    box-sizing: border-box !important;
  }

  .home-today,
  section.fade,
  #fzClassHub,
  .classroom-page,
  .progress-page,
  .profile-page,
  .ch-student {
    padding-left: 12px !important;
    padding-right: 12px !important;
    width: 100% !important;
    max-width: 440px !important;
    margin: 0 auto !important;
    box-sizing: border-box !important;
  }

  .section-head {
    padding-left: 4px !important;
    padding-right: 4px !important;
    margin-bottom: 14px !important;
    box-sizing: border-box !important;
  }

  /* Quiz Shell: Sleek edge-to-edge fit with 6px margin, ZERO lateral void */
  body.fz-stage-quiz #app,
  body:has(.quiz-shell) #app,
  #app:has(.quiz-shell) {
    padding-left: 6px !important;
    padding-right: 6px !important;
    box-sizing: border-box !important;
  }
}

/* 2. Topbar: 100% Full-Width Edge-to-Edge */
.topbar,
header.topbar {
  position: sticky !important;
  top: 0 !important;
  left: 0 !important;
  right: 0 !important;
  width: 100% !important;
  max-width: 100% !important;
  margin: 0 !important;
  border-radius: 0 !important;
  border-left: none !important;
  border-right: none !important;
  border-top: none !important;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08) !important;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.45) !important;
  padding: max(10px, env(safe-area-inset-top)) 16px 10px 16px !important;
  background: rgba(14, 14, 20, 0.94) !important;
  backdrop-filter: blur(24px) !important;
  -webkit-backdrop-filter: blur(24px) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  gap: 12px !important;
  z-index: 100 !important;
  box-sizing: border-box !important;
}


.fz-home-brand-wrap {
  display: inline-flex !important;
  align-items: center !important;
  cursor: pointer !important;
}

.fz-home-brand-wrap svg.fiezel-wordmark {
  height: 24px !important;
  width: auto !important;
  max-width: 110px !important;
  display: block !important;
  filter: drop-shadow(0 2px 8px rgba(255, 217, 79, 0.35)) !important;
}


/* 4. Auth & Login Screen: 100% Viewport-Fit (No Scroll Required) */
.fz-auth {
  position: fixed !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100dvh !important;
  max-height: 100dvh !important;
  display: flex !important;
  flex-direction: column !important;
  justify-content: space-between !important;
  overflow-y: auto !important;
  overscroll-behavior: contain !important;
  background: #FBF7F3 !important;
  box-sizing: border-box !important;
  z-index: 2147481950 !important;
}

.fz-auth-hero.is-masuk {
  flex: 0 0 auto !important;
  min-height: 14vh !important;
  max-height: 16vh !important;
  padding: max(14px, calc(env(safe-area-inset-top) + 8px)) 20px 24px !important;
}

.fz-auth-hero.is-masuk .fz-auth-brand .fiezel-wordmark {
  width: min(36vw, 140px) !important;
}

.fz-auth-wave {
  height: 32px !important;
}

.fz-auth-body {
  flex: 1 1 auto !important;
  display: flex !important;
  flex-direction: column !important;
  justify-content: space-between !important;
  padding: 4px 20px max(16px, env(safe-area-inset-bottom)) 20px !important;
  max-width: 440px !important;
  margin: 0 auto !important;
  width: 100% !important;
  box-sizing: border-box !important;
}

.fz-auth-title {
  font-size: 1.6rem !important;
  line-height: 1.1 !important;
  margin: 0 0 8px 0 !important;
}

.fz-auth-roles {
  margin: 0 0 8px !important;
  padding: 3px !important;
}

.fz-auth-role {
  padding: 7px 10px !important;
  font-size: 0.88rem !important;
}

.fz-auth-google {
  min-height: 38px !important;
  height: 38px !important;
}

.fz-auth-or {
  margin: 6px 0 2px !important;
  font-size: 0.75rem !important;
}

.fz-auth-form {
  gap: 8px !important;
  margin-top: 2px !important;
}

.fz-auth-field {
  gap: 3px !important;
}

.fz-auth-label {
  font-size: 0.82rem !important;
}

.fz-auth-input {
  padding: 2px 0 !important;
}

.fz-auth .fz-auth-input input[name] {
  min-height: 34px !important;
  padding: 4px 0 !important;
  font-size: 0.92rem !important;
}

.fz-auth-row {
  margin-top: -2px !important;
}

.fz-auth .fz-auth-link {
  font-size: 0.8rem !important;
}

.fz-auth .fz-auth-submit {
  width: 100% !important;
  margin-top: 10px !important;
  padding: 13px 20px !important;
  font-size: 1rem !important;
  font-weight: 800 !important;
  border-radius: 9999px !important;
  background: linear-gradient(135deg, #FFE048 0%, #FFB800 100%) !important;
  color: #0F0E11 !important;
  border: none !important;
  box-shadow: 0 4px 18px rgba(255, 184, 0, 0.35) !important;
  cursor: pointer !important;
}

/* 5. Welcome Screen Compactness */
.fz-auth-hero.is-welcome {
  min-height: 45vh !important;
  max-height: 50vh !important;
}
.fz-auth-hero.is-welcome .fz-auth-paw {
  width: 90px !important;
  height: 90px !important;
}

/* m025-378: label soal ulangan lesson lain di sesi lesson 20 soal */
.quiz-review-tag{display:inline-flex;align-items:center;gap:6px;margin:0 0 6px;padding:4px 10px;border-radius:var(--radius-pill);font-size:.75rem;font-weight:700;letter-spacing:.02em;background:var(--sun-soft);color:var(--info)}
.quiz-review-tag i,.quiz-review-tag svg{width:13px;height:13px}

/* ==========================================================================
   UX-BRIEF (Anti-Ribet & Anti-Bosan) — 2026-06
   §1 tombol aksi utama beranda · §2 kuis 100dvh tanpa scroll di HP · §3 combo,
   bounce/shake · §4 layar kemenangan satu kartu · (naskah §5 di copy-id-*.js)
   ========================================================================== */
/* §1 Zero-friction home CTA */
/* body.fz-lux button (fiezel-lux.css) menimpa bg/warna semua tombol - tombol ini dikunci. */
body .fz-hero-cta,body.fz-lux .fz-hero-cta{
  width:100%;display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:14px;
  margin:6px 0 14px;padding:14px 16px 14px 14px;border:none!important;border-radius:20px!important;text-align:left;cursor:pointer;
  color:#0A0A0E!important;background:linear-gradient(135deg,#FFD94F 0%,#FFB800 55%,#FF9F1C 100%)!important;
  box-shadow:0 10px 28px -6px rgba(255,184,0,.45),0 2px 6px rgba(0,0,0,.18)!important;
  transition:transform .14s var(--ease-spring),box-shadow .14s ease;
  animation:heroCtaIn .55s var(--ease-spring) both;
}
.fz-hero-cta:hover{box-shadow:0 14px 32px -6px rgba(255,184,0,.55),0 2px 6px rgba(0,0,0,.18);transform:translateY(-1px)}
.fz-hero-cta:active{transform:scale(.975)}
.fz-hero-cta:focus-visible{outline:3px solid #fff;outline-offset:2px}
.fz-hero-cta-icon{width:46px;height:46px;display:grid;place-items:center;border-radius:14px;background:rgba(10,10,14,.12);color:#0A0A0E}
.fz-hero-cta-icon .fz-i,.fz-hero-cta-icon svg{width:24px;height:24px}
.fz-hero-cta-text{display:grid;gap:2px;min-width:0}
.fz-hero-cta-text b{font-size:1.02rem;font-weight:800;letter-spacing:-.01em;line-height:1.2}
.fz-hero-cta-text small{font-size:.78rem;font-weight:600;opacity:.78;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fz-hero-cta-arrow{width:36px;height:36px;display:grid;place-items:center;border-radius:999px;background:#0A0A0E;color:#FFD94F;transition:transform .2s var(--ease-spring)}
.fz-hero-cta-arrow svg{width:18px;height:18px}
.fz-hero-cta:hover .fz-hero-cta-arrow{transform:translateX(3px)}
body .fz-hero-cta.is-resume,body.fz-lux .fz-hero-cta.is-resume{background:linear-gradient(135deg,#FF8A5B 0%,#EA580C 60%,#C2410C 100%)!important;color:#fff!important;box-shadow:0 10px 28px -6px rgba(234,88,12,.5),0 2px 6px rgba(0,0,0,.2)!important}
.fz-hero-cta.is-resume .fz-hero-cta-icon{background:rgba(255,255,255,.18)}
.fz-hero-cta.is-resume .fz-hero-cta-arrow{background:#fff;color:#C2410C}
@keyframes heroCtaIn{from{opacity:0;transform:translateY(12px) scale(.97)}to{opacity:1;transform:none}}

/* §2 Kuis di HP: seluruh shell = tinggi layar; kartu soal melar sampai bawah, jadi tidak ada
   ruang hampa di bawah pilihan. Bilah "Lanjut" melayang tetap di zona jempol (fixed). Isi yang
   panjang (pembahasan) tetap bisa digulir DI DALAM halaman, bukan lompat dari ruang kosong. */
@media(max-width:640px){
  /* mobile-edge-fit.css: `#app > section{min-height:auto!important}` - dilawan dengan spesifisitas + !important */
  #app>section.quiz-shell,.quiz-shell{min-height:calc(100vh - var(--fz-topbar-h,65px))!important;min-height:calc(100dvh - var(--fz-topbar-h,65px))!important;display:flex;flex-direction:column;box-sizing:border-box}
  .quiz-shell>.card:last-of-type{flex:1 1 auto;display:flex;flex-direction:column;margin-bottom:0}
  .quiz-shell .quiz-mascot{flex:0 0 auto}
  .quiz-shell .options{gap:10px}
  .quiz-shell .option{min-height:56px}
}
@media(max-width:640px) and (max-height:700px){
  .quiz-shell .quiz-mascot{display:none}
  .quiz-shell .question{margin:4px 0 12px}
}

/* §3 Umpan balik instan: centang memantul saat benar, getar saat salah, lencana combo. */
@keyframes optionBounce{0%{transform:scale(1)}30%{transform:scale(1.035) translateY(-3px)}60%{transform:scale(.985) translateY(0)}100%{transform:none}}
@keyframes optionShake{0%,100%{transform:translateX(0)}15%{transform:translateX(-7px)}35%{transform:translateX(6px)}55%{transform:translateX(-4px)}75%{transform:translateX(3px)}}
@keyframes tagPop{0%{transform:scale(.4);opacity:0}60%{transform:scale(1.15);opacity:1}100%{transform:scale(1)}}
.option.correct{animation:optionBounce .55s var(--ease-spring)}
.option.wrong{animation:optionShake .45s var(--ease)}
.option.correct::after,.option.wrong::after{animation:tagPop .45s var(--ease-spring) both}
.combo-badge{
  position:fixed;left:50%;top:22%;z-index:2147481600;pointer-events:none; /* di atas scrim popup keyakinan (2147481400) */
  display:grid;grid-auto-flow:column;align-items:center;gap:10px;padding:12px 20px;
  border-radius:999px;color:#fff;background:linear-gradient(135deg,#FF8A5B,#EA580C 55%,#C2410C);
  box-shadow:0 14px 36px -8px rgba(234,88,12,.6),0 0 0 4px rgba(255,255,255,.12);
  opacity:0;transform:translate(-50%,10px) scale(.6);
  transition:opacity .28s var(--ease),transform .38s var(--ease-spring);
}
.combo-badge.hidden{display:none}
.combo-badge.show{opacity:1;transform:translate(-50%,0) scale(1)}
.combo-badge-flame{width:34px;height:34px;display:grid;place-items:center;border-radius:999px;background:rgba(255,255,255,.2);animation:comboFlame .9s ease-in-out infinite alternate}
.combo-badge-flame svg{width:20px;height:20px}
.combo-badge b{font-size:1.25rem;font-weight:900;letter-spacing:-.01em;white-space:nowrap}
.combo-badge-note{font-size:.82rem;font-weight:700;opacity:.92;white-space:nowrap}
@keyframes comboFlame{from{transform:scale(1) rotate(-6deg)}to{transform:scale(1.12) rotate(6deg)}}

/* §4 Layar Kemenangan: satu kartu penuh, bintang animasi bertahap, chip hadiah, rincian dilipat. */
.result-stars{display:flex;justify-content:center;gap:8px;margin:-4px 0 10px}
.result-stars svg{width:34px;height:34px;color:var(--line);fill:transparent;transform:scale(.6);opacity:.55;transition:none}
.result-stars svg.is-lit{color:#FFB800;fill:#FFD94F;opacity:1;animation:starPop .6s var(--ease-spring) both;animation-delay:calc(var(--si,1)*140ms + 200ms)}
.result-stars svg:nth-child(2){width:42px;height:42px;margin-top:-6px}
@keyframes starPop{0%{transform:scale(.3) rotate(-20deg);opacity:0}65%{transform:scale(1.2) rotate(6deg);opacity:1}100%{transform:scale(1) rotate(0)}}
.result-rewards{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin:2px 0 8px}
.result-reward-chip{display:inline-flex;align-items:center;gap:6px;padding:7px 12px;border-radius:999px;font-weight:800;font-size:.9rem;
  background:var(--panel-soft);border:1px solid var(--line);color:var(--text);animation:riseIn .5s var(--ease) both;animation-delay:.5s}
.result-reward-chip svg{width:16px;height:16px}
.result-reward-chip.is-gem{background:rgba(56,189,248,.16);border-color:rgba(125,211,252,.55);color:#38BDF8}
.result-reward-chip.is-combo{background:rgba(251,146,60,.16);border-color:rgba(253,186,116,.55);color:#FB923C}
.result-details{margin-top:8px;text-align:left}
.result-details>summary{cursor:pointer;font-weight:700;color:var(--muted);font-size:.9rem;list-style:none;display:flex;align-items:center;justify-content:center;gap:6px;padding:8px}
.result-details>summary::-webkit-details-marker{display:none}
.result-details>summary::after{content:"▾";transition:transform .2s ease}
.result-details[open]>summary::after{transform:rotate(180deg)}
.result-details-body{padding-top:6px}
@media(max-width:640px){
  #app>section.result-stage.is-compact,.result-stage.is-compact{min-height:calc(100vh - var(--fz-topbar-h,65px))!important;min-height:calc(100dvh - var(--fz-topbar-h,65px))!important;display:flex;flex-direction:column;justify-content:center;padding-top:0;box-sizing:border-box}
  .result-stage.is-compact .result-card{margin:0;padding:22px 18px}
  .result-stage.is-compact .result-icon{width:52px;height:52px;margin-bottom:8px}
  .result-stage.is-compact h2{margin:6px 0 4px}
  .result-stage.is-compact .result-actions{margin-top:12px}
}
@media(prefers-reduced-motion:reduce){
  .fz-hero-cta,.option.correct,.option.wrong,.option.correct::after,.option.wrong::after,.combo-badge-flame,.result-stars svg.is-lit,.result-reward-chip{animation:none}
  .result-stars svg.is-lit{transform:none;opacity:1}
}

/* ===== Audit UX 2026-10 Perbaikan ===== */

/* P0-3: Banner retry di atas opsi saat percobaan pertama salah */
.quiz-retry-hint{
  display:flex;align-items:center;gap:8px;
  padding:10px 14px;margin:0 0 8px;
  border-radius:var(--radius-sm,18px);
  background:var(--info-soft,#FBF3E2);
  color:var(--info,#7A5512);
  font-size:.88rem;font-weight:600;
  animation:riseIn .4s var(--ease-spring,cubic-bezier(.34,1.4,.4,1)) both;
}
.quiz-retry-hint svg{width:16px;height:16px;flex-shrink:0}
@media(prefers-reduced-motion:reduce){.quiz-retry-hint{animation:none}}

/* P2-4: Retention peek di layar kemenangan (di luar lipatan details) */
.result-peek{
  display:flex;align-items:center;gap:6px;justify-content:center;
  margin:4px 0;
  font-size:.88rem;font-weight:600;
  color:var(--muted,#6E635C);
}
.result-peek svg{width:15px;height:15px;flex-shrink:0}
.result-peek b{color:var(--good-bright,#2E8B69)}

/* P2-5: Review tag visual hierarchy — aksen biru untuk soal ulangan */
.quiz-review-tag{
  background:rgba(41,121,255,.08) !important;
  border-color:rgba(41,121,255,.22) !important;
  color:var(--info,#2979FF) !important;
}


/* Penjelasan Guru & Diagnostic Clue (Midnight Navy / Travertine White - Zero Brown / Zero Maroon) */
.tutor-turn,
html body .tutor-turn,
.card .tutor-turn {
  margin-top: 14px !important;
  padding: 14px 16px !important;
  border-radius: 14px !important;
  background: #151520 !important;
  border: 1px solid rgba(255, 255, 255, 0.12) !important;
  border-left: 4px solid #38BDF8 !important;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35) !important;
}

[data-theme="light"] .tutor-turn,
body:not(.theme-dark):not(.fz-lux) .card-light .tutor-turn,
body:not(.theme-dark):not(.fz-lux) .tutor-turn {
  background: #FFFFFF !important;
  border: 1px solid #E2E8F0 !important;
  border-left: 4px solid #0284C7 !important;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05) !important;
}

.tutor-turn-head,
.card .tutor-turn-head {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
  margin-bottom: 8px !important;
  font-size: 0.72rem !important;
  letter-spacing: 0.12em !important;
  text-transform: uppercase !important;
  color: #38BDF8 !important;
  font-weight: 800 !important;
}

[data-theme="light"] .tutor-turn-head,
body:not(.theme-dark):not(.fz-lux) .card-light .tutor-turn-head,
body:not(.theme-dark):not(.fz-lux) .tutor-turn-head {
  color: #0369A1 !important;
}

.tutor-turn-face {
  display: grid !important;
  place-items: center !important;
  width: 22px !important;
  height: 22px !important;
  border-radius: 50% !important;
  background: rgba(56, 189, 248, 0.2) !important;
  color: #38BDF8 !important;
  flex-shrink: 0 !important;
}

[data-theme="light"] .tutor-turn-face,
body:not(.theme-dark):not(.fz-lux) .card-light .tutor-turn-face,
body:not(.theme-dark):not(.fz-lux) .tutor-turn-face {
  background: #E0F2FE !important;
  color: #0284C7 !important;
}

.tutor-diagnostic-clue {
  background: rgba(56, 189, 248, 0.08) !important;
  border: 1px solid rgba(56, 189, 248, 0.25) !important;
  border-radius: 10px !important;
  padding: 10px 14px !important;
  color: #F8FAFC !important;
  font-weight: 600 !important;
  font-size: 14.5px !important;
  line-height: 1.55 !important;
  margin: 6px 0 10px !important;
  display: flex !important;
  align-items: flex-start !important;
  gap: 10px !important;
}

.tutor-diagnostic-clue svg {
  width: 17px !important;
  height: 17px !important;
  color: #38BDF8 !important;
  flex-shrink: 0 !important;
  margin-top: 2px !important;
}

[data-theme="light"] .tutor-diagnostic-clue,
body:not(.theme-dark):not(.fz-lux) .card-light .tutor-diagnostic-clue,
body:not(.theme-dark):not(.fz-lux) .tutor-diagnostic-clue {
  background: #F0F9FF !important;
  border-color: #BAE6FD !important;
  color: #0C4A6E !important;
}

.tutor-turn-say,
.card .tutor-turn-say {
  margin: 0 !important;
  font-size: 0.92rem !important;
  line-height: 1.6 !important;
  color: #CBD5E1 !important;
}

[data-theme="light"] .tutor-turn-say,
body:not(.theme-dark):not(.fz-lux) .card-light .tutor-turn-say,
body:not(.theme-dark):not(.fz-lux) .tutor-turn-say {
  color: #475569 !important;
}

.tutor-turn-ask,
.card .tutor-turn-ask {
  margin: 8px 0 0 !important;
  font-size: 0.94rem !important;
  line-height: 1.6 !important;
  font-weight: 700 !important;
  color: #FBBF24 !important;
}

[data-theme="light"] .tutor-turn-ask,
body:not(.theme-dark):not(.fz-lux) .card-light .tutor-turn-ask,
body:not(.theme-dark):not(.fz-lux) .tutor-turn-ask {
  color: #B45309 !important;
}

.tutor-turn-actions {
  margin-top: 12px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: flex-start !important;
}

.tutor-stuck,
html body .tutor-stuck,
.card .tutor-stuck {
  min-height: 38px !important;
  padding: 6px 14px !important;
  border-radius: 999px !important;
  font-size: 0.84rem !important;
  font-weight: 600 !important;
  background: rgba(255, 255, 255, 0.06) !important;
  border: 1px solid rgba(255, 255, 255, 0.16) !important;
  color: #CBD5E1 !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 7px !important;
  transition: all .15s ease !important;
  text-decoration: none !important;
}

.tutor-stuck svg {
  width: 15px !important;
  height: 15px !important;
  color: #94A3B8 !important;
}

.tutor-stuck:hover {
  background: rgba(255, 255, 255, 0.12) !important;
  color: #FFFFFF !important;
  border-color: rgba(255, 255, 255, 0.3) !important;
}

[data-theme="light"] .tutor-stuck,
body:not(.theme-dark):not(.fz-lux) .card-light .tutor-stuck,
body:not(.theme-dark):not(.fz-lux) .tutor-stuck {
  background: #F8FAFC !important;
  border-color: #CBD5E1 !important;
  color: #475569 !important;
}

[data-theme="light"] .tutor-stuck:hover,
body:not(.theme-dark):not(.fz-lux) .card-light .tutor-stuck:hover,
body:not(.theme-dark):not(.fz-lux) .tutor-stuck:hover {
  background: #F1F5F9 !important;
  color: #0F172A !important;
}

/* Compact question card & prompt (Reduced by >50% vertical footprint) */
.quiz-bubble,
.speech-bubble {
  padding: 8px 12px !important;
  border-radius: 12px !important;
  margin-bottom: 8px !important;
}

.quiz-bubble .question-instruction,
.quiz-stage .question-instruction,
.speech-bubble .question-instruction,
.quiz-shell .question-instruction,
.card .question-instruction,
.question .question-instruction,
.question-instruction {
  display: inline-block !important;
  font-size: 0.75rem !important;
  font-weight: 700 !important;
  color: #94A3B8 !important;
  letter-spacing: 0.06em !important;
  text-transform: uppercase !important;
  margin-bottom: 4px !important;
  line-height: 1.25 !important;
  padding: 2px 7px !important;
  border-radius: 5px !important;
  background: rgba(148, 163, 184, 0.12) !important;
}

.quiz-bubble .question-main,
.quiz-stage .question-main,
.speech-bubble .question-main,
.quiz-shell .question-main,
.card .question-main,
.question .question-main,
.question-main {
  display: block !important;
  font-size: clamp(0.92rem, 0.88rem + 0.3vw, 1.02rem) !important;
  font-weight: 600 !important;
  line-height: 1.35 !important;
  letter-spacing: -0.01em !important;
}


.tutor-diagnostic-clue,
.tutor-turn .tutor-diagnostic-clue,
.card .tutor-diagnostic-clue,
#tutorTurn .tutor-diagnostic-clue {
  background: #F0F9FF !important;
  border: 1px solid #BAE6FD !important;
  border-radius: 12px !important;
  padding: 10px 14px !important;
  color: #0369A1 !important;
  font-weight: 600 !important;
  font-size: 14px !important;
  line-height: 1.55 !important;
  margin: 6px 0 10px !important;
  display: flex !important;
  align-items: flex-start !important;
  gap: 10px !important;
}

.tutor-diagnostic-clue span,
.tutor-turn .tutor-diagnostic-clue span,
.card .tutor-diagnostic-clue span,
.card div > .tutor-diagnostic-clue span,
#tutorTurn .tutor-diagnostic-clue span {
  color: #0369A1 !important;
  font-weight: 600 !important;
  font-size: 14px !important;
}

.tutor-diagnostic-clue svg,
.tutor-turn .tutor-diagnostic-clue svg {
  width: 17px !important;
  height: 17px !important;
  color: #0284C7 !important;
  flex-shrink: 0 !important;
  margin-top: 2px !important;
}

body.scene-night .tutor-diagnostic-clue,
body.theme-dark .tutor-diagnostic-clue {
  background: rgba(14, 165, 233, 0.16) !important;
  border-color: rgba(56, 189, 248, 0.35) !important;
  color: #E0F2FE !important;
}

body.scene-night .tutor-diagnostic-clue span,
body.theme-dark .tutor-diagnostic-clue span {
  color: #E0F2FE !important;
}

body.scene-night .tutor-diagnostic-clue svg,
body.theme-dark .tutor-diagnostic-clue svg {
  color: #38BDF8 !important;
}


/* ==========================================================================
   TRAVERTINE CARD & ZERO ISOLATED BOX PALETTE FOR QUIZ STAGE
   ========================================================================== */
.quiz-shell > .card,
body.fz-stage-quiz .quiz-shell > .card,
.quiz-shell .card {
  background: linear-gradient(180deg, #FDF8F1 0%, #F5ECE0 100%) !important;
  border: 1.5px solid #E6D9C8 !important;
  border-radius: var(--radius-lg, 28px) !important;
  box-shadow: 0 12px 36px rgba(46, 39, 36, 0.08) !important;
}

/* ZERO isolated box around Mochi companion */
.quiz-stage .fz-paw-slot,
.quiz-stage .fz-paw-above,
.quiz-stage fiezel-mascot,
.quiz-shell .fz-paw-side,
.quiz-shell .fz-paw-side fiezel-mascot,
.fz-mochi-viewport {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

/* Clean white tile options with delicate warm sand border */
.quiz-shell .options button:not(.correct):not(.wrong):not(.is-correct):not(.is-selected),
.quiz-shell .options .option:not(.correct):not(.wrong):not(.is-correct):not(.is-selected),
.quiz-shell button.option:not(.correct):not(.wrong):not(.is-correct):not(.is-selected),
.quiz-shell .option:not(.correct):not(.wrong):not(.is-correct):not(.is-selected) {
  background: #FFFFFF !important;
  border: 1.5px solid #E8DFD3 !important;
  border-radius: 16px !important;
  color: #1E293B !important;
  box-shadow: 0 4px 10px rgba(46, 39, 36, 0.04) !important;
  font-weight: 600 !important;
}

/* ==========================================================================
   DYNAMIC CONTEXTUAL TOPBAR PER PANEL & ZERO-DUPLICATE HEADERS
   ========================================================================== */
.topbar-context-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.topbar-context-back-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.04);
  border: 1px solid rgba(0, 0, 0, 0.06);
  cursor: pointer;
  color: var(--text, #111827);
  flex-shrink: 0;
  transition: transform 0.15s ease, background 0.15s ease;
}
.topbar-context-back-btn:active {
  transform: scale(0.92);
}
.topbar-context-title {
  font-size: 20px !important;
  font-weight: 800 !important;
  letter-spacing: -0.025em !important;
  color: var(--text, #111827) !important;
  margin: 0 !important;
  line-height: 1.1 !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
.topbar-context-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Compact Active Level Pill inside Topbar (Zero Card Bloat) */
html body header.topbar .active-level-control,
header.topbar .active-level-control,
header.topbar #topContextActions .active-level-control,
#topContextActions .active-level-control,
.topbar-context-actions .active-level-control {
  display: inline-flex !important;
  flex-direction: row !important;
  align-items: center !important;
  justify-content: center !important;
  align-self: center !important;
  flex-shrink: 0 !important;
  width: auto !important;
  min-width: 0 !important;
  max-width: none !important;
  height: 32px !important;
  min-height: 32px !important;
  max-height: 32px !important;
  padding: 2px 8px 2px 10px !important;
  margin: 0 !important;
  border-radius: 9999px !important;
  border: 1.5px solid #E2E8F0 !important;
  background: #FFFFFF !important;
  box-shadow: 0 2px 0 #CBD5E1 !important;
  gap: 6px !important;
  cursor: pointer !important;
  box-sizing: border-box !important;
  transition: transform 0.1s ease, box-shadow 0.1s ease !important;
}

html body header.topbar .active-level-control:active,
header.topbar .active-level-control:active,
#topContextActions .active-level-control:active {
  transform: translateY(1px) scale(0.97) !important;
  box-shadow: 0 1px 0 #CBD5E1 !important;
}

html body header.topbar .active-level-control > span,
header.topbar .active-level-control > span,
#topContextActions .active-level-control > span {
  display: none !important;
}

html body header.topbar .active-level-control strong,
header.topbar .active-level-control strong,
#topContextActions .active-level-control strong {
  font-family: 'Plus Jakarta Sans', sans-serif !important;
  font-size: 13px !important;
  font-weight: 800 !important;
  color: #D97706 !important;
  line-height: 1 !important;
  letter-spacing: normal !important;
  margin: 0 !important;
  padding: 0 !important;
}

html body header.topbar .active-level-control small,
header.topbar .active-level-control small,
#topContextActions .active-level-control small {
  font-family: 'Plus Jakarta Sans', sans-serif !important;
  font-size: 10.5px !important;
  font-weight: 800 !important;
  color: #0F172A !important;
  background: #FDE047 !important;
  border: 1px solid #FACC15 !important;
  border-radius: 9999px !important;
  padding: 2px 7px !important;
  line-height: 1 !important;
  box-shadow: none !important;
  margin: 0 !important;
}

html body header.topbar .active-level-control b,
html body header.topbar .active-level-control .active-level-val,
header.topbar .active-level-control b,
header.topbar .active-level-control .active-level-val,
#topContextActions .active-level-control b,
#topContextActions .active-level-control .active-level-val {
  background: transparent !important;
  color: #D97706 !important;
  font-family: 'Plus Jakarta Sans', sans-serif !important;
  font-size: 13px !important;
  font-weight: 800 !important;
  padding: 0 !important;
  box-shadow: none !important;
  border-radius: 0 !important;
}

/* Eliminate duplicate page titles on panels where topbar handles it */
html body.fz-view-latihan #app .section-head,
html body.fz-view-grammar #app .section-head,
html body.fz-view-vocab #app .section-head,
html body.fz-stage-sl #app .section-head,
html body.fz-view-reading #app .section-head,
html body.fz-view-writing #app .section-head,
html body.fz-view-library #app .section-head,
body.fz-view-latihan .section-head,
body.fz-view-grammar .section-head,
body.fz-view-vocab .section-head,
body.fz-stage-sl .section-head,
body.fz-view-reading .section-head,
body.fz-view-writing .section-head,
body.fz-view-library .section-head,
#view-latihan > .section-head,
#view-grammar > .section-head {
  display: none !important;
  margin: 0 !important;
  padding: 0 !important;
  height: 0 !important;
  overflow: hidden !important;
}

/* ==========================================================================
   KOSAKATA HUB OVERHAUL (IMG_2620 Clean Cohesive Layout)
   ========================================================================== */
.vocab-hub-page {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: 8px 0 24px;
  box-sizing: border-box;
}
.vocab-hero-card {
  background: #FFFFFF !important;
  border-radius: 24px !important;
  padding: 20px 20px 18px !important;
  border: 1.5px solid #EAE3D9 !important;
  box-shadow: 0 8px 24px rgba(46, 39, 36, 0.06) !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 14px !important;
}
.vocab-hero-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.vocab-level-chip {
  font-size: 11px !important;
  font-weight: 800 !important;
  color: #B45309 !important;
  background: #FEF3C7 !important;
  border: 1px solid #FDE68A !important;
  padding: 4px 10px !important;
  border-radius: 999px !important;
  letter-spacing: 0.03em !important;
  text-transform: uppercase !important;
}
.vocab-count-badge {
  font-size: 12.5px !important;
  font-weight: 700 !important;
  color: #64748B !important;
}
.vocab-progress-track {
  width: 100%;
  height: 9px;
  background: #F1E9DE;
  border-radius: 999px;
  overflow: hidden;
}
.vocab-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #F59E0B, #10B981);
  border-radius: 999px;
  transition: width 0.3s ease;
}
.vocab-hero-desc {
  font-size: 14px !important;
  line-height: 1.5 !important;
  color: #475569 !important;
  margin: 0 !important;
}
.vocab-hero-desc b {
  color: #0F172A !important;
  font-weight: 800 !important;
}
.vocab-main-flashcard-btn {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  width: 100% !important;
  padding: 15px 18px !important;
  border-radius: 18px !important;
  background: linear-gradient(135deg, #FFB800, #F59E0B) !important;
  color: #1A1A1A !important;
  border: none !important;
  cursor: pointer !important;
  box-shadow: 0 6px 18px rgba(245, 158, 11, 0.35) !important;
  transition: transform 0.15s ease, filter 0.15s ease !important;
  box-sizing: border-box !important;
}
.vocab-main-flashcard-btn:active {
  transform: scale(0.98);
}
.vmf-left {
  display: flex;
  align-items: center;
  gap: 12px;
  text-align: left;
}
.vmf-icon {
  font-size: 24px;
  line-height: 1;
}
.vmf-text strong {
  display: block;
  font-size: 15.5px !important;
  font-weight: 800 !important;
  color: #1A1A1A !important;
  line-height: 1.2 !important;
}
.vmf-text small {
  display: block;
  font-size: 12px !important;
  font-weight: 600 !important;
  color: rgba(26, 26, 26, 0.75) !important;
  margin-top: 2px !important;
}
.vmf-arrow {
  font-size: 20px;
  font-weight: 800;
  color: #1A1A1A;
}
.vocab-quick-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  width: 100%;
}
.vocab-quick-btn {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  padding: 14px 14px !important;
  border-radius: 18px !important;
  background: #FFFFFF !important;
  border: 1.5px solid #EAE3D9 !important;
  box-shadow: 0 4px 12px rgba(46, 39, 36, 0.04) !important;
  cursor: pointer !important;
  text-align: left !important;
  transition: transform 0.15s ease, background 0.15s ease !important;
  box-sizing: border-box !important;
}
.vocab-quick-btn:active {
  transform: scale(0.97);
}
.vq-icon {
  font-size: 20px;
  line-height: 1;
  flex-shrink: 0;
}
.vq-text strong {
  display: block;
  font-size: 13.5px !important;
  font-weight: 800 !important;
  color: #0F172A !important;
  line-height: 1.25 !important;
}
.vq-text small {
  display: block;
  font-size: 11px !important;
  color: #64748B !important;
  margin-top: 3px !important;
}

/* Contextual Topbar Display Guard across panels */
body:not(.fz-stage-home) header.topbar #topBrandWrap,
body:not(.fz-stage-home) header.topbar #fzCourseSwitchBtn,
body:not(.fz-stage-home) header.topbar #fzNotifBtn {
  display: none !important;
}
body.fz-stage-home header.topbar #topBrandWrap {
  display: flex !important;
}
body.fz-stage-home header.topbar #fzCourseSwitchBtn {
  display: inline-flex !important;
}
body.fz-stage-home header.topbar #fzNotifBtn {
  display: inline-flex !important;
}
body.fz-stage-home header.topbar #topProfileFriendBtn,
body.fz-stage-home header.topbar #topSettingsBtn {
  display: none !important;
}
body.fz-stage-home header.topbar #topContextWrap,
body.fz-stage-home header.topbar #topContextActions {
  display: none !important;
}

body:not(.fz-view-profile) header.topbar #topProfileFriendBtn,
body:not(.fz-view-profile) header.topbar #topSettingsBtn {
  display: none !important;
}
body.fz-view-profile header.topbar #topProfileFriendBtn {
  display: inline-flex !important;
}
body.fz-view-profile header.topbar #topSettingsBtn {
  display: inline-flex !important;
}
body.fz-view-profile header.topbar #fzNotifBtn,
body.fz-view-profile header.topbar #fzCourseSwitchBtn {
  display: none !important;
}

body.fz-view-classroom header.topbar #topContextWrap,
body.fz-view-classroom header.topbar #topContextActions,
body.fz-view-classroom header.topbar #topGamifyCluster {
  display: none !important;
}

/* -------------------------------------------------------------------------
   SISTEM SCAN QRIS / TEMAN (KAMERA LIVE & UNGGAH GAMBAR GALERI)
   ------------------------------------------------------------------------- */
.fz-qr-scanner-box {
  position: relative;
  width: 210px;
  height: 210px;
  max-width: 100%;
  margin: 0 auto;
  background: #090D16;
  border-radius: 16px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.8), 0 6px 20px rgba(0, 0, 0, 0.25);
  border: 1.5px solid rgba(255, 255, 255, 0.12);
}

.fz-qr-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.fz-qr-reticle {
  position: absolute;
  width: 145px;
  height: 145px;
  box-shadow: 0 0 0 9999px rgba(10, 14, 23, 0.55);
  border-radius: 14px;
  pointer-events: none;
}

.fz-qr-corner {
  position: absolute;
  width: 22px;
  height: 22px;
  border-color: #FFC800;
  border-style: solid;
  pointer-events: none;
}

.fz-qr-corner-tl {
  top: 0;
  left: 0;
  border-width: 3.5px 0 0 3.5px;
  border-top-left-radius: 12px;
}

.fz-qr-corner-tr {
  top: 0;
  right: 0;
  border-width: 3.5px 3.5px 0 0;
  border-top-right-radius: 12px;
}

.fz-qr-corner-bl {
  bottom: 0;
  left: 0;
  border-width: 0 0 3.5px 3.5px;
  border-bottom-left-radius: 12px;
}

.fz-qr-corner-br {
  bottom: 0;
  right: 0;
  border-width: 0 3.5px 3.5px 0;
  border-bottom-right-radius: 12px;
}

.fz-qr-laser {
  position: absolute;
  left: 4px;
  right: 4px;
  height: 2px;
  background: linear-gradient(90deg, rgba(255,200,0,0) 0%, #FFC800 50%, rgba(255,200,0,0) 100%);
  box-shadow: 0 0 10px #FFC800, 0 0 4px #FFF;
  border-radius: 2px;
  animation: fzQrScanLaser 2s cubic-bezier(0.4, 0, 0.2, 1) infinite alternate;
  pointer-events: none;
}

@keyframes fzQrScanLaser {
  0% {
    top: 8px;
    opacity: 0.4;
  }
  50% {
    opacity: 1;
  }
  100% {
    top: calc(100% - 10px);
    opacity: 0.4;
  }
}

.fz-qr-cam-fallback {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 14px;
  text-align: center;
  color: #94A3B8;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}

.fz-qr-cam-fallback p {
  font-size: 11.5px !important;
  line-height: 1.35 !important;
  margin: 0 !important;
  color: #CBD5E1 !important;
}

.modal-panel.modal-connect-panel,
#modalPanel.modal-connect-panel {
  padding: 16px 16px 16px !important;
  padding-bottom: max(16px, env(safe-area-inset-bottom, 16px)) !important;
  max-width: 360px !important;
  max-height: 92vh !important;
}

/* Kontras WCAG AAA: Kode Undangan & Teman di dalam modal gelap (#14141C) */
.modal-panel .social-code,
#modalPanel .social-code {
  background: rgba(255, 200, 0, 0.12) !important;
  border: 1.5px solid #FFC800 !important;
  color: #FFDE43 !important;
}

/* Modal handle ID: pill kontras tinggi (#FFF9E6 teks #111118, kontras > 16:1 AAA) */
.modal-panel .fz2-myid,
#modalPanel .fz2-myid,
.modal-connect-panel .fz2-myid {
  background: #FFF9E6 !important;
  color: #111118 !important;
  padding: 4px 12px !important;
  border-radius: 999px !important;
  border: 1.5px solid rgba(255, 200, 0, 0.45) !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-weight: 800 !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
  letter-spacing: 0.02em !important;
}

/* Ergonomi Touch Target: Segmented Nav Modal (min-height 40px, padding 8px 4px) */
.connect-segmented-nav button {
  min-height: 40px !important;
  padding: 8px 4px !important;
  font-size: 11px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}

/* Ergonomi Touch Target: Tombol Salin ID (min-height >= 36px, padding 6px 12px) */
.btn-copy-code {
  min-height: 36px !important;
  padding: 6px 12px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 4px !important;
}

/* Ergonomi Touch Target: Baris Permintaan Teman (min-height 40px, padding 8px 14px, gap 10px) */
.social-request-acts,
#connectRequestsList [style*="flex-shrink:0"],
#connectRequestsList div:has(> button) {
  gap: 10px !important;
}

.social-request-acts button,
.social-request-acts .text-button,
.social-request-acts .primary,
#connectRequestsList button.text-button,
#connectRequestsList button.primary,
#connectRequestsList [onclick*="decideFriendRequest"] {
  min-height: 40px !important;
  padding: 8px 14px !important;
  font-size: 11.5px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}

/* Pencegahan Horizontal Layout Blowout pada layar sempit */
@media (max-width: 400px) {
  .social-friend {
    flex-wrap: wrap !important;
    gap: 8px !important;
  }
  .social-friend-acts {
    width: 100% !important;
    justify-content: flex-end !important;
  }
}

.fz3-qr {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 4px auto;
}

.fz3-qr svg {
  max-width: 145px;
  max-height: 145px;
  width: auto;
  height: auto;
  display: block;
}

.notif-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 36px 16px;
  text-align: center;
  color: var(--muted);
}

.notif-spinner {
  width: 26px;
  height: 26px;
  border: 3px solid rgba(255, 200, 0, 0.2);
  border-top-color: #FFC800;
  border-radius: 50%;
  animation: notifSpin 0.8s linear infinite;
  display: inline-block;
}

@keyframes notifSpin {
  to { transform: rotate(360deg); }
}

/* m025-577 Alasan Soal: satu baris di atas soal sesi adaptif yang mengucapkan KENAPA soal itu
   dipilih. Sengaja setenang Stempel Ingatan (12px, muted) supaya tidak bersaing dengan soal;
   yang membuatnya terlihat adalah ikon Pau kecil dan ketepatan kalimatnya, bukan bobotnya. */
.quiz-alasan{display:flex;align-items:flex-start;gap:6px;margin:0 0 8px;font-size:12px;line-height:1.45;font-weight:600;letter-spacing:.01em;color:var(--muted,#6E635C);text-align:left}
.quiz-alasan .fz-i,.quiz-alasan svg{width:14px;height:14px;flex:0 0 14px;margin-top:1px;--fz-i-line:var(--info,#2979FF)}
/* Di gelembung soal gelap (slot Pau 'above') warna muted bawaan hanya ~2:1 terhadap latarnya:
   naik ke slate terang, ikon emas brand. */
html body #app .quiz-bubble p.quiz-alasan{color:#CBD5E1 !important;-webkit-text-fill-color:#CBD5E1 !important}
html body #app .quiz-bubble .quiz-alasan .fz-i,html body #app .quiz-bubble .quiz-alasan svg{--fz-i-line:#FFD54A}
:lang(th) .quiz-alasan{font-size:13px;line-height:1.6;letter-spacing:normal}
/* Rekap "Yang Fiezel atur untukmu" di layar hasil, di luar lipatan Detail. Rata kiri di dalam
   kartu hasil yang rata tengah: daftar tiga kalimat terbaca sebagai laporan, bukan slogan. */
.result-alasan{margin:10px auto 4px;max-width:360px;padding:10px 14px;border-radius:14px;background:rgba(41,121,255,.06);border:1px solid rgba(41,121,255,.16);text-align:left}
.result-alasan-head{display:flex;align-items:center;gap:6px;font-size:.8rem;font-weight:800;letter-spacing:.02em;color:var(--text,#1F2937)}
.result-alasan-head .fz-i,.result-alasan-head svg{width:14px;height:14px;flex:0 0 14px;--fz-i-line:var(--info,#2979FF)}
.result-alasan ul{margin:6px 0 0;padding:0 0 0 18px}
/* --muted di kartu hasil jatuh ke #94A3B8 (~2,5:1 di atas latar biru muda): terlalu pucat untuk
   kalimat yang justru ingin dibaca. */
.result-alasan li{margin:2px 0;font-size:.84rem;line-height:1.45;font-weight:500}
html body #app .result-alasan li{color:#4B5563 !important}
:lang(th) .result-alasan li{line-height:1.65}
/* m025-577 Bukti Ingatan: satu kalimat + garis dua ruas di popup vonis (kartu putih). Ruas kiri
   = jarak yang baru saja ditempuh ingatan, ruas kanan = jarak ke ulangan berikutnya. "Masih
   ingat" memanjangkan ruas kanan (hijau), "pudar" memendekkannya (amber). Tanpa animasi:
   gambar yang diam sudah cukup bicara, dan popup ini sudah punya animasi masuknya sendiri. */
/* Latar SOLID, bukan rgba: kartu vonis sedikit tembus pandang, dan latar transparan membuat
   teks pilihan di balik popup terbaca samar di dalam kotak ini (terlihat di probe 390px). */
.cp-ingatan{margin:-4px 0 12px;padding:10px 12px;border-radius:12px;background:#F0F6FF;border:1px solid #D6E4FF}
.cp-ingatan-line{display:flex;align-items:flex-start;gap:6px;margin:0 0 8px;font-size:.84rem;line-height:1.45;font-weight:600;color:#334155}
.cp-ingatan-line .fz-i,.cp-ingatan-line svg{width:15px;height:15px;flex:0 0 15px;margin-top:1px;--fz-i-line:var(--info,#2979FF)}
.cp-ingatan-track{display:flex;gap:3px;height:20px}
.cp-seg{display:flex;align-items:center;justify-content:center;min-width:0;border-radius:6px;font-size:.7rem;font-weight:800;letter-spacing:.02em;white-space:nowrap;overflow:hidden}
.cp-seg.is-lalu{background:#E2E8F0;color:#475569}
.cp-ingatan.is-masih .cp-seg.is-depan{background:#D1FAE5;color:#047857}
.cp-ingatan.is-pudar .cp-seg.is-depan{background:#FEF3C7;color:#B45309}
:lang(th) .cp-ingatan-line{font-size:.88rem;line-height:1.6}
/* m025-577 Hero "Rencana Fiezel hari ini". Hanya elemen BARU; kartu, ubin kata, pil
   (.adaptive-sub) dan tombol tetap memakai aturan tactile-clay yang sudah ada. */
.hero-kata-judul{margin:0 0 3px;font-size:10.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:#B45309}
.hero-kata-meta{margin-top:3px;font-size:11.5px;font-weight:700;color:#475569}
.hero-card.is-rawan .hero-micro-bite{border-color:#FDE68A !important;background:#FFFBEB !important}
.hero-plan{display:flex;flex-wrap:wrap;gap:6px;margin-top:-4px}
.hero-plan .hero-pil{margin-top:0 !important;max-width:100%}
.hero-plan .hero-pil > span{min-width:0;white-space:normal;line-height:1.35}
.hero-plan .hero-pil svg{width:12px;height:12px;flex:0 0 12px}
:lang(th) .hero-kata-judul{letter-spacing:normal;font-size:11.5px}
:lang(th) .hero-kata-meta,:lang(th) .hero-plan .hero-pil{line-height:1.5}
