/* ===========================================================================
   Simulator aliran energi — sistem hybrid dan off-grid.

   Diagram ini KUALITATIF. Ia menunjukkan arah, kehadiran, dan prioritas
   aliran energi, bukan nilai kW. Alasannya bukan kemalasan: docs/ hanya
   memuat agregat (master-reference-plts.md B3 memberi "70%+ pukul 07–17",
   manual-plts-v1.2.md A1.1 memberi PSH harian), tidak ada kurva 24 titik.
   Menggambar angka per jam berarti mengarangnya — dilarang CLAUDE.md §0.5.

   Karena itu berkas ini tidak memuat satu pun angka teknis (INV-11).
   Seluruh nilainya adalah geometri dan waktu animasi.

   PENAMAAN. Awalan .flow-sim__, bukan .flow__. Dua komponen lain sudah
   memakai .flow__: rangkaian langkah di beranda (sections.css) dan batang
   self-consumption di kalkulator (kalkulator.css). Menumpang awalan yang
   sama akan merusak keduanya.

   Struktur: simpul adalah elemen HTML (teks nyata, ikut ukuran font
   pengguna, terbaca screen reader), kawat adalah SVG di belakangnya.
   Keduanya berbagi sistem koordinat lewat aspect-ratio tetap pada
   .flow-sim__stage, sehingga posisi persen HTML jatuh persis di ujung path.
   =========================================================================== */

.flow-sim {
  /* --- Bahasa warna ------------------------------------------------------
     Serumpun dengan batang "Ke mana perginya produksi panel Anda" di
     kalkulator: kuning-jingga untuk energi surya, biru untuk energi yang
     lewat baterai. Tingkat terangnya berbeda karena latarnya berbeda —
     batang kalkulator duduk di blok biru gelap dan memakai be-sun-300 /
     be-blue-300, sedangkan diagram ini duduk di latar terang sehingga
     nuansa yang sama harus digelapkan agar tetap terbaca. Rona sengaja
     dipertahankan supaya pengunjung mengenali kode warna yang sama di
     dua halaman (INV-3, konsistensi antar-permukaan).

     Warna bukan satu-satunya pembawa makna di sini: setiap kawat
     menghubungkan dua simpul yang sudah berlabel teks, dan keterangan di
     bawah diagram menyatakan keadaannya dengan kalimat. */
  --flow-surya: var(--be-sun-600);
  --flow-beban: var(--be-sun-500);
  --flow-baterai: var(--be-blue-500);
  --flow-pln: var(--ink-400);
  --flow-track: var(--ink-100);

  /* Jingga bergaris di kalkulator menandai energi terbuang. Di sini efeknya
     dicapai lewat gradasi memudar, karena garis miring tidak terbaca pada
     goresan setipis ini. Rona sun-500 sengaja sama persis. */
  --flow-buang: var(--be-sun-500);

  --flow-node-w: 27%;
  --flow-dur: 2.4s;
  --flow-stroke: 6;
  --flow-stroke-lemah: 3;

  max-width: 46rem;
  margin-inline: auto;
}

/* --- Panggung ------------------------------------------------------------
   aspect-ratio mengunci rasio ke viewBox SVG (500 × 400). Tanpa ini,
   simpul HTML yang diposisikan dengan persen akan meleset dari ujung
   kawat begitu lebar kontainer berubah. */
.flow-sim__stage {
  position: relative;
  aspect-ratio: 5 / 4;
  container-type: inline-size;
}

.flow-sim__wires {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* --- Kawat ---------------------------------------------------------------
   Dua lapis per rute: track yang selalu terlihat (menyatakan sambungan
   fisik ada) dan pulse yang bergerak (menyatakan energi sedang mengalir).
   Pemisahan inilah yang membuat "PLN tersambung tetapi tidak dipakai" dapat
   dibedakan dari "PLN diputus inverter". */
.flow-sim__track {
  fill: none;
  stroke: var(--flow-track);
  stroke-width: 10;
  stroke-linecap: round;
}

.flow-sim__pulse {
  fill: none;
  stroke-width: var(--flow-stroke);
  stroke-linecap: round;
  stroke-dasharray: 14 22;
  animation: flow-sim-drift var(--flow-dur) linear infinite;
}

/* Arah animasi menyatakan arah energi: pulsa bergerak mengikuti arah path
   digambar. Pembalikannya diatur animation-direction pada mode "balik". */
@keyframes flow-sim-drift {
  to { stroke-dashoffset: -36; }
}

.flow-sim__pulse[data-wire="surya"] { stroke: var(--flow-surya); }
.flow-sim__pulse[data-wire="beban"] { stroke: var(--flow-beban); }
.flow-sim__pulse[data-wire="baterai"] { stroke: var(--flow-baterai); }
.flow-sim__pulse[data-wire="pln"] { stroke: var(--flow-pln); }

/* --- Keadaan ------------------------------------------------------------
   Digerakkan atribut data-mode yang dipasang flow-sim.js per elemen, bukan
   kombinasi selektor [data-state] × [data-wire]. Menambah keadaan baru cukup
   menambah entri di peta SISTEM pada flow-sim.js plus keterangannya di
   tools/content/; berkas ini tidak perlu ikut berubah. */
.flow-sim__pulse[data-mode="diam"],
.flow-sim__pulse[data-mode="putus"] { opacity: 0; }

/* Baterai melepas, bukan mengisi: aliran yang sama dibalik arahnya. */
.flow-sim__pulse[data-mode="balik"] { animation-direction: reverse; }

/* Produksi lemah: goresan menipis dan alirannya melambat. Keduanya
   perbandingan relatif terhadap keadaan penuh, bukan pernyataan besaran. */
.flow-sim__pulse[data-mode="lemah"] {
  stroke-width: var(--flow-stroke-lemah);
  animation-duration: calc(var(--flow-dur) * 2);
}

/* --- Energi terbuang -----------------------------------------------------
   Satu-satunya rute yang tidak berujung di simpul mana pun. Gradasinya
   memudar sampai tembus pandang, sehingga alirannya terlihat kehilangan
   tujuan alih-alih sampai ke suatu tempat. */
.flow-sim__pulse--buang {
  stroke: url(#flow-sim-buang);
  stroke-dasharray: 10 16;
}

.flow-sim__buang-awal {
  stop-color: var(--flow-buang);
  stop-opacity: 0.95;
}

.flow-sim__buang-akhir {
  stop-color: var(--flow-buang);
  stop-opacity: 0;
}

/* Gradasi punya id sendiri per halaman karena id SVG wajib unik. */
.flow-sim__pulse--buang-offgrid { stroke: url(#flow-sim-buang-offgrid); }

/* --- Isi bank baterai ----------------------------------------------------
   Tiga batang berundak, bukan persentase. Batas DoD yang sesungguhnya
   tinggal di plts-constants.js dan tidak boleh digandakan sebagai posisi
   grafis di sini (INV-11). Yang disampaikan hanya arah perubahannya.

   Dipakai off-grid saja. Pada hybrid keadaan baterai tidak menentukan nasib
   rumah karena PLN selalu menjadi lapis terakhir. */
.flow-sim [data-soc="sedang"] [data-soc-level="3"],
.flow-sim [data-soc="rendah"] [data-soc-level="3"],
.flow-sim [data-soc="rendah"] [data-soc-level="2"],
.flow-sim [data-soc="kritis"] [data-soc-level="3"],
.flow-sim [data-soc="kritis"] [data-soc-level="2"] { opacity: 0; }

/* Batang terakhir berubah merah, dan simpulnya ikut ditegaskan. Warna bukan
   satu-satunya penanda: jumlah batang yang tersisa sudah menyatakan hal yang
   sama, dan keterangan di bawah diagram menyebutnya dengan kalimat. */
.flow-sim [data-soc="kritis"] [data-soc-level="1"] { stroke: var(--danger); }

.flow-sim__node[data-soc="kritis"] { border-color: var(--danger); }

.flow-sim__ghost {
  position: absolute;
  left: var(--x);
  top: var(--y);
  translate: -50% -50%;
  margin: 0;
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  /* be-sun-700: satu-satunya nuansa surya yang lolos AA pada latar terang
     (tokens.css mencatatnya 5,55:1). */
  color: var(--be-sun-700);
  white-space: nowrap;
}

.flow-sim__ghost[data-mode="diam"] {
  opacity: 0;
  visibility: hidden;
}

/* Rute yang terputus tetap digambar. Menghapusnya akan menyiratkan kabelnya
   hilang, padahal yang terjadi adalah inverter memutus sambungan. */
.flow-sim__track[data-mode="putus"] {
  stroke-dasharray: 7 13;
  opacity: 0.6;
}

/* Simpul yang sedang tidak mengalirkan energi ditandai lewat permukaan dan
   garis tepinya, BUKAN dengan meredupkan seluruh kotak. Menurunkan opacity
   kotak ke 55% menjatuhkan label ke 4,15:1 dan catatan ke 2,91:1 — keduanya
   di bawah WCAG AA. Yang boleh diredupkan hanya ikonnya, karena maknanya
   sudah dibawa teks di bawahnya. */
.flow-sim__node[data-mode="diam"],
.flow-sim__node[data-mode="putus"] {
  background: var(--bg-alt);
  border-style: dashed;
  box-shadow: none;
}

.flow-sim__node[data-mode="diam"] .flow-sim__icon,
.flow-sim__node[data-mode="putus"] .flow-sim__icon { opacity: 0.45; }

@media (prefers-reduced-motion: no-preference) {
  .flow-sim__node {
    transition: background-color var(--dur-normal, 260ms) ease,
                border-color var(--dur-normal, 260ms) ease;
  }
  .flow-sim__track { transition: opacity var(--dur-normal, 260ms) ease; }
  .flow-sim__icon { transition: opacity var(--dur-normal, 260ms) ease; }
}

/* --- Penanda putus -------------------------------------------------------
   Hanya muncul saat sambungan ke jaringan benar-benar diputus. Bentuk silang
   di dalam cakram, bukan sekadar warna, supaya tetap terbaca tanpa persepsi
   warna yang utuh. */
.flow-sim__break {
  opacity: 0;
  visibility: hidden;
}

.flow-sim[data-state="padam"] .flow-sim__break {
  opacity: 1;
  visibility: visible;
}

.flow-sim__break-disc {
  fill: var(--surface);
  stroke: var(--danger);
  stroke-width: 2;
}

.flow-sim__break-mark {
  fill: none;
  stroke: var(--danger);
  stroke-width: 2.5;
  stroke-linecap: round;
}

/* --- Geometri simpul ------------------------------------------------------
   --x dan --y adalah titik pusat simpul dalam persen panggung.

   Nilainya dulu ditulis sebagai atribut style= di markup, supaya duduk
   berdampingan dengan koordinat path SVG. Itu tidak dapat dipertahankan:
   Content-Security-Policy situs ini tidak memuat 'unsafe-inline' pada
   style-src, jadi peramban menolak seluruh atribut itu di produksi dan
   kelima simpul menumpuk di pojok kiri atas — tanpa satu pun galat yang
   terlihat, persis seperti yang diperingatkan komentar di .htaccess.

   Kedua diagram memakai simpul yang sama dengan tata letak berbeda, jadi
   koordinatnya dikunci pada data-flow-sim di wadahnya. Menambah diagram
   ketiga berarti menambah satu blok di sini, bukan style= di markup. */

[data-flow-sim="hybrid"] .flow-sim__node--surya   { --x: 16%; --y: 16%; }
[data-flow-sim="hybrid"] .flow-sim__node--pln     { --x: 16%; --y: 82%; }
[data-flow-sim="hybrid"] .flow-sim__node--hub     { --x: 48%; --y: 50%; }
[data-flow-sim="hybrid"] .flow-sim__node--rumah   { --x: 84%; --y: 50%; }
[data-flow-sim="hybrid"] .flow-sim__node--baterai { --x: 48%; --y: 84%; }
[data-flow-sim="hybrid"] .flow-sim__ghost         { --x: 70%; --y: 20%; }

[data-flow-sim="offgrid"] .flow-sim__node--surya   { --x: 16%; --y: 22%; }
[data-flow-sim="offgrid"] .flow-sim__node--hub     { --x: 48%; --y: 50%; }
[data-flow-sim="offgrid"] .flow-sim__node--rumah   { --x: 84%; --y: 50%; }
[data-flow-sim="offgrid"] .flow-sim__node--baterai { --x: 48%; --y: 84%; }
[data-flow-sim="offgrid"] .flow-sim__ghost         { --x: 70%; --y: 20%; }

/* --- Simpul ------------------------------------------------------------- */
.flow-sim__node {
  position: absolute;
  left: var(--x);
  top: var(--y);
  translate: -50% -50%;
  width: var(--flow-node-w);
  display: grid;
  justify-items: center;
  gap: 0.35rem;
  padding: 0.7rem 0.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  box-shadow: 0 1px 2px rgb(6 11 22 / 0.06), 0 8px 20px -12px rgb(6 11 22 / 0.28);
  text-align: center;
}

.flow-sim__icon {
  width: 1.5rem;
  height: 1.5rem;
  stroke-width: 1.75;
  fill: none;
  stroke: var(--text-muted);
}

.flow-sim__label {
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text);
}

.flow-sim__note {
  font-family: var(--font-ui);
  font-size: 0.6875rem;
  line-height: 1.3;
  color: var(--text-faint);
}

/* Inverter adalah pusat kendali, bukan sekadar salah satu kotak. Ia
   mendapat bobot visual lebih besar supaya hierarkinya terbaca tanpa
   perlu dijelaskan lewat teks. */
.flow-sim__node--hub {
  --flow-node-w: 30%;
  border-color: var(--accent);
  box-shadow: 0 1px 2px rgb(7 44 189 / 0.10), 0 12px 28px -14px rgb(7 44 189 / 0.45);
}

.flow-sim__node--hub .flow-sim__icon { stroke: var(--accent); }

.flow-sim__node--surya .flow-sim__icon { stroke: var(--flow-surya); }
.flow-sim__node--baterai .flow-sim__icon { stroke: var(--flow-baterai); }

/* --- Kontrol -------------------------------------------------------------
   Disembunyikan tanpa JavaScript: tombol yang tidak melakukan apa pun lebih
   membingungkan daripada tombol yang tidak ada. Diagram tetap bermakna pada
   keadaan bawaannya. */
.flow-sim__controls { display: none; }

.has-js .flow-sim__controls {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
  margin-top: 1.25rem;
}

.flow-sim__btn {
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-muted);
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
}

/* Lihat catatan bidang sentuh di assets/css/components.css. Tombol keadaan pada
   diagram ini termasuk yang paling sering disentuh di halaman sistem, dan
   tingginya 34px. */
@media (pointer: coarse) {
  .flow-sim__btn { min-height: 44px; }
}

@media (prefers-reduced-motion: no-preference) {
  .flow-sim__btn { transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease; }
}

.flow-sim__btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.flow-sim__btn:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* Keadaan terpilih dinyatakan lewat aria-pressed, bukan kelas tambahan:
   satu sumber kebenaran untuk mata dan untuk pembaca layar sekaligus. */
.flow-sim__btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--text-invert);
}

/* Tombol pemadaman diberi bobot berbeda karena itulah pertanyaan yang paling
   sering menahan calon pelanggan. */
.flow-sim__btn--padam[aria-pressed="true"] {
  border-color: var(--danger);
  background: var(--danger);
}

.flow-sim__btn--padam:hover:not([aria-pressed="true"]) {
  border-color: var(--danger);
  color: var(--danger);
}

/* --- Keterangan state ----------------------------------------------------
   Padanan teks dari yang digambar. Bukan pelengkap: inilah yang dibaca
   screen reader dan perayap mesin telusur, dan inilah yang tersisa bila
   CSS gagal dimuat. */
/* --- Ajakan kontekstual --------------------------------------------------
   Terikat pada satu keadaan. Tanpa JavaScript ia tampil sekali sebagai
   ajakan biasa di bawah daftar keterangan, jadi tidak ada yang hilang. */
.flow-sim__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem 1.25rem;
  margin-top: 1.25rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--be-sun-100);
  border-radius: 0.7rem;
  background: var(--paper-warm);
}

.has-js .flow-sim__cta { display: none; }
.has-js .flow-sim__cta.is-active { display: flex; }

.flow-sim__cta-teks {
  flex: 1 1 18rem;
  margin: 0;
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--text-muted);
  text-wrap: pretty;
}

/* --- Angka milik pengunjung ----------------------------------------------
   Hanya tampil bila ia baru memakai kalkulator pada sesi yang sama, jadi
   sebagian besar pengunjung tidak akan pernah melihatnya. Diberi permukaan
   sendiri supaya terbaca sebagai "ini punya Anda", bukan sebagai angka umum
   yang berlaku bagi semua orang. */
.flow-sim__anda {
  margin: 1.25rem 0 0;
  padding: 0.8rem 1rem;
  border: 1px solid var(--be-sun-100);
  border-radius: 0.7rem;
  background: var(--paper-warm);
  font-family: var(--font-ui);
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--text-muted);
  text-align: center;
  text-wrap: pretty;
}

.flow-sim__anda[hidden] { display: none; }

.flow-sim__anda b {
  color: var(--be-sun-700);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.flow-sim__captions {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  font-family: var(--font-ui);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--text-muted);
  text-align: center;
  text-wrap: pretty;
}

.flow-sim__caption { margin: 0 0 0.75rem; }
.flow-sim__caption:last-child { margin-bottom: 0; }
.flow-sim__caption strong { color: var(--text); }

/* Tanpa JavaScript keenam keterangan tampil sebagai daftar, sehingga seluruh
   isi edukasinya tetap sampai. Dengan JavaScript hanya yang aktif yang
   ditampilkan, dan ruang cadangan menjaga isi halaman di bawahnya tidak
   melompat setiap kali keadaan berganti. */
.has-js .flow-sim__captions { min-height: 7.5em; }
.has-js .flow-sim__caption { display: none; }
.has-js .flow-sim__caption.is-active { display: block; }

/* --- Ruang sempit --------------------------------------------------------
   Di bawah 30rem simpul saling berdesakan. Yang dikorbankan adalah
   keterangan sekunder, bukan label utamanya. */
@container (max-width: 30rem) {
  .flow-sim__note { display: none; }

  .flow-sim__node {
    padding: 0.5rem 0.35rem;
    border-radius: 0.7rem;
  }

  .flow-sim__label { font-size: 0.6875rem; }
  .flow-sim__icon { width: 1.15rem; height: 1.15rem; }
}

/* --- Gerak berkurang -----------------------------------------------------
   Aliran berhenti, tetapi kawatnya tetap berwarna penuh. Pengguna yang
   menolak animasi tetap melihat rute mana yang aktif — informasinya tidak
   ikut hilang bersama geraknya. */
@media (prefers-reduced-motion: reduce) {
  .flow-sim__pulse {
    animation: none;
    stroke-dasharray: none;
  }
}
