/* blooply.id hub.
   Identitas: aurora berbutir di pita atas (keluarga rona dari rujukan pemilik,
   hub/DESIGN.md memuat angka dan asalnya), tipografi editorial untuk suara
   merek, dan halaman yang bersih di bawahnya supaya isi produk tenang dibaca.
   Dua mode hidup di satu set variabel; mode gelap memakai versi dalam dari rona
   yang sama, bukan sekadar membalik warna.

   Pembagian peran warna, disengaja:
   - navy / tinta  -> semua teks dan tombol;
   - koral, kuning -> aksen grafis (mark, pip status, angka bagian);
   - aurora        -> latar pita atas, tidak pernah jadi tempat teks kecil;
     teks kecil yang benar-benar berada di pita itu memakai tinta penuh dan
     sudah diukur (tabel di DESIGN.md). */

@font-face {
  font-family: "Yeseva One";
  src: url("assets/fonts/YesevaOne-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Alegreya Sans";
  src: url("assets/fonts/AlegreyaSans-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Alegreya Sans";
  src: url("assets/fonts/AlegreyaSans-Italic.ttf") format("truetype");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Alegreya Sans";
  src: url("assets/fonts/AlegreyaSans-Bold.ttf") format("truetype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;
  --bg: #fbf9fb;
  /* Tinta = navy mark Blooply. Tinta lembut digelapkan dari versi sebelumnya
     supaya teks kecil tetap lolos di atas aurora, bukan hanya di atas latar. */
  --ink: #101830;
  --ink-soft: #333c57;
  --surface: #ffffff;
  --line: #e7e2e8;
  --brand-coral: #ff6678;
  --brand-yellow: #facc00;
  /* Satu-satunya bentuk koral yang boleh jadi teks; #ff6678 sendiri hanya 2.7:1
     di atas latar terang, jadi koral untuk teks selalu versi yang digelapkan. */
  --accent: #931a34;
  --btn-bg: #101830;
  --btn-ink: #fbf9fb;
  --focus: #931a34;
  /* Aurora. Lima rona, bukan empat tint yang bertetangga: sebaran rona inilah
     yang membedakan "aurora" dari "pastel". Nama token menyebut ronanya, bukan
     mereknya, karena tugasnya melukis cahaya, bukan membawa logo. */
  --blob-sage: 104 146 142;
  --blob-cream: 250 214 176;
  --blob-peri: 192 198 236;
  --blob-lilac: 206 196 224;
  --blob-blush: 248 206 200;
  --blob-alpha: 0.85;
  /* Lipatan air. Satu sisi jalur kursor terangkat (crest), sisi lain tertekan
     (trough): itu yang membuat gerakan terbaca sebagai air, bukan sebagai
     lapisan warna yang menempel. Kedua angka mix adalah batas atas yang diukur,
     dan kanvas membacanya langsung dari sini (lihat tabel di DESIGN.md). */
  --crest: 250 248 255;
  --crest-mix: 0.16;
  --trough: 58 66 96;
  --trough-mix: 0.06;
  --grain-opacity: 0.16;
  /* Satu kolom isi, dipakai header sampai footer supaya tepi kirinya sejajar.
     62rem terlalu sempit: teks hero hanya memakai sepertiga kolom dan sisanya
     terbaca sebagai ruang mati. */
  --shell: 74rem;
  --gutter: clamp(1.25rem, 3.5vw, 2.5rem);
  --radius-btn: 10px;
  --radius-card: 18px;
  --radius-shot: 12px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #080b14;
    --ink: #eef2fb;
    --ink-soft: #c9d2e4;
    --surface: #111726;
    --line: #262f47;
    --brand-coral: #ff8a99;
    --brand-yellow: #f7cf46;
    /* Lebih terang dari ronde sebelumnya: angka "01" pada label seksi sekarang
       duduk lebih tinggi di dalam pita, di atas aurora yang lebih pekat, dan
       #ffb3bd di sana hanya 4,42:1 (ambang 4,5). Diukur, bukan diperkirakan. */
    --accent: #ffc2ca;
    --btn-bg: #eef2fb;
    --btn-ink: #080b14;
    --focus: #ffc2ca;
    /* Versi dalam dari lima rona yang sama. Aurora gelap harus tetap di bawah
       ambang terang tertentu, kalau tidak tinta terang kehilangan kontras. */
    --blob-sage: 26 106 104;
    --blob-cream: 116 80 34;
    --blob-peri: 84 76 168;
    --blob-lilac: 100 80 158;
    --blob-blush: 132 52 70;
    --blob-alpha: 0.8;
    --crest: 208 220 255;
    --crest-mix: 0.12;
    --trough: 2 4 12;
    --trough-mix: 0.14;
    --grain-opacity: 0.2;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #080b14;
  --ink: #eef2fb;
  --ink-soft: #c9d2e4;
  --surface: #111726;
  --line: #262f47;
  --brand-coral: #ff8a99;
  --brand-yellow: #f7cf46;
  --accent: #ffc2ca;
  --btn-bg: #eef2fb;
  --btn-ink: #080b14;
  --focus: #ffc2ca;
  --blob-sage: 26 106 104;
  --blob-cream: 116 80 34;
  --blob-peri: 84 76 168;
  --blob-lilac: 100 80 158;
  --blob-blush: 132 52 70;
  --blob-alpha: 0.8;
  --crest: 208 220 255;
  --crest-mix: 0.12;
  --trough: 2 4 12;
  --trough-mix: 0.14;
  --grain-opacity: 0.2;
}

* { box-sizing: border-box; }

body {
  position: relative;
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "Alegreya Sans", "Segoe UI", system-ui, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Lapisan identitas di bawah isi halaman, semuanya pointer-events: none:
   1. body::before - pita aurora (juga cadangan tanpa WebGL);
   2. .water       - kanvas air: pita yang sama, dideformasi kursor;
   3. body::after  - butiran film, di atas semuanya supaya semuanya bergrain.
   Pita itu setinggi satu layar dan ikut tergulir; di bawahnya halaman bersih,
   jadi teks produk tidak pernah berbagi latar dengan aurora. Mask di ujung
   bawah membuat pita berakhir tanpa garis.

   Geometri lima lapis di bawah ini adalah salinan yang dipelihara bersama
   WASH di script.js; `node hub/tools/check.mjs` membandingkan keduanya. */
body::before,
.water {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  pointer-events: none;
  z-index: -1;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 58%, rgb(0 0 0 / 0) 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 58%, rgb(0 0 0 / 0) 100%);
}

/* Kanvas air. Ditampilkan hanya setelah frame pertama benar-benar tergambar
   (script.js yang memasang data-liquid), sehingga tidak ada frame kosong dan
   tidak ada permukaan WebGL sebelum airnya benar-benar diperlukan. */
.water { display: none; }
:root[data-liquid="on"] .water { display: block; }
:root[data-liquid="on"] body::before { display: none; }

body::before {
  content: "";
  background-image:
    radial-gradient(48rem 40rem at 2% 5%, rgb(var(--blob-sage) / var(--blob-alpha)), rgb(var(--blob-sage) / 0) 62%),
    radial-gradient(56rem 46rem at 38% -8%, rgb(var(--blob-cream) / var(--blob-alpha)), rgb(var(--blob-cream) / 0) 64%),
    radial-gradient(60rem 50rem at 99% 10%, rgb(var(--blob-peri) / var(--blob-alpha)), rgb(var(--blob-peri) / 0) 66%),
    radial-gradient(50rem 42rem at 80% 42%, rgb(var(--blob-lilac) / calc(var(--blob-alpha) * 0.9)), rgb(var(--blob-lilac) / 0) 64%),
    radial-gradient(46rem 38rem at 8% 50%, rgb(var(--blob-blush) / calc(var(--blob-alpha) * 0.9)), rgb(var(--blob-blush) / 0) 60%);
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: -1;
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

.wrap {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--btn-bg);
  color: var(--btn-ink);
  padding: 0.6rem 1rem;
}
.skip:focus { left: 0.75rem; top: 0.75rem; z-index: 3; }

.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.4rem 0.5rem;
}

/* Tap target 44px: diukur di sepuluh lebar viewport, brand cuma 39px tinggi dan
   itu berarti jempol meleset di HP. Tingginya dinaikkan lewat min-height, bukan
   lewat ukuran mark, jadi tampilannya tidak ikut membesar. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 44px;
  color: var(--ink);
  text-decoration: none;
}
.brand-mark {
  width: 30px;
  height: 30px;
  border-radius: 8px;
}
.wordmark {
  font-family: "Yeseva One", Georgia, serif;
  font-size: 1.35rem;
  letter-spacing: 0.01em;
  padding-bottom: 2px;
  border-bottom: 2px solid var(--brand-coral);
}

.toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-btn);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
}
.toggle:hover { border-color: var(--accent); }
.toggle-mark { width: 20px; height: 20px; fill: currentColor; }
.toggle-mark .rays { fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; }
/* Ikon menunjukkan aksi berikutnya: mode terang menampilkan bulan (menuju gelap),
   mode gelap menampilkan matahari (menuju terang). */
.toggle .i-sun { display: none; }
:root[data-theme="dark"] .toggle .i-sun { display: block; }
:root[data-theme="dark"] .toggle .i-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .toggle .i-sun { display: block; }
  :root:not([data-theme="light"]) .toggle .i-moon { display: none; }
}

/* Hero: satu kolom teks, dijangkarkan ke atas pita. Versi sebelumnya dipusatkan
   di dalam 62vh, dan itu membuatnya terbaca melayang di tengah bidang kosong.
   Tidak ada badge eyebrow di atas judul: label yang mengulang arti judul plus
   titik yang tidak menandai state apa pun.
   Padding bawah lebih kecil daripada atas dengan sengaja, supaya rak app naik
   ke dalam pita dan bagian bawah pita punya subjek, bukan cuma gradien. */
.hero {
  display: flex;
  flex-direction: column;
  min-height: clamp(18rem, 36vh, 27rem);
  padding-block: clamp(2.25rem, 6vh, 4rem) clamp(1rem, 2.5vh, 1.75rem);
}

.hero h1 {
  margin: 0;
  font-family: "Yeseva One", Georgia, serif;
  font-weight: 400;
  font-size: clamp(2.4rem, 5.6vw, 4rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  max-width: 20ch;
}
.lede {
  margin: 1.4rem 0 0;
  max-width: 42ch;
  font-size: 1.15rem;
  color: var(--ink-soft);
}

.apps { padding-block: 0; }

/* Halaman 404: tanpa pita tinggi, jadi tidak memakai .hero. */
.notfound { padding-block: 6rem 4rem; }
.notfound h1 {
  margin: 0;
  font-family: "Yeseva One", Georgia, serif;
  font-weight: 400;
  font-size: clamp(2.2rem, 5vw, 3.4rem);
  line-height: 1.08;
  max-width: 20ch;
}
.notfound .lede { margin-bottom: 1.8rem; }
.notfound .btn { margin-top: 0.4rem; }

.apps-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.3rem;
}
.label {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.rule {
  flex: 1;
  height: 1px;
  background: var(--line);
}
.count {
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--accent);
}

.card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: 2rem;
  align-items: center;
  padding: 1.75rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface);
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 1rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand-coral);
}

.card-title {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin: 0 0 0.85rem;
  font-family: "Yeseva One", Georgia, serif;
  font-weight: 400;
  font-size: 2rem;
}
.app-mark {
  width: 52px;
  height: 52px;
  border-radius: 12px;
}

.card-copy {
  margin: 0 0 1.6rem;
  max-width: 40ch;
  color: var(--ink-soft);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem 1.4rem;
  margin: 0;
}
.btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.7rem 1.2rem;
  border-radius: var(--radius-btn);
  background: var(--btn-bg);
  color: var(--btn-ink);
  font-weight: 700;
  text-decoration: none;
}
.btn:hover { background: var(--accent); color: #fff; }
:root[data-theme="dark"] .btn:hover { color: #080b14; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .btn:hover { color: #080b14; }
}
/* Sama: 27px tinggi sebelumnya. inline-flex + min-height 44px memberi kotak
   sentuh yang benar tanpa menggeser garis bawah teksnya. */
.link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.link:hover { color: var(--accent); }

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-shot);
}

.foot {
  margin-top: clamp(3.5rem, 8vh, 6rem);
  padding-block: 2rem 2.5rem;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.95rem;
}
.foot-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  color: var(--ink);
}
.foot-mark {
  width: 24px;
  height: 24px;
  border-radius: 7px;
}
.foot-word {
  font-family: "Yeseva One", Georgia, serif;
  font-size: 1.1rem;
}
.foot-line {
  margin: 0.9rem 0 0;
  max-width: 34ch;
}
/* Tautan footer adalah navigasi berdiri sendiri, bukan tautan di tengah
   kalimat, jadi ambang 44px berlaku: sebelumnya tingginya 24px, dan "Terms"
   cuma 36px lebar. Kotak sentuhnya dilebarkan lewat padding, lalu jarak antar
   tautan dikurangi sebanyak itu dan barisnya ditarik ke kiri sebanyak itu,
   sehingga tepi kiri teks tetap sejajar dengan kolom dan dengan brand di
   atasnya. Padding itu yang membuat "Terms" melewati 44px di kedua sumbu. */
.foot-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.75rem;
  margin: 0.9rem 0 0 -0.65rem;
}
.foot-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 0.65rem;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.foot-links a:hover { color: var(--accent); }
.foot-year { margin: 1.6rem 0 0; font-size: 0.9rem; }

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

@media (max-width: 880px) {
  .hero {
    min-height: 0;
    padding-block: 2rem 1.5rem;
  }
}

@media (max-width: 720px) {
  .card { grid-template-columns: minmax(0, 1fr); gap: 1.5rem; padding: 1.25rem; }
  .shot { order: -1; }
  .card-copy { max-width: none; }
}

@media (prefers-reduced-motion: no-preference) {
  body, .toggle, .btn, .link, .foot-links a {
    transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease;
  }
}

/* Gerak yang tidak diminta berhenti sepenuhnya. Air tidak dimulai sama sekali
   oleh script.js (bukan cuma disembunyikan), dan pita aurora statis yang tampil. */
@media (prefers-reduced-motion: reduce) {
  .water { display: none; }
}

/* Tanpa penunjuk presisi tidak ada kursor untuk menggerakkan air. */
@media (hover: none) {
  .water { display: none; }
}
