/* Peta beranda: jalur level (bentuk tombol, banner dunia) dan dunia bertema (js/world.js): latar bergambar
   selebar layar per bagian, jalan berliku, hiasan di sisi jalur, bintang level. Hanya warna palet
   (+ abu gelap untuk mode gelap). */

.unit { --unit: var(--brand); --unit-dark: var(--brand-dark); margin-top: 28px; }
.unit-2 { --unit: var(--teal); --unit-dark: var(--teal-dark); }
.unit-3 { --unit: var(--french); --unit-dark: var(--violet); }
:root[data-theme="dark"] .unit-3 { --unit: var(--powder); --unit-dark: var(--french); }
.unit-banner { display: flex; align-items: center; gap: 12px; padding: 12px 16px; color: var(--on-brand); background: var(--unit); border: 3px solid var(--seashell); border-radius: 20px; box-shadow: 0 5px 0 var(--unit-dark); }
.unit-banner h2 { font-size: 21px; line-height: 1.2; }
.unit-kicker { font-size: 13px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.unit-icon { flex: none; display: grid; place-items: center; width: 48px; height: 48px; color: var(--violet); background: var(--wheat); border: 3px solid var(--violet); border-radius: 50%; }
.unit-icon svg { width: 26px; height: 26px; }

.path { display: flex; flex-direction: column; align-items: center; gap: 26px; margin: 28px 0 0; padding: 0; list-style: none; }
.path-end { margin-top: 44px; }
.path-item { position: relative; display: flex; flex-direction: column; align-items: center; transform: translateX(var(--x, 0)); }
.path-item.is-current { margin-top: 38px; }

/* Level seperti tombol game: elips tebal dengan bibir bawah, ditekan masuk. */
.node {
  position: relative;
  display: grid;
  place-items: center;
  width: 80px;
  height: 72px;
  color: var(--on-brand);
  text-decoration: none;
  background: var(--unit, var(--brand));
  border-radius: 50%;
  box-shadow: 0 8px 0 var(--unit-dark, var(--brand-dark));
  transition: transform .1s, box-shadow .1s;
}
.node .icon svg { width: 34px; height: 34px; }
a.node:active { transform: translateY(6px); box-shadow: 0 2px 0 var(--unit-dark, var(--brand-dark)); }
@media (hover: hover) { a.node:hover { transform: translateY(-3px); box-shadow: 0 11px 0 var(--unit-dark, var(--brand-dark)); } }
.node-locked { color: var(--violet); background: var(--line); box-shadow: 0 8px 0 var(--french); }
:root[data-theme="dark"] .node-locked { color: var(--seashell); }
.node-trophy { color: var(--violet); background: var(--warn); box-shadow: 0 8px 0 var(--brand-dark); }
.node-trophy, .node-trophy-locked { width: 96px; height: 86px; }
.node-trophy .icon svg, .node-trophy-locked .icon svg { width: 42px; height: 42px; }
/* Ronde Kilat: kotak bonus, beda bentuk dari level biasa. */
.node-quick, .node-quick-locked { border-radius: 26px; }
/* Level yang sedang dimainkan: cincin di sekelilingnya dan papan "Mulai" yang memantul. */
.is-current .node::before {
  content: "";
  position: absolute;
  inset: -12px -12px -20px;
  border: 6px solid var(--line);
  border-radius: 50%;
}
.node-label { max-width: 170px; margin-top: 12px; font-size: 15px; font-weight: 700; line-height: 1.3; text-align: center; }
.node-locked ~ .node-label { color: var(--muted); }

/* Level terkunci adalah tombol: diketuk, muncul gelembung "kenapa terkunci" di atasnya (js/path.js). */
button.node { padding: 0; font: inherit; border: 0; cursor: pointer; }
button.node:active { transform: translateY(4px); box-shadow: 0 4px 0 var(--french); }
.path-item.has-tip { z-index: 5; } /* di atas level dan hiasan lain, di bawah banner dunia yang menempel */
.lock-tip {
  position: absolute;
  bottom: calc(100% + 14px);
  left: 50%;
  width: min(300px, 100cqi - 32px);
  padding: 12px 14px;
  text-align: left;
  color: var(--ink);
  background: var(--bg);
  border: 2px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 6px 0 var(--line);
  /* Di tengah jalur (bukan di tengah level) supaya tidak keluar layar; ekornya menunjuk ke level. */
  translate: calc(-50% - var(--x, 0px)) 0;
  animation: lock-pop .22s cubic-bezier(.3, 0, .3, 1.3);
}
.is-current .lock-tip { bottom: calc(100% + 48px); }
.lock-tip::after {
  content: "";
  position: absolute;
  left: calc(50% + var(--x, 0px));
  bottom: -9px;
  width: 14px;
  height: 14px;
  background: var(--bg);
  border-right: 2px solid var(--line);
  border-bottom: 2px solid var(--line);
  transform: translateX(-50%) rotate(45deg);
}
.lock-tip-text { display: flex; align-items: flex-start; gap: 8px; font-size: 16px; font-weight: 700; line-height: 1.4; }
.lock-tip-text .icon { flex: none; margin-top: 2px; color: var(--muted); }
.lock-tip-text .icon svg { width: 18px; height: 18px; }
.lock-go {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  margin-top: 10px;
  padding: 8px 14px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--on-brand);
  background: var(--brand);
  border-radius: 12px;
  box-shadow: 0 4px 0 var(--brand-dark);
}
.lock-go:active { transform: translateY(4px); box-shadow: none; }
@keyframes lock-pop { from { opacity: 0; transform: translateY(8px) scale(.92); } }
.node-badge {
  position: absolute;
  top: -40px;
  padding: 4px 12px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--unit, var(--brand));
  background: var(--bg);
  border: 2px solid var(--line);
  border-radius: 10px;
  animation: bob 1.4s ease-in-out infinite;
}
.node-badge::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -7px;
  width: 10px;
  height: 10px;
  background: var(--bg);
  border-right: 2px solid var(--line);
  border-bottom: 2px solid var(--line);
  transform: translateX(-50%) rotate(45deg);
}


.world-1 { --w-sky: var(--powder); --w-ground: var(--wheat); --w-road: var(--seashell); --w-road-line: var(--powder); }
.world-2 { --w-sky: var(--french); --w-ground: var(--seashell); --w-road: var(--powder); --w-road-line: var(--seashell); }
:root[data-theme="dark"] .world-1 { --w-sky: var(--slate); --w-ground: var(--graphite); --w-road: var(--charcoal); --w-road-line: var(--slate); }
:root[data-theme="dark"] .world-2 { --w-sky: var(--french); --w-ground: var(--graphite); --w-road: var(--charcoal); --w-road-line: var(--slate); }
/* Dunia 3 "Teluk Phishing": langit sore, laut biru, dermaga kayu terang. */
.world-3 { --w-sky: var(--wheat); --w-ground: var(--powder); --w-road: var(--seashell); --w-road-line: var(--wheat); }
:root[data-theme="dark"] .world-3 { --w-sky: var(--slate); --w-ground: var(--charcoal); --w-road: var(--graphite); --w-road-line: var(--slate); }

.world {
  --sky-h: 210px;
  position: relative;
  padding: 16px 12px 36px;
  overflow: hidden;
  overflow: clip; /* clip, bukan hidden: hidden membuat banner sticky di dalamnya tidak bisa menempel */
  background: var(--w-ground);
  container-type: inline-size;
}
/* Dunia berikutnya langsung menyambung, tanpa celah, seperti peta game yang digulir. */
.home .world { margin-top: 0; }
.world-sky { position: absolute; top: 0; left: 0; right: 0; height: var(--sky-h); overflow: hidden; background: var(--w-sky); }
/* Kota setinggi tetap di dasar langit, dideret ke samping dari tengah supaya layar lebar ikut penuh. */
.world-town { position: absolute; bottom: 0; left: 50%; display: flex; transform: translateX(-50%); }
.world-town svg { flex: none; width: calc(130px * 400 / 120); height: 130px; overflow: visible; }
.world-sky .w-ground { fill: var(--w-ground); }

.world-road { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.world-road path { fill: none; stroke-linecap: round; }
.world-road .road { stroke: var(--w-road); stroke-width: 26px; }
.world-road .road-line { stroke: var(--w-road-line); stroke-width: 4px; stroke-dasharray: 2 14; }

.world .unit-banner { position: relative; max-width: 536px; margin-inline: auto; }
/* Banner dunia menempel di bawah bar atas selama dunianya terlihat, lalu didorong banner dunia berikutnya. */
.home .world .unit-banner { position: sticky; top: calc(var(--topbar-h) + 10px); z-index: 6; }

/* Langit yang hidup: awan melayang, burung mengepak, bintang berkelip, matahari berdenyut. */
.w-cloud, .w-bird, .w-twinkle, .w-sun { transform-box: fill-box; transform-origin: center; }
.w-cloud { animation: w-cloud 9s ease-in-out infinite alternate; }
.w-cloud:nth-of-type(2) { animation-duration: 12s; animation-direction: alternate-reverse; }
.w-birds { animation: w-glide 14s ease-in-out infinite alternate; }
.w-bird { animation: w-flap .5s ease-in-out infinite alternate; }
.w-bird:nth-child(2) { animation-delay: -.2s; }
.w-bird:nth-child(3) { animation-delay: -.35s; }
.w-twinkle { animation: w-twinkle 2.4s ease-in-out infinite; }
.w-sun { animation: pulse 4s ease-in-out infinite; }
.w-waves { animation: w-cloud 3.4s ease-in-out infinite alternate; }
.w-boat { transform-box: fill-box; transform-origin: 50% 100%; animation: w-rock 3s ease-in-out infinite; }
.w-boat:nth-of-type(2) { animation-delay: -1.4s; }
@keyframes w-rock { 0%, 100% { transform: rotate(-3deg); } 50% { transform: translateY(2px) rotate(3deg); } }
@keyframes w-cloud { to { transform: translateX(34px); } }
@keyframes w-glide { to { transform: translate(-60px, 8px); } }
@keyframes w-flap { to { transform: scaleY(.35); } }
@keyframes w-twinkle { 50% { transform: scale(.35) rotate(45deg); } }
.world .path { position: relative; margin-top: calc(var(--sky-h) - 86px); }

/* ---------- Pemandangan di tanah (CekWorld.scenery): di bawah jalur dan jalan, di atas warna tanah ---------- */
.world { isolation: isolate; } /* z-index -1 di bawah tetap di dalam dunia */
.world-scenery { position: absolute; inset: var(--sky-h) 0 0; z-index: -1; overflow: hidden; pointer-events: none; }
.scene-item, .scene-mover { position: absolute; pointer-events: auto; cursor: pointer; }
/* Tekstur tanah halus khas tiap dunia (rumput, bintang kecil, riak air). Warnanya dari --w-texture, bentuknya mask. */
.world-1 { --w-texture: var(--seashell); --w-pattern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M18 30l3-8 3 8M21 30v-9M74 64l3-7 3 7M98 100l2-6 2 6M38 92l3-8 3 8M41 92v-8'/%3E%3C/g%3E%3Ccircle cx='60' cy='20' r='2'/%3E%3Ccircle cx='104' cy='44' r='2'/%3E%3Ccircle cx='12' cy='72' r='2'/%3E%3C/svg%3E"); }
.world-2 { --w-texture: var(--powder); --w-pattern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cpath d='M24 18q0 6 6 6q-6 0-6 6q0-6-6-6q6 0 6-6zM86 70q0 5 5 5q-5 0-5 5q0-5-5-5q5 0 5-5z'/%3E%3Ccircle cx='70' cy='26' r='1.8'/%3E%3Ccircle cx='30' cy='86' r='1.8'/%3E%3Ccircle cx='106' cy='104' r='1.8'/%3E%3C/svg%3E"); }
.world-3 { --w-texture: var(--seashell); --w-pattern: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='120'%3E%3Cg fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M14 30q6-5 12 0t12 0M84 68q6-5 12 0t12 0M40 100q6-5 12 0'/%3E%3C/g%3E%3C/svg%3E"); }
:root[data-theme="dark"] .world-1, :root[data-theme="dark"] .world-2, :root[data-theme="dark"] .world-3 { --w-texture: var(--slate); }
.world-scenery::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--w-texture);
  -webkit-mask: var(--w-pattern) 0 0 / 120px 120px repeat;
  mask: var(--w-pattern) 0 0 / 120px 120px repeat;
}
.scene-item svg, .scene-mover svg { display: block; width: 100%; height: 100%; }
/* Hiasan diam: pita kiri dan kanan di luar jalur (jalur + hiasan levelnya selebar +-300px dari tengah). */
.scene-item {
  top: calc(var(--y) * (100% - 90px) + 10px);
  width: var(--size);
  height: var(--size);
  animation: scene-sway 4.6s ease-in-out infinite;
  animation-delay: calc(var(--i) * -.53s);
  transform-origin: 50% 100%;
}
.scene-item.is-left { left: calc(2cqi + var(--r) * (46cqi - 330px)); }
.scene-item.is-right { right: calc(2cqi + var(--r) * (46cqi - 330px)); }
@keyframes scene-sway { 0%, 100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg) translateY(-2px); } }
@container (max-width: 760px) { .scene-item { display: none; } } /* layar sempit: sisi jalur sudah terisi */

/* Diketuk: membal sambil berputar sedikit. */
.scene-item.is-boing, .scene-mover.is-boing { animation: scene-boing .55s cubic-bezier(.3, 0, .3, 1.5); }
@keyframes scene-boing { 0% { transform: none; } 35% { transform: translateY(-16px) rotate(-8deg) scale(1.1); } 70% { transform: translateY(2px) scale(1.05, .92); } 100% { transform: none; } }

/* Dunia 1: mobil kurir melaju melintasi peta (satu ke kanan, satu kembali ke kiri). */
.mover-van { top: calc(var(--y) * 100%); left: 0; width: 70px; height: 70px; animation: van-drive 18s linear infinite; animation-delay: var(--delay); }
.mover-van.is-back { animation-name: van-back; }
.mover-van svg { animation: van-bump .45s ease-in-out infinite alternate; }
.mover-van.is-back svg { animation-name: van-bump-back; }
@keyframes van-drive { from { transform: translateX(-90px); } to { transform: translateX(calc(100cqi + 20px)); } }
@keyframes van-back { from { transform: translateX(calc(100cqi + 20px)); } to { transform: translateX(-90px); } }
@keyframes van-bump { to { transform: translateY(-2px); } }
@keyframes van-bump-back { from { transform: scaleX(-1); } to { transform: scaleX(-1) translateY(-2px); } }

/* Dunia 2: kunang-kunang melayang dan berkelip di malam benteng. */
.mover-firefly { top: calc(var(--y) * (100% - 20px)); left: calc(var(--x) * 1%); width: 12px; height: 12px; color: var(--wheat); animation: firefly 7s ease-in-out infinite; animation-delay: var(--delay); }
:root:not([data-theme="dark"]) .mover-firefly { color: var(--french); }
@keyframes firefly {
  0%, 100% { transform: translate(0, 0); opacity: .25; }
  25% { transform: translate(18px, -14px); opacity: 1; }
  50% { transform: translate(-6px, -26px); opacity: .45; }
  75% { transform: translate(-20px, -8px); opacity: 1; }
}

/* Dunia 3: ombak bergelombang dan ikan melompat dari laut. */
.mover-wave { top: calc(var(--y) * 100%); left: -60px; right: -60px; height: 12px; color: var(--seashell); animation: wave-roll 5s ease-in-out infinite alternate; animation-delay: var(--delay); pointer-events: none; }
:root[data-theme="dark"] .mover-wave { color: var(--slate); }
@keyframes wave-roll { to { transform: translateX(48px); } }
.mover-fish { top: calc(var(--y) * 100%); left: calc(var(--x) * 1% - 24px); width: 48px; height: 48px; animation: fish-jump 4.2s cubic-bezier(.4, 0, .6, 1) infinite; animation-delay: var(--delay); }
@keyframes fish-jump {
  0%, 55%, 100% { transform: translateY(18px) rotate(40deg); opacity: 0; }
  62% { transform: translateY(0) rotate(-20deg); opacity: 1; }
  72% { transform: translate(14px, -30px) rotate(10deg); opacity: 1; }
  82% { transform: translate(28px, 0) rotate(50deg); opacity: 1; }
  88% { transform: translate(32px, 18px) rotate(70deg); opacity: 0; }
}


/* Hiasan di sisi kosong level: menempel di samping levelnya, setinggi tengah tombol level, jadi ikut
   jalur yang berliku (bukan berbaris lurus di satu kolom). --gap = jarak tengah level ke tengah hiasan. */
.world-prop {
  --gap: 104px; /* setengah level (40) + celah (30) + setengah hiasan (34) */
  position: absolute;
  top: 2px;
  left: 50%;
  width: 68px;
  height: 68px;
  pointer-events: none;
  transform: translateX(calc(var(--side) * var(--gap) - 50%));
}
.world-prop svg { width: 100%; height: 100%; animation: bob 3s ease-in-out infinite; animation-delay: calc(var(--i, 0) * -.7s); }
/* Coach Wall menunggu di samping level yang sedang dimainkan; bisa diketuk (tips muncul di gelembung). */
.world-coach { --gap: 118px; top: -14px; z-index: 4; width: 96px; height: 96px; pointer-events: auto; } /* di luar cincin level */
.world-coach .coach-wrap, .world-coach .coach-btn { width: 100%; height: 100%; }
.world-coach .coach-tip { max-width: 200px; }

/* Label level seperti papan nama, supaya tetap terbaca di atas gambar. */
.world .node-label {
  padding: 3px 12px;
  border-radius: 14px;
  color: var(--ink);
  background: var(--bg);
  border: 2px solid var(--violet);
}
:root[data-theme="dark"] .world .node-label { border-color: var(--slate); }
.world .node-locked ~ .node-label { color: var(--muted); border-color: var(--line); }
.world .node-locked { border: 3px solid var(--seashell); }
:root[data-theme="dark"] .world .node-locked { border-color: var(--graphite); }
/* Ronde Kilat berwarna wheat: diberi tepi violet, dan di Dunia 1 (tanah wheat) isinya seashell supaya tidak tenggelam. */
.world .node-quick { border: 3px solid var(--violet); }
.world-1 .node-quick { background: var(--seashell); }
:root[data-theme="dark"] .world .node-quick { background: var(--wheat); border-color: var(--graphite); }

/* Level selesai: ikon level + centang kecil, lalu tiga bintang. */
.node { position: relative; }
.node-check {
  position: absolute;
  right: -4px;
  bottom: -2px;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  color: var(--violet);
  background: var(--wheat);
  border: 3px solid var(--violet);
  border-radius: 50%;
}
.node-check .icon svg { width: 16px; height: 16px; }
.stars { display: flex; gap: 2px; margin-top: 10px; margin-bottom: -4px; }
.star .icon svg { width: 24px; height: 24px; color: var(--seashell); stroke: var(--violet); stroke-width: 1.6px; stroke-linejoin: round; }
.star.is-on .icon svg { color: var(--brand); }
.star:nth-child(2) { transform: translateY(-5px); }
:root[data-theme="dark"] .star .icon svg { color: var(--slate); stroke: var(--charcoal); }
:root[data-theme="dark"] .star.is-on .icon svg { color: var(--wheat); }

/* Transisi masuk level (CekWorld.mountTransitions): latar dunia membesar menutup layar. */
.level-wipe { position: fixed; inset: 0; z-index: 50; pointer-events: none; background: var(--w-ground); clip-path: circle(0 at 50% 50%); }

/* Halaman level (pelajaran, materi, Ronde Kilat): latar polos sewarna tanah dunianya, tanpa hiasan bergerak
   supaya tidak mengganggu saat menjawab. Isinya muncul pelan, menyambung transisi dari peta. */
.world-page { background: var(--w-ground); }
/* Dunia 3 di tema terang: tanah Powder Blue terlalu redup untuk teks, jadi halamannya (dan tirai transisinya) Seashell. */
:root:not([data-theme="dark"]) .world-page.world-3, :root:not([data-theme="dark"]) .level-wipe.world-3 { background: var(--seashell); }
.world-page > .lesson-top, .world-page > .lesson-main, .world-page > .lesson-footer { animation: level-in .3s ease-out both; }
@keyframes level-in { from { opacity: 0; } }
.world-coach .mascot svg { animation: none; } /* Coach Wall punya gerakannya sendiri (css/coach.css) */
