/* =====================================================================
   Playtime MAIN — sistem reka bentuk
   =====================================================================
   Susunan: token → asas → susun atur → komponen → skrin khusus.
   Semua kelas berawalan .pt- supaya tidak berlanggar dengan apa-apa lagi.
   ===================================================================== */

:root {
  /* Jenama */
  --purple: #5d2fa5;
  --purple-2: #7c48c5;
  --purple-soft: #f4efFB;
  --plum: #241044;
  --yellow: #ffe252;
  --coral: #ff785a;
  --pink: #ffc8df;
  --sky: #b9e5ff;
  --mint: #c9f1df;

  /* Neutral */
  --paper: #fbfaf7;
  --card: #ffffff;
  --ink: #241a2e;
  --ink-2: #4a4155;
  --muted: #746c80;
  --line: #e8e3ee;
  --line-2: #f1eef5;

  /* Semantik */
  --ok-bg: #e4f6ec;      --ok-ink: #14663f;   --ok-line: #bfe7d1;
  --warn-bg: #fff4d6;    --warn-ink: #855100;  --warn-line: #f5dfa6;
  --stop-bg: #fdeaee;    --stop-ink: #9c2138;  --stop-line: #f4ccd5;

  /* Ruang */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-7: 32px; --sp-8: 44px;

  /* Bentuk */
  --r-sm: 10px; --r-md: 14px; --r-lg: 18px; --r-xl: 24px; --r-pill: 999px;

  /* Bayang */
  --sh-1: 0 1px 2px rgba(36, 16, 68, .06), 0 4px 12px rgba(36, 16, 68, .05);
  --sh-2: 0 2px 6px rgba(36, 16, 68, .07), 0 12px 32px rgba(36, 16, 68, .08);
  --sh-3: 0 18px 48px rgba(36, 16, 68, .14);

  /* Lebar kandungan */
  --w-narrow: 560px;
  --w-wide: 1120px;

  --font-display: "Plus Jakarta Sans", "Segoe UI", Arial, sans-serif;
  --font-body: "Nunito Sans", "Segoe UI", Arial, sans-serif;
}

/* ---------------------------------------------------------------- asas */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;

  /* Bar atas melekat, jadi tanpa ini setiap pautan #bahagian mendaratkan
     tajuk bahagian itu DI BAWAH bar dan pengguna melihat pertengahannya.
     Nilai ini melepasi kepala (60px) berserta baris nav muka depan. */
  scroll-padding-top: 104px;

  /* TIADA scroll-behavior: smooth di sini, dan itu disengajakan.
     Ia dicuba sekali: dalam persekitaran yang tidak menjalankan animasi
     tatalan, lompatan itu langsung TIDAK berlaku — pautan #bahagian
     menukar URL dan berhenti di situ. Lompatan serta-merta sentiasa
     berfungsi; kelicinan tidak berbaloi dengan pautan yang mati. */
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--plum);
  letter-spacing: -0.022em;
  margin: 0;
}

p { margin: 0; }

a { color: var(--purple); text-decoration-thickness: 1px; text-underline-offset: 2px; }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid rgba(93, 47, 165, .35);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ----------------------------------------------------------- susun atur */

.pt-page { display: flex; flex-direction: column; min-height: 100vh; }

/* Bar atas melekat. Sama pada setiap skrin supaya pengguna sentiasa tahu
   di mana mereka berada dan bagaimana untuk berundur. */
.pt-head {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(251, 250, 247, .88);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line-2);
}
.pt-head-in {
  width: min(var(--w-wide), calc(100% - var(--sp-6)));
  margin: 0 auto;
  min-height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
}
.pt-brand {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.04em;
  color: var(--plum);
  text-decoration: none;
}
.pt-brand-mark {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--purple), var(--purple-2));
  color: #fff;
  font-size: 14px;
  font-weight: 800;
}
.pt-brand i { font-style: normal; color: var(--coral); }

.pt-back {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 38px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--card);
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  transition: border-color .15s, color .15s;
}
.pt-back:hover { border-color: var(--purple-2); color: var(--purple); }

.pt-main { flex: 1; padding: var(--sp-6) 0 var(--sp-8); }
.pt-wrap { width: min(var(--w-narrow), calc(100% - var(--sp-6))); margin: 0 auto; }
.pt-wrap-lebar { width: min(var(--w-wide), calc(100% - var(--sp-6))); margin: 0 auto; }

.pt-foot {
  border-top: 1px solid var(--line-2);
  padding: var(--sp-5) 0;
  color: var(--muted);
  font-size: 12.5px;
}
.pt-foot-in {
  width: min(var(--w-wide), calc(100% - var(--sp-6)));
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-5);
  align-items: center;
  justify-content: space-between;
}

/* ------------------------------------------------------------ tipografi */

.pt-h1 { font-size: clamp(23px, 2.4vw, 28px); line-height: 1.2; }
.pt-h2 { font-size: 18px; line-height: 1.3; }
.pt-h3 { font-size: 15px; line-height: 1.35; }
.pt-lead { color: var(--ink-2); font-size: 15px; margin-top: var(--sp-2); }
.pt-meta { color: var(--muted); font-size: 13px; }
.pt-hint { color: var(--muted); font-size: 12.5px; line-height: 1.5; }
.pt-error { color: var(--stop-ink); font-size: 13px; font-weight: 700; }

.pt-kicker {
  display: block;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--purple);
}

.pt-stack { display: grid; gap: var(--sp-4); }
.pt-stack-sm { display: grid; gap: var(--sp-2); }
.pt-row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.pt-mt { margin-top: var(--sp-4); }
.pt-mt-lg { margin-top: var(--sp-6); }

/* ------------------------------------------------------------- komponen */

.pt-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: var(--sp-5);
  box-shadow: var(--sh-1);
}
.pt-card-pad-sm { padding: var(--sp-4); }

/* Jarak antara kad yang BERTINDAN menegak. */
.pt-card + .pt-card { margin-top: var(--sp-4); }

/* ...tetapi bukan apabila kad duduk BERSEBELAHAN dalam grid.
 *
 * Peraturan adik-beradik di atas tidak tahu arah susunan, jadi kad kedua
 * dalam satu baris grid turut menerima margin-top dan terdorong 16px ke
 * bawah. Kesannya bukan sekadar jarak: grid meregangkan kad pertama 16px
 * lebih tinggi untuk mengisi baris, jadi dua kad bersebelahan berakhir
 * dengan tinggi berbeza dan tepi atas yang tidak sejajar.
 *
 * Jurang antara kad sudah dikendalikan oleh `gap` bekas itu sendiri.
 *
 * Hanya .pt-fakta disenaraikan kerana hanya ia yang benar-benar
 * mengandungi .pt-card sebagai anak terus hari ini — .pt-grid membawa
 * .pt-listing dan .pt-panel-lajur membawa .pt-panel. Mana-mana bekas
 * baharu yang meletakkan kad bersebelahan perlu ditambah di sini. */
.pt-fakta > .pt-card + .pt-card { margin-top: 0; }

.pt-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  width: fit-content;          /* jangan terbentang dalam grid */
  max-width: 100%;
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--purple-soft);
  border: 1px solid transparent;
  color: var(--purple);
  font-size: 11.5px;
  font-weight: 800;
  line-height: 1.5;
  white-space: nowrap;
}
.pt-chip-ok { background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-ink); }
.pt-chip-warn { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn-ink); }
.pt-chip-stop { background: var(--stop-bg); border-color: var(--stop-line); color: var(--stop-ink); }

.pt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  width: 100%;
  min-height: 50px;
  padding: 0 var(--sp-5);
  border: 1.5px solid transparent;
  border-radius: var(--r-md);
  background: var(--purple);
  color: #fff;
  font-size: 15px;
  font-weight: 800;
  text-decoration: none;
  transition: background .15s, transform .06s, box-shadow .15s;
  box-shadow: var(--sh-1);
}
.pt-btn:hover { background: var(--purple-2); }
.pt-btn:active { transform: translateY(1px); }
.pt-btn[disabled], .pt-btn.is-mati { opacity: .5; pointer-events: none; }
.pt-btn-2 { background: var(--card); color: var(--plum); border-color: var(--line); box-shadow: none; }
.pt-btn-2:hover { background: var(--purple-soft); border-color: var(--purple-2); }
.pt-btn-danger { background: var(--card); color: var(--stop-ink); border-color: var(--stop-line); box-shadow: none; }
.pt-btn-danger:hover { background: var(--stop-bg); }
.pt-btn-auto { width: auto; }

/* Medan borang */
.pt-field { display: grid; gap: 6px; }
.pt-field > label {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-2);

  /* Tinggi label DIKUNCI kepada satu baris.

     Dua medan bersebelahan dalam .pt-dua ialah dua sel grid yang bebas,
     jadi inputnya hanya sebaris kalau label di atasnya sama tinggi.
     Sebaik sahaja satu label membawa teks bersaiz lain — "(pilihan)"
     dalam .pt-hint, misalnya — kotak barisnya membesar dan inputnya
     tersorong beberapa piksel berbanding jirannya. */
  line-height: 1.35;
  min-height: 1.35em;
}

/* Nota kecil DALAM label mewarisi saiz dan line-height label, supaya ia
   tidak pernah menukar tinggi baris itu. Huruf kecil sengaja: "TELEFON
   (pilihan)" membezakan nota daripada nama medan, sedangkan
   "TELEFON (PILIHAN)" membacanya sebagai satu nama panjang. */
.pt-field > label .pt-hint {
  font-size: inherit;
  line-height: inherit;
  font-weight: 700;
  letter-spacing: normal;
  text-transform: none;
}
.pt-input, .pt-select, .pt-textarea {
  width: 100%;
  min-height: 50px;
  padding: 0 var(--sp-4);
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
  font-size: 15px;
  transition: border-color .15s, box-shadow .15s;
}
.pt-textarea { min-height: 92px; padding: var(--sp-3) var(--sp-4); font-family: inherit; resize: vertical; }

/* Pemilih melukis anak panahnya sendiri.

   Anak panah lalai pelayar diletak rapat pada tepi kotak, dan dengan
   width:auto ia hampir menyentuh sempadan — ketara pada pemilih pendek
   seperti penapis status. Ia juga berbeza rupa antara Chrome, Safari dan
   Firefox, jadi satu-satunya kawalan dalam sistem ini yang tidak
   kelihatan seperti yang lain.

   appearance:none membuang anak panah itu; SVG di bawah menggantikannya
   dengan jarak yang betul daripada sempadan. Ruang untuknya ditempah
   melalui padding-right supaya teks panjang tidak menyelinap di
   belakangnya. */
select.pt-input,
.pt-select,
.pt-jadual-saiz {
  appearance: none;
  -webkit-appearance: none;
  padding-right: calc(var(--sp-4) + 16px);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23746c80' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--sp-3) center;
  cursor: pointer;
}
/* Pemilih saiz halaman lebih kecil daripada medan borang, jadi ruang
   untuk anak panah dikira semula daripada paddingnya sendiri. */
.pt-jadual-saiz { padding-right: calc(var(--sp-3) + 16px); }
.pt-input:hover, .pt-select:hover, .pt-textarea:hover { border-color: #d9d1e3; }
.pt-input:focus, .pt-select:focus, .pt-textarea:focus {
  border-color: var(--purple-2);
  box-shadow: 0 0 0 3px rgba(93, 47, 165, .12);
  outline: none;
}
.pt-select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235d2fa5' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--sp-4) center;
  padding-right: var(--sp-8);
}
.pt-field-bad .pt-input, .pt-field-bad .pt-select, .pt-field-bad .pt-textarea { border-color: var(--stop-line); }

.pt-prefix {
  display: grid;
  place-items: center;
  flex: 0 0 62px;
  min-height: 50px;
  border: 1.5px solid var(--line);
  border-right: 0;
  border-radius: var(--r-md) 0 0 var(--r-md);
  background: var(--purple-soft);
  color: var(--purple);
  font-weight: 800;
}
.pt-prefix + .pt-input { border-radius: 0 var(--r-md) var(--r-md) 0; }

/* Pilihan berbentuk butang (umur, kaedah bayaran) */
.pt-opts { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.pt-opt {
  position: relative;
  flex: 1 1 0;
  min-width: 72px;
  min-height: 50px;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}
.pt-opt:hover { border-color: var(--purple-2); }
.pt-opt.is-on {
  border-color: var(--purple);
  border-width: 2px;
  background: var(--purple-soft);
  color: var(--purple);
}
.pt-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.pt-opt-wide { flex-basis: 100%; }

.pt-check {
  display: flex;
  gap: var(--sp-3);
  align-items: flex-start;
  font-size: 13px;
  color: var(--ink-2);
  line-height: 1.55;
  cursor: pointer;
}
.pt-check input { width: 20px; height: 20px; margin-top: 2px; accent-color: var(--purple); flex: 0 0 20px; }

/* Nota / amaran */
.pt-note {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-lg);
  border: 1px solid transparent;
  background: var(--purple-soft);
  color: var(--plum);
  font-size: 13px;
  line-height: 1.55;
}
.pt-note-warn { background: var(--warn-bg); border-color: var(--warn-line); color: var(--warn-ink); }
.pt-note-stop { background: var(--stop-bg); border-color: var(--stop-line); color: var(--stop-ink); }
.pt-note-ok { background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-ink); }

/* Senarai pasangan kunci-nilai */
.pt-summary { display: grid; gap: var(--sp-2); font-size: 14px; }
.pt-summary > div { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-4); }
.pt-summary .k { color: var(--muted); flex: 0 0 auto; }
.pt-summary .v { font-weight: 700; color: var(--plum); text-align: right; }
.pt-summary .pt-baris-jumlah { border-top: 1px solid var(--line-2); padding-top: var(--sp-3); margin-top: var(--sp-1); }

.pt-price {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 800;
  color: var(--purple);
  letter-spacing: -0.035em;
  white-space: nowrap;
}
.pt-price small { display: block; font-family: var(--font-body); font-size: 11px; font-weight: 600; color: var(--muted); letter-spacing: 0; }

.pt-ref {
  font-family: ui-monospace, "Cascadia Mono", Menlo, monospace;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--plum);
}

/* Langkah borang */
.pt-steps { display: flex; gap: var(--sp-3); margin-bottom: var(--sp-5); }
.pt-step { flex: 1; display: grid; gap: 6px; }
.pt-step i { display: block; height: 4px; border-radius: var(--r-pill); background: var(--line); }
.pt-step span { font-size: 11.5px; font-weight: 700; color: var(--muted); }
.pt-step.is-on i { background: var(--purple); }
.pt-step.is-on span { color: var(--purple); }

/* Keadaan kosong */
.pt-empty { text-align: center; padding: var(--sp-7) var(--sp-5); }
.pt-empty-mark {
  display: grid;
  place-items: center;
  width: 52px; height: 52px;
  margin: 0 auto var(--sp-3);
  border-radius: var(--r-lg);
  background: var(--purple-soft);
  color: var(--purple);
  font-size: 22px;
}

/* --------------------------------------------------- P-02 hasil carian */

.pt-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
}

/* Grid hasil carian.
 *
 * Lajur berlebar TETAP dan digrid ke TENGAH, bukan tiga lajur 1fr.
 *
 * Dengan repeat(3, 1fr), satu hasil carian menghasilkan satu kad kurus di
 * hujung kiri dan dua pertiga skrin kosong di sebelahnya — halaman
 * kelihatan rosak, sedangkan carian itu berjaya. Poskod dengan satu centre
 * ialah kes BIASA pada fasa rintis, bukan kes tepi.
 *
 * Lebar tetap bermakna kad kelihatan sama pada satu hasil atau lapan, dan
 * justify-content memusatkan barisan yang tidak penuh. */
.pt-grid {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(290px, 340px));
  justify-content: center;
  margin-top: var(--sp-4);
}

.pt-listing {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  overflow: hidden;
  box-shadow: var(--sh-1);
  color: inherit;
  text-decoration: none;
  transition: transform .15s, box-shadow .15s, border-color .15s;
}
a.pt-listing:hover {
  transform: translateY(-2px);
  box-shadow: var(--sh-2);
  border-color: #ddd4e8;
}
.pt-listing-foto {
  position: relative;
  height: 118px;
  display: grid;
  place-items: center;
  background: linear-gradient(140deg, var(--yellow), #ffc957);
  color: var(--purple);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .1em;
}
.pt-foto-2 { background: linear-gradient(140deg, var(--pink), #ff9ec4); }
.pt-foto-3 { background: linear-gradient(140deg, var(--sky), #7fc9ff); }
.pt-listing-foto .pt-chip {
  position: absolute;
  left: var(--sp-3);
  top: var(--sp-3);
  background: rgba(255, 255, 255, .94);
  border-color: transparent;
  color: var(--ok-ink);
  box-shadow: var(--sh-1);
}
.pt-listing-body { padding: var(--sp-4); display: grid; gap: 3px; }
.pt-listing-nama { font-family: var(--font-display); font-size: 17px; font-weight: 800; color: var(--plum); letter-spacing: -.02em; }
/* Sesi pagi dan petang di dalam kad centre. Baki slot ditunjukkan di sini
   supaya parent tahu hari itu masih terbuka tanpa membuka butiran. */
.pt-listing-sesi { list-style: none; margin: var(--sp-3) 0 0; padding: 0; display: grid; gap: 5px; }
.pt-listing-sesi li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--paper);
  font-size: 13px;
  font-weight: 700;
  color: var(--plum);
}

.pt-listing-foot {
  margin-top: auto;
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-3);
}
.pt-off { opacity: .58; }

/* --------------------------------------------------------- P-03 butiran */

.pt-hero {
  height: 190px;
  border-radius: var(--r-xl);
  display: grid;
  place-items: center;
  background: linear-gradient(140deg, var(--yellow), #ffc957);
  color: var(--purple);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .12em;
}

.pt-fakta { display: grid; align-items: stretch; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--sp-3); }

/* Kad DIREGANGKAN supaya setinggi jirannya; medan borang TIDAK.

   .pt-field ialah grid dalam grid. Apabila ia diregangkan mengikut tinggi
   baris, ruang lebih itu diagihkan antara label, input dan nota di
   dalamnya — jadi empat medan bersebelahan yang notanya berlainan panjang
   menghasilkan empat input pada empat paras berbeza. align-self:start
   membiarkan setiap medan setinggi kandungannya sendiri, dan inputnya
   bermula pada garis yang sama. */
.pt-fakta > .pt-field { align-self: start; }

.pt-slot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  border: 1.5px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--card);
  color: inherit;
  text-decoration: none;
  transition: border-color .15s, background .15s;
}
a.pt-slot:hover { border-color: var(--purple-2); }
.pt-slot.is-on { border-color: var(--purple); border-width: 2px; background: var(--purple-soft); }
.pt-slot + .pt-slot { margin-top: var(--sp-2); }
.pt-slot-tarikh { font-size: 14px; font-weight: 800; color: var(--plum); }

.pt-policy { display: grid; gap: var(--sp-2); font-size: 13.5px; }
.pt-policy > div { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }

/* Bar tindakan melekat di bawah */
.pt-dock {
  position: sticky;
  bottom: 0;
  margin-top: var(--sp-6);
  padding: var(--sp-3) 0 var(--sp-4);
  background: linear-gradient(180deg, rgba(251, 250, 247, 0), var(--paper) 22%);
}
.pt-dock-in {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  box-shadow: var(--sh-2);
}

/* ------------------------------------------------------- konsol admin */


.pt-tapis { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.pt-tapis a {
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  padding: 0 var(--sp-4);
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  text-decoration: none;
  transition: border-color .15s, background .15s;
}
.pt-tapis a:hover { border-color: var(--purple-2); }
.pt-tapis a.is-on { background: var(--purple); border-color: var(--purple); color: #fff; }

.pt-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--card); box-shadow: var(--sh-1); }
.pt-jadual { width: 100%; border-collapse: collapse; min-width: 860px; }
.pt-jadual th {
  position: sticky;
  top: 0;
  z-index: 1;
  text-align: left;
  padding: var(--sp-3) var(--sp-4);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--line-2);
  border-bottom: 1px solid var(--line);
}
.pt-jadual td { padding: var(--sp-4); border-bottom: 1px solid var(--line-2); font-size: 13.5px; vertical-align: top; }
.pt-jadual tbody tr:last-child td { border-bottom: 0; }
.pt-jadual tbody tr:hover { background: #fcfbfd; }
.pt-jadual .ref { font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; font-weight: 700; color: var(--plum); }
.pt-jadual .kecil { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.pt-jadual .amaran { color: var(--warn-ink); font-weight: 700; }

/* Baris yang terbuka di bawah barisnya sendiri — borang sunting sebaris.
   Latar berwarna dan jalur kiri menunjukkan ia milik baris di atasnya dan
   bukan satu lagi rekod dalam senarai. */
.pt-jadual tbody tr.pt-baris-buka,
.pt-jadual tbody tr.pt-baris-buka:hover { background: var(--line-2); }
.pt-jadual tbody tr.pt-baris-buka > td {
  padding: var(--sp-4) var(--sp-4) var(--sp-5);
  border-left: 3px solid var(--purple);
}

/* Versi .amaran yang boleh digunakan DI LUAR jadual. Peraturan di atas
   diskop kepada .pt-jadual, jadi ia senyap di mana-mana lagi. */
.pt-nota-lewat { font-size: 12.5px; font-weight: 700; color: var(--warn-ink); }

/* Bar alat yang tinggal satu elemen sahaja tidak sepatutnya menyebarkannya
   ke dua hujung. */
.pt-toolbar-kiri { justify-content: flex-start; }

/* Julat tarikh dan butang eksport sebagai satu kumpulan di hujung kanan
   bar alat, supaya ia tidak berselerak bila cip tempoh membaluti. */
.pt-julat-alat {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}
.pt-julat-alat .pt-input { height: 38px; }

/* Bilangan pada cip penapis. Nombor dalam bulatan pucat supaya ia dibaca
   sebagai kiraan dan bukan sebahagian daripada label. */
.pt-tapis-kira {
  display: inline-block;
  min-width: 18px;
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: var(--r-pill);
  background: var(--line-2);
  color: var(--ink-2);
  font-size: 11px;
  font-weight: 800;
  text-align: center;
}
.pt-tapis a.is-on .pt-tapis-kira { background: rgba(255, 255, 255, .28); color: #fff; }

.pt-tindakan { display: flex; gap: 6px; flex-wrap: wrap; }
.pt-tindakan button, .pt-tindakan a {
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  padding: 0 var(--sp-3);
  border-radius: var(--r-sm);
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--ink-2);
  font-size: 12.5px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color .15s, background .15s, color .15s;
}
.pt-tindakan button:hover, .pt-tindakan a:hover { border-color: var(--purple-2); color: var(--purple); }
.pt-tindakan .utama { background: var(--purple); border-color: var(--purple); color: #fff; }
.pt-tindakan .utama:hover { background: var(--purple-2); color: #fff; }
.pt-tindakan .bahaya { color: var(--stop-ink); border-color: var(--stop-line); }
.pt-tindakan .bahaya:hover { background: var(--stop-bg); color: var(--stop-ink); }
.pt-tindakan .wasap { background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-ink); }
.pt-tindakan .wasap:hover { background: #d6f0e2; color: var(--ok-ink); }

/* ------------------------------------------------- konsol admin: 4 menu */

/* Menu utama konsol. Empat bahagian — Dashboard, Taska, Pengguna, Laporan —
   menggantikan konsol dua skrin yang lama. Ia melekat di atas setiap
   halaman admin supaya admin sentiasa tahu di mana dia berada. */
.pt-admin-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--line);
}
.pt-admin-menu { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.pt-admin-menu a {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-pill);
  border: 1.5px solid transparent;
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 800;
  text-decoration: none;
  transition: background .15s, color .15s, border-color .15s;
}
.pt-admin-menu a:hover { background: var(--purple-soft); color: var(--purple); }
.pt-admin-menu a.is-on {
  background: var(--purple);
  border-color: var(--purple);
  color: #fff;
}
.pt-admin-keluar {
  min-height: 34px;
  padding: 0 var(--sp-3);
  border-radius: var(--r-sm);
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--ink-2);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
.pt-admin-keluar:hover { border-color: var(--purple-2); color: var(--purple); }

/* Kotak carian pada setiap senarai admin. Zarul meminta search/filter
   kerana senarai menjadi sukar dibaca sebaik data bertambah. */
.pt-cari { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
/* width: auto membatalkan `width: 100%` daripada peraturan .pt-input asas.
   Tanpanya medan cuba mengisi seluruh borang dan menolak butang "Cari"
   ke baris kedua — pada setiap bar carian dalam konsol. */
.pt-cari .pt-input { width: auto; min-width: 240px; height: 38px; }

/* Medan carian yang placeholdernya panjang. 240px memotong "Rujukan,
   nama, WhatsApp, centre…" di tengah, jadi admin tidak pernah membaca
   separuh daripada apa yang sebenarnya boleh dicari. */
.pt-cari .pt-cari-lebar { flex: 1 1 340px; min-width: 0; max-width: 460px; }

/* Borang carian mengambil ruang yang tinggal dalam bar alat, supaya
   medan dan butang "Cari" kekal sebaris. */
.pt-toolbar > .pt-cari { flex: 1 1 320px; }
/* Butang bar alat: versi padat butang biasa, untuk sebelah medan input.

   Gaya ini dahulunya hidup HANYA di bawah `.pt-cari button`, jadi ia
   berfungsi untuk butang "Cari" dan tidak untuk apa-apa di luar bar
   carian. Butang di luar itu ditulis sebagai `class="pt-btn-2"` — yang
   nampak betul dalam markup tetapi bukan: .pt-btn-2 cuma pengubah WARNA.
   Padding, sempadan, jejari dan fon semuanya datang daripada .pt-btn
   asas, yang setinggi 50px dan terlalu berat di sebelah medan.

   Hasilnya butang tanpa bentuk langsung — warna sahaja pada butang
   pelayar lalai. Ia terlepas pandang sehingga Zarul menyedarinya pada
   butang "Tapis".

   Kelas ini memberi gaya itu nama supaya ia boleh digunakan di mana-mana,
   dan .pt-cari button terus berkongsi peraturan yang sama. */
/* .pt-btn-alat kini dipakai pada <a> dan pada butang yang turut membawa
   .pt-btn, yang lebarnya 100%. Peraturan ini menjadikannya berkelakuan
   sama tanpa mengira elemen atau gabungan kelas. */
.pt-btn-alat {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-height: 38px;
}
.pt-btn-alat,
.pt-cari button {
  min-height: 38px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-sm);
  border: 1.5px solid var(--line);
  background: var(--card);
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.pt-btn-alat:hover,
.pt-cari button:hover { border-color: var(--purple-2); color: var(--purple); }

/* ------------------------------------- jalur tarikh & foto centre */

/* Hari yang tidak boleh ditempah dinyatakan dengan perkataan, bukan
   coretan. Coretan menunjukkan sesuatu tidak kena tanpa menyatakan apa;
   "Slot penuh" dan "Tutup" memberitahu ibu bapa perkara yang berbeza.
   Kedua-duanya tetap boleh diklik. */
.pt-tapis-hari a { flex-direction: column; gap: 1px; line-height: 1.15; padding-top: 5px; padding-bottom: 5px; }
.pt-tapis-hari a small { font-size: 10.5px; font-weight: 700; opacity: .85; }

.pt-tapis a.pt-hari-penuh { color: var(--warn-ink); border-color: var(--warn-line); background: var(--warn-bg); }
.pt-tapis a.pt-hari-tutup { color: var(--muted); background: var(--line-2); }
.pt-tapis a.pt-hari-tutup small { opacity: .75; }

/* Inisial centre apabila tiada foto. Menggantikan perkataan "FOTO CENTRE"
   yang membuat tapak kelihatan belum siap; huruf pada latar berwarna
   kelihatan seperti pilihan reka bentuk. */
.pt-foto-huruf {
  font-family: var(--font-display);
  font-size: 40px;
  font-weight: 800;
  letter-spacing: -.04em;
  color: rgba(36, 16, 68, .28);
  line-height: 1;
}
.pt-foto-huruf-besar { font-size: 72px; }

/* Dua medan bersebelahan pada skrin lebar — borang admin sahaja.
   Pada telefon ia jatuh menjadi satu lajur, kerana medan sempit
   berkembar lebih sukar diisi daripada medan penuh bertindan. */
/* align-items:start supaya satu medan yang membawa .pt-hint panjang di
   bawah inputnya tidak meregangkan jirannya. */
.pt-dua { display: grid; align-items: start; gap: var(--sp-3); grid-template-columns: 1fr; }
@media (min-width: 700px) { .pt-dua { grid-template-columns: repeat(2, 1fr); } }

/* Lipatan (details/summary) untuk bahagian panjang dalam konsol admin.
   Tajuk kekal terbaca apabila tertutup dan membawa ringkasan di sebelahnya,
   supaya admin tahu apa yang ada di dalam tanpa membukanya. */
.pt-lipat {
  border: 1px solid var(--line-2);
  border-radius: 14px;
  padding: var(--sp-3) var(--sp-4);
  margin-top: var(--sp-4);
  background: var(--card);
}
.pt-lipat > summary {
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-3);
  list-style: none;
}
.pt-lipat > summary::-webkit-details-marker { display: none; }
.pt-lipat > summary::before {
  content: "▸";
  color: var(--plum);
  font-size: 12px;
  transition: transform .15s ease;
  display: inline-block;
}
.pt-lipat[open] > summary::before { transform: rotate(90deg); }
.pt-lipat[open] > summary { margin-bottom: var(--sp-2); }
.pt-lipat-tajuk {
  font-weight: 800;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--plum);
}
.pt-lipat-nota { font-size: 13px; color: var(--muted); }

/* Jadual rapat: banyak baris pendek, bukan sedikit baris padat. */
.pt-jadual-rapat { min-width: 620px; }
.pt-jadual-rapat td { padding: var(--sp-2) var(--sp-3); font-size: 13px; }
.pt-jadual-rapat th { padding: var(--sp-2) var(--sp-3); }
.pt-jadual-pemisah td {
  background: var(--purple-soft);
  font-weight: 800;
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--plum);
}

/* ------------------------------------------------ foto centre (admin) */

/* Grid foto dalam konsol admin. Nisbah 4:3 dikunci pada setiap petak
   supaya barisan kekal rata walaupun gambar yang dimuat naik mempunyai
   nisbah berbeza — yang memang berlaku, kerana ia datang daripada
   pelbagai telefon. object-fit: cover memangkas, bukan meleretkan. */
.pt-foto-grid {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
.pt-foto-item {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: var(--sp-2);
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
}
/* Kad muka depan membawa cip tambahan, jadi kapsyennya membaluti kepada
   dua baris sementara yang lain kekal satu. Menolak baris butang ke bawah
   memastikan setiap kad dalam baris yang sama tamat pada paras yang sama. */
.pt-foto-item .pt-tindakan { margin-top: auto; padding-top: var(--sp-1); }
.pt-foto-item.pt-foto-utama { border-color: var(--ok-line); }
.pt-foto-item img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--r-sm);
  background: var(--purple-soft);
}
.pt-foto-item figcaption {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin: var(--sp-2) 0;
}

/* Input fail tidak boleh menerima padding dalaman .pt-input tanpa butang
   "Browse" penyemak imbas terkeluar daripada kotaknya. */
.pt-input[type="file"] {
  padding: 8px;
  font-size: 13px;
}

.pt-senarai-nota {
  margin: var(--sp-2) 0;
  padding-left: 18px;
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink-2);
}

/* ------------------------------------------- grid daerah (muka depan) */

/* Grid centre aktif di bawah borang carian, menggantikan senarai cip
   poskod.

   auto-fill dan BUKAN pertanyaan media dengan kiraan lajur tetap. Halaman
   carian menggunakan .pt-wrap yang sempit (--w-narrow), jadi pertanyaan
   media akan mengukur TETINGKAP sedangkan grid hidup dalam lajur sempit
   itu: pada skrin komputer ia memilih empat lajur dan memampatkan empat
   kad ke dalam ruang selebar telefon. auto-fill mengukur ruang yang
   benar-benar ada, jadi grid yang sama betul di dalam mana-mana bekas. */
.pt-daerah-grid {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

.pt-daerah {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
  text-decoration: none;
  box-shadow: var(--sh-1);
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.pt-daerah:hover  { border-color: var(--purple-2); transform: translateY(-2px); box-shadow: var(--sh-2); }
.pt-daerah:focus-visible { outline: 2px solid var(--purple); outline-offset: 2px; }
.pt-daerah.is-on  { border-color: var(--purple); }

.pt-daerah-foto {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  background: var(--purple-soft) center / cover no-repeat;
}

/* Nama daerah sahaja — tanpa nama centre. Pada peringkat ini ibu bapa
   memilih tempat, bukan jenama. */
.pt-daerah-nama {
  padding: var(--sp-2) var(--sp-3);
  font-weight: 700;
  font-size: 13.5px;
  color: var(--ink);
  text-align: center;
}

/* --------------------------------------------------- hero muka depan */

/* Gambar latar hero.
 *
 * background-position dikunci ke KANAN dan bukan center. Gambar yang
 * Zarul beri mempunyai ruang kosong di kiri dan budak di kanan; memusatkan
 * gambar pada skrin sempit akan memotong budak itu keluar dan meletakkan
 * tajuk di atas rak buku. Menambat ke kanan mengekalkan subjek kelihatan
 * pada setiap lebar, dan teks sentiasa jatuh ke ruang kosong. */
/* min-height, bukan tinggi yang ditentukan kandungan sahaja.
 *
 * Gambar ini 16:9. Tanpa tinggi minimum, kotak hero mengecut kepada tinggi
 * teks (~140px) manakala `cover` tetap menskala gambar mengikut LEBAR —
 * hasilnya jalur nipis yang memotong kepala budak. 200px memberi nisbah
 * yang cukup hampir kepada gambar asal supaya keratan menegak hampir
 * tiada. */
.pt-hero-utama {
  position: relative;
  display: flex;
  align-items: center;
  overflow: hidden;
  min-height: 200px;
  margin-top: var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--purple-soft) url("hero-main.jpg") right center / cover no-repeat;
}

/* "Cairkan sikit bahagian yg ada tulisan" — permintaan Zarul.
 *
 * Kecerunan dan bukan gambar yang disunting: gambar hero boleh ditukar
 * bila-bila masa tanpa mengulang kerja penyuntingan.
 *
 * SATU kecerunan tanpa pertanyaan media. Hero ini sentiasa hidup dalam
 * .pt-wrap yang berlebar tetap (--w-narrow, 560px), jadi pertanyaan media
 * akan mengukur TETINGKAP dan memilih versi "skrin lebar" yang lebih nipis
 * untuk kotak yang sebenarnya masih sempit — teks kemudian jatuh di atas
 * budak dan hilang. */
.pt-hero-utama::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(255, 253, 247, .97) 0%,
    rgba(255, 253, 247, .95) 46%,
    rgba(255, 253, 247, .70) 62%,
    rgba(255, 253, 247, 0) 88%
  );
}

.pt-hero-teks {
  position: relative;   /* di atas lapisan cair */
  max-width: 62%;
  padding: var(--sp-5) var(--sp-4);
}

/* Pil kecil di atas tajuk, mengikut rujukan reka bentuk Zarul. */
.pt-hero-pil {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-bottom: var(--sp-3);
  padding: 5px var(--sp-3);
  border-radius: var(--r-pill);
  background: #fff;
  box-shadow: var(--sh-1);
  color: var(--purple);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* Tajuk dua warna: baris pertama gelap, baris kedua ungu jenama —
   corak yang sama seperti rujukan yang Zarul hantar. */
.pt-hero-tajuk {
  font-size: clamp(22px, 4.4vw, 28px);
  line-height: 1.18;
  color: var(--plum);
}
.pt-hero-tajuk span { color: var(--purple); }

.pt-hero-lead { font-size: 14px; }

/* Kad carian menaiki sedikit ke atas hero supaya kedua-duanya terbaca
   sebagai satu blok dan bukan dua kotak bertindan. */
.pt-hero-utama + .pt-card { margin-top: calc(var(--sp-4) * -1); }

/* --------------------------------------------- galeri foto centre (P-03) */

/* Mozek: satu gambar besar di kiri, dua bertindan di kanan — susun atur
   yang sama seperti rujukan Booking.com yang Zarul lampirkan.
   grid-template-areas dan bukan span, kerana ia membaca seperti bentuk
   sebenar yang dihasilkannya. */
.pt-galeri {
  display: grid;
  gap: 6px;
  border-radius: var(--r-xl);
  overflow: hidden;
}
.pt-galeri-petak:nth-child(1) { grid-area: utama; }
.pt-galeri-petak:nth-child(2) { grid-area: kecil1; }
.pt-galeri-petak:nth-child(3) { grid-area: kecil2; }

/* Satu bentuk bagi setiap bilangan petak.
 *
 * Tanpa ini, susun atur tiga petak digunakan untuk semua: dua gambar
 * meninggalkan LUBANG kosong di kanan bawah, kerana kawasan "kecil2"
 * wujud tetapi tiada apa untuk mengisinya. */
.pt-galeri-1 { grid-template-columns: 1fr; grid-template-areas: "utama"; }
.pt-galeri-2 { grid-template-columns: 2fr 1fr; grid-template-areas: "utama kecil1"; }
.pt-galeri-3 {
  grid-template-columns: 2fr 1fr;
  grid-template-areas:
    "utama kecil1"
    "utama kecil2";
}

.pt-galeri-petak {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--purple-soft);
}
.pt-galeri-petak img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .25s ease;
}
.pt-galeri-petak:hover img { transform: scale(1.04); }
.pt-galeri-petak:focus-visible { outline: 3px solid var(--purple); outline-offset: -3px; }

/* Gambar besar mengunci nisbah keseluruhan mozek. Petak kecil mengisi
   separuh tinggi lajurnya, jadi ia tidak perlukan nisbahnya sendiri. */
.pt-galeri-utama { aspect-ratio: 4 / 3; }
.pt-galeri-1 .pt-galeri-utama { aspect-ratio: 16 / 9; }

/* "+N" pada petak terakhir, seperti "+6 photos" dalam rujukan. */
.pt-galeri-lagi {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(36, 16, 68, .55);
  color: #fff;
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 800;
}

/* ---- pembesar: :target, tiada JavaScript ---- */

.pt-galeri-besar {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 60;
  place-items: center;
  padding: var(--sp-4);
}
.pt-galeri-besar:target { display: grid; }

/* Latar ialah pautan tutup bersaiz penuh: menekan di luar gambar ialah
   perkara pertama yang orang cuba. */
.pt-galeri-latar {
  position: absolute;
  inset: 0;
  background: rgba(20, 8, 40, .88);
}
.pt-galeri-besar img {
  position: relative;
  max-width: 100%;
  max-height: 82vh;
  width: auto;
  height: auto;
  border-radius: var(--r-md);
  box-shadow: var(--sh-2);
}

.pt-galeri-tutup,
.pt-galeri-nav {
  position: absolute;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .92);
  color: var(--plum);
  font-size: 24px;
  line-height: 1;
  text-decoration: none;
}
.pt-galeri-tutup:hover,
.pt-galeri-nav:hover { background: #fff; }
.pt-galeri-tutup { top: var(--sp-4); right: var(--sp-4); font-size: 26px; }
.pt-galeri-nav { top: 50%; transform: translateY(-50%); font-size: 30px; }
.pt-galeri-sebelum { left: var(--sp-3); }
.pt-galeri-selepas { right: var(--sp-3); }

.pt-galeri-kira {
  position: absolute;
  bottom: var(--sp-4);
  left: 50%;
  transform: translateX(-50%);
  padding: 4px var(--sp-3);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .92);
  color: var(--plum);
  font-size: 12px;
  font-weight: 700;
}

/* ------------------------------------- statistik berwarna (dashboard) */

/* Enam kad, satu warna setiap satu — gaya yang Zarul minta dalam
   AMENDMENT.docx berserta gambar rujukan.
   Warna di sini BUKAN hiasan: ia memberi setiap angka tempat tetap pada
   skrin, jadi Zarul boleh mencari "payout akan datang" dengan warnanya
   tanpa membaca keenam-enam label setiap kali dia membuka dashboard. */
/* 170px bukan nombor sembarangan. Dengan jurang 12px, ia membahagi lajur
   admin selebar 1120px kepada TEPAT enam — satu baris, seperti gambar
   rujukan — dan jatuh kepada tiga lalu dua apabila bekas mengecil. Nilai
   yang lebih besar (185px) memberi lima lajur, yang meninggalkan kad
   keenam terkapai sendirian pada baris kedua. */
.pt-stat-warna {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}

.pt-statkad {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-5);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--sh-1);
}

/* Jalur warna di tepi kiri, bukan seluruh kad diwarnakan. Enam kad
   berlatar penuh bersebelahan bertarung antara satu sama lain dan
   nombornya menjadi lebih sukar dibaca, bukan lebih senang. */
.pt-statkad::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 5px;
  background: var(--pt-stat-warna, var(--purple));
}

/* Dua baris walaupun teksnya muat dalam satu.
 *
 * "PAYOUT AKAN DATANG" membalut pada lebar kad, "JUM. TEMPAHAN" tidak.
 * Tanpa tinggi tetap, nombor pada enam kad bersebelahan bermula pada
 * paras berbeza dan barisan itu kelihatan senget. */
.pt-statkad-label {
  display: block;
  min-height: 2.9em;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .07em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--muted);
}
.pt-statkad-angka {
  display: block;
  margin-top: 4px;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.15;
  color: var(--pt-stat-warna, var(--plum));
}
/* Nota ditolak ke bawah supaya ia duduk pada paras yang sama merentas
   barisan, walaupun nombor di atasnya berlainan tinggi. */
.pt-statkad-nota {
  display: block;
  margin-top: auto;
  padding-top: 2px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--muted);
}

/* Nama daerah ialah teks, bukan nombor — ia perlu muat tanpa melimpah. */
.pt-statkad-daerah .pt-statkad-angka { font-size: 19px; }

.pt-statkad-tempahan { --pt-stat-warna: #5d2fa5; }
.pt-statkad-nilai    { --pt-stat-warna: #1f7a52; }
.pt-statkad-batal    { --pt-stat-warna: #c0304b; }
.pt-statkad-daerah   { --pt-stat-warna: #1f6fb2; }
.pt-statkad-centre   { --pt-stat-warna: #9a6212; }
.pt-statkad-payout   { --pt-stat-warna: #7c48c5; }

/* =====================================================================
   Muka depan (landing page)
   =====================================================================
   Dibina mengikut mockup yang Zarul hantar. Palet di sini lebih ceria
   daripada seluruh sistem — merah jambu, kuning, biru, hijau di samping
   ungu jenama — kerana muka depan menjual, manakala skrin tempahan
   mengesahkan. Warna ini SENGAJA tidak dieksport ke token global: skrin
   bayaran dan resit kekal tenang.
   ===================================================================== */

:root {
  --lp-pink: #ff4d8d;
  --lp-biru: #2f7fd4;
  --lp-kuning: #f5a623;
  --lp-hijau: #22a06b;
  --lp-merah: #ff6b5a;
  --lp-krim: #fffaf0;
  --lp-langit: #eef5ff;
}

/* ------------------------------------------------------------- hero */

.pt-lp-hero {
  position: relative;
  margin-top: var(--sp-4);
  padding: var(--sp-6) var(--sp-5) var(--sp-7);
  border-radius: var(--r-xl);
  background: linear-gradient(165deg, var(--lp-krim) 0%, var(--lp-langit) 100%);

  /* TIADA overflow: hidden di sini. Ia pernah ada, tetapi satu-satunya
     perkara yang melimpah keluar ialah senarai cadangan carian — dan
     itulah yang sepatutnya keluar. Corat-coret matahari, bintang dan
     pelangi semuanya duduk dalam padding hero pada setiap lebar skrin,
     jadi tiada apa lagi yang perlu dipotong. */
}

/* Satu lajur pada telefon, dua pada skrin lebar. Teks sentiasa dahulu
   dalam susunan DOM supaya pembaca skrin dan telefon mendapat tajuk
   sebelum gambar hiasan. */
.pt-lp-hero-grid {
  display: grid;
  gap: var(--sp-6);
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .pt-lp-hero-grid { grid-template-columns: 1.05fr .95fr; gap: var(--sp-7); }
}

.pt-lp-tajuk {
  margin-top: var(--sp-3);
  font-family: var(--font-display);
  font-size: clamp(30px, 5vw, 46px);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -.03em;
  color: var(--plum);
}
.pt-lp-tajuk span { color: var(--lp-pink); }

.pt-lp-lead {
  margin-top: var(--sp-3);
  max-width: 46ch;
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--ink-2);
}

/* ---- kad carian dalam hero ---- */

.pt-lp-cari {
  margin-top: var(--sp-5);
  padding: var(--sp-4);
  border-radius: var(--r-lg);
  background: #fff;
  box-shadow: var(--sh-2);
}
.pt-lp-cari-tajuk {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-bottom: var(--sp-3);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 800;
  color: var(--purple);
}

/* Medan berbaris pada skrin lebar, bertindan pada telefon — butang
   sentiasa selebar penuh di bawah supaya ia mudah dicapai dengan ibu jari. */
.pt-lp-cari-medan {
  display: grid;
  gap: var(--sp-3);
  grid-template-columns: 1fr;
}
@media (min-width: 620px) {
  /* Satu medan, satu butang. Dahulu tiga lajur kerana ada DUA medan
     (poskod dan nama) yang bersilih ganti; dengan satu medan, butang
     tersangkut dalam lajur 1fr kedua dan diregangkan selebar medan.
     `auto` membiarkan butang sekadar sebesar teksnya, dan medan mengambil
     selebihnya. */
  .pt-lp-cari-medan { grid-template-columns: 1fr auto; align-items: end; }
}

.pt-lp-medan label {
  display: block;
  margin-bottom: 3px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.pt-lp-medan input {
  width: 100%;
  min-height: 46px;
  padding: 0 var(--sp-3);
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
  font-size: 15px;
}
.pt-lp-medan input:focus { outline: none; border-color: var(--purple-2); }
.pt-lp-medan.is-salah input { border-color: var(--stop-line); background: var(--stop-bg); }

.pt-lp-btn {
  min-height: 46px;
  padding: 0 var(--sp-6);
  border: none;
  border-radius: var(--r-md);
  background: var(--lp-pink);
  color: #fff;
  font-size: 15px;
  font-weight: 800;
  white-space: nowrap;
  transition: background .15s, transform .06s;
}
.pt-lp-btn:hover { background: #e83f7d; }
.pt-lp-btn:active { transform: translateY(1px); }
@media (max-width: 619px) { .pt-lp-btn { width: 100%; } }

/* --------------------------------------------------- pautan alamat */

/* Peta yang dibenamkan pernah dicuba di sini dan dibuang semula —
   pautan sudah memadai, dan benaman itu memuat Google pada setiap
   lawatan halaman centre. */
.pt-alamat-pautan {
  display: inline-block;
  margin-top: var(--sp-3);
  color: var(--purple);
  font-size: 13px;
  font-weight: 800;
  text-decoration: none;
}
.pt-alamat-pautan:hover { text-decoration: underline; }

/* ------------------------------------------------ paparan cetak (PDF) */

/* Laluan "PDF" tanpa pustaka PDF: pelayar menukar halaman ini kepada PDF
   melalui "Simpan sebagai PDF" dalam dialog cetak. Jadi semua kerja reka
   letak berlaku di sini, bukan dalam penjana. */

.pt-cetak-kepala {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-bottom: var(--sp-3);
  margin-bottom: var(--sp-4);
  border-bottom: 2px solid var(--ink);
  font-size: 12px;
}
.pt-cetak-kepala b { font-size: 15px; }
.pt-cetak-kepala span { display: block; color: var(--muted); }
.pt-cetak-kanan { text-align: right; }

.pt-cetak-jadual { width: 100%; border-collapse: collapse; font-size: 11px; }
.pt-cetak-jadual th {
  padding: 6px 8px;
  border-bottom: 1px solid var(--ink);
  text-align: left;
  font-size: 10px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.pt-cetak-jadual td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

/* Lajur wang dan nombor baris.

   tabular-nums memaksa setiap digit selebar yang sama, jadi RM9.00 dan
   RM48.93 berbaris pada titik perpuluhan. Tanpa ia, lajur wang bergoyang
   dan mata tidak boleh menjumlah menuruni lajur — perkara pertama yang
   sesiapa buat dengan senarai bercetak. */
.pt-cetak-jadual .no,
.pt-cetak-jadual .wang {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pt-cetak-jadual .no { color: var(--muted); }

/* Nombor rujukan dan tarikh tidak dibenarkan berpecah.

   "UJI-C4CA4238A0" yang dibalut kepada dua baris tidak lagi boleh dibaca
   sebagai satu rujukan, dan "2026-09-" di atas "17" langsung tidak
   kelihatan seperti tarikh. */
.pt-cetak-jadual .teguh { white-space: nowrap; }
.pt-cetak-jadual .kecil { display: block; color: var(--muted); font-size: 10px; }

/* Baris jumlah di kaki jadual. */
.pt-cetak-jadual tfoot td {
  padding-top: 8px;
  border-top: 2px solid var(--ink);
  border-bottom: none;
  font-weight: 800;
}

/* Nota kaki dokumen — bukan footer tapak. */
.pt-cetak-nota {
  margin-top: var(--sp-4);
  padding-top: var(--sp-2);
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 10px;
  line-height: 1.5;
}

@media print {
  /* Margin muka surat dikawal di sini, bukan diserahkan kepada lalai
     pelayar yang berbeza antara mesin. 14mm atas/bawah memberi ruang
     kepada kepala dan kaki yang pelayar sendiri cetak (URL, tarikh,
     nombor muka surat) tanpa ia bertindih dengan jadual. */
  /* Margin lalai untuk SETIAP halaman yang dicetak dari tapak ini —
     resit ibu bapa, halaman status, laporan centre. Potret. */
  @page {
    margin: 14mm 12mm;
  }

  /* LANDSKAP untuk senarai tempahan sahaja, melalui halaman bernama.

     Sembilan lajur tidak muat pada lebar A4 potret: nombor rujukan
     berpecah kepada dua baris, "2026-09-17" menjadi "2026-09-" dan "17",
     dan status yang panjang mengambil tiga baris. Hasilnya baris setinggi
     tiga kali dan senarai yang memakan dua kali ganda kertas.

     Landskap memberi kira-kira 1030px berbanding 700px — cukup untuk
     setiap lajur duduk pada satu baris.

     Ia DIIKAT kepada .pt-cetak dan bukan diletak pada @page global.
     Jadual data memang dicetak landskap; resit satu muka surat yang ibu
     bapa cetak tidak. Tanpa halaman bernama, satu peraturan di sini akan
     memutarkan setiap cetakan dalam sistem.

     Pelayar yang tidak menyokong halaman bernama mengabaikannya dan
     mencetak potret — lebih sesak, tetapi masih betul. */
  @page tempahan {
    size: A4 landscape;
    margin: 12mm;
  }
  .pt-cetak { page: tempahan; }

  .pt-head,
  .pt-foot,
  .pt-toast-bekas { display: none !important; }

  body { background: #fff; }
  .pt-main { padding: 0; }

  /* Bekas lajur berpusat mengecilkan jadual kepada kira-kira dua pertiga
     lebar kertas, dan ruang kosong itu memaksa nama centre dan nama ibu
     bapa membalut tanpa sebab. Dalam cetakan, margin muka surat SUDAH
     menjadi jidarnya. */
  .pt-wrap,
  .pt-wrap-lebar {
    width: 100%;
    max-width: none;
    margin: 0;
  }

  /* Kepala tidak dibiarkan bersendirian di hujung muka surat. */
  .pt-cetak-kepala { break-after: avoid; }

  /* Baris jadual tidak dipecahkan merentas muka surat, dan tajuk lajur
     berulang pada setiap muka surat. */
  .pt-cetak-jadual tr { break-inside: avoid; }
  .pt-cetak-jadual thead { display: table-header-group; }

  /* tfoot SEKALI di hujung, bukan berulang setiap muka surat.
     Chrome mengulangi table-footer-group pada setiap muka surat, dan
     "jumlah keseluruhan" yang muncul tiga kali dalam satu dokumen
     membaca seperti tiga jumlah yang berbeza. */
  .pt-cetak-jadual tfoot { display: table-row-group; }

  /* Pautan dicetak sebagai teks. Warna ungu menjadi kelabu pucat pada
     pencetak hitam putih, dan garis bawah hanya menambah bunyi. */
  .pt-cetak a { color: inherit; text-decoration: none; }
}

/* Baris penapis status.

   Ia pernah membawa tujuh cip di kiri dan pemilih ini di kanan. Cip
   dibuang pada 17 Sep 2026: setiap satu bertindih dengan sesuatu yang
   sudah ada pada skrin yang sama — "Semua" dengan kad Jumlah tempahan,
   "Menunggu centre" dengan kadnya sendiri, dan empat lagi dengan pemilih
   ini. Yang tinggal hanyalah dua kawalan yang melakukan kerja yang sama,
   iaitu keadaan yang halaman ini pernah dibersihkan untuk dielakkan. */
.pt-tapis-baris {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
}

.pt-tapis-pilih {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
}
/* Label memenuhi lebar penuh supaya ia memaksa baris sendiri DI ATAS
   pemilih. Di sebelah, ia berebut ruang mendatar dengan pemilih dan
   butang, dan tiga benda sebaris pada bar yang sudah padat membaca
   sebagai satu kekacauan dan bukan satu kawalan bernama. */
.pt-tapis-pilih label {
  flex: 0 0 100%;
  margin-bottom: 2px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .03em;
  text-transform: uppercase;
}
/* .pt-input lalai 100% lebar; di sini ia perlu mengikut kandungannya. */
.pt-tapis-pilih .pt-input { width: auto; min-height: 36px; font-size: 13px; }

/* ------------------------------------------ butiran satu tempahan */

.pt-lihat-kepala {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--line-2);
}
.pt-lihat-kepala .pt-hint { display: block; margin-top: 2px; }

.pt-lihat-blok { margin-top: var(--sp-5); }
.pt-lihat-blok .pt-kicker { display: block; margin-bottom: var(--sp-2); }

/* Sepasang label/nilai. Label kelabu di kiri dengan lebar tetap supaya
   nilai berbaris menegak merentas semua blok — mata menuruni satu lajur
   dan bukan mengejar hujung setiap label. */
.pt-butir {
  display: grid;
  grid-template-columns: 170px 1fr;
  gap: var(--sp-3);
  padding: 7px 0;
  border-bottom: 1px solid var(--line-2);
  font-size: 13.5px;
}
.pt-butir:last-child { border-bottom: none; }
.pt-butir > span:first-child { color: var(--muted); }
.pt-butir a { color: var(--purple); }
.pt-lihat-kod { font-family: var(--mono, ui-monospace, monospace); font-size: 12.5px; word-break: break-all; }
.pt-lihat-nota { color: var(--stop-ink); font-weight: 700; }
.pt-lihat-belum { color: var(--stop-ink); font-weight: 700; }

/* Pada telefon dua lajur menjadi terlalu sempit untuk kedua-duanya. */
@media (max-width: 520px) {
  .pt-butir { grid-template-columns: 1fr; gap: 2px; }
}

/* Garis masa sejarah status. Titik dan garis dilukis dengan pseudo
   elemen supaya tiada markup tambahan bagi setiap baris. */
.pt-masa { margin: 0; padding: 0 0 0 var(--sp-5); list-style: none; }
.pt-masa li {
  position: relative;
  padding: 0 0 var(--sp-4) 0;
  font-size: 13.5px;
}
.pt-masa li::before {
  content: "";
  position: absolute;
  left: calc(var(--sp-5) * -1 + 4px);
  top: 6px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--purple);
}
/* Garis penyambung berhenti pada item terakhir. */
.pt-masa li:not(:last-child)::after {
  content: "";
  position: absolute;
  left: calc(var(--sp-5) * -1 + 8px);
  top: 17px;
  bottom: 2px;
  width: 1px;
  background: var(--line);
}
.pt-masa li:last-child { padding-bottom: 0; }
.pt-masa-atas { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--sp-2); }
.pt-masa-sebab { display: block; margin-top: 2px; color: var(--ink-2); }

/* ------------------------------------------------------- breadcrumb */

/* Jejak "anda berada di sini" pada setiap halaman konsol. Ia hidup rapat
   di bawah kepala, sebelum kandungan, supaya ia dibaca sebelum apa-apa
   keputusan dibuat pada halaman itu. */
.pt-remah { padding: var(--sp-3) 0 0; }
.pt-remah ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 12.5px;
}

/* Pemisah ialah pseudo-elemen, bukan aksara dalam markup.

   Teks "›" antara item akan dibaca oleh pembaca skrin sebagai sebahagian
   nama pautan ("› Tempahan"), dan disalin bersama apabila pengguna
   menyalin jejak itu. */
.pt-remah li + li::before {
  content: "›";
  margin-right: 6px;
  color: var(--line);
}
.pt-remah a {
  color: var(--muted);
  font-weight: 600;
  text-decoration: none;
}
.pt-remah a:hover { color: var(--purple); text-decoration: underline; }
.pt-remah [aria-current="page"] { color: var(--ink); font-weight: 700; }

/* ------------------------------------------- modal dan menu tindakan */

/* <dialog> asli: perangkap fokus, Esc, dan latar gelap datang percuma.
   Yang tinggal hanya rupa kotaknya. */
.pt-modal {
  width: min(680px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  padding: var(--sp-6);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--sh-3);
}
.pt-modal::backdrop { background: rgba(36, 16, 68, .45); }

/* Modal yang membawa satu SKRIN, bukan satu borang pendek.

   Tukar slot menyenaraikan setiap sesi yang layak, jadi ia perlu ruang
   dan perlu boleh ditatal sendiri — kalau tidak, dialog membesar melebihi
   tetingkap dan butang "Tukar slot sekarang" di bawahnya tidak boleh
   dicapai langsung. */
.pt-modal-lebar { width: min(760px, calc(100vw - 32px)); }
.pt-modal-isi { max-height: min(70vh, 640px); overflow-y: auto; margin-top: var(--sp-3); }

/* Kad di dalam modal sudah pun berada dalam kotak; bingkai kedua hanya
   menambah garis di dalam garis. */
.pt-modal-isi .pt-card { border: none; box-shadow: none; padding: 0; }
.pt-modal-isi .pt-card + .pt-card { margin-top: var(--sp-4); }

/* Bar atas halaman penuh (rujukan + pautan kembali) tidak diperlukan di
   sini — tajuk dialog sudah menamakan tempahan, dan butang tutup sudah
   menjadi jalan keluar. */
.pt-modal-isi .pt-toolbar { display: none; }

/* Dialog pengesahan — sempit, kerana ia membawa satu ayat dan dua butang.
   Lebar penuh menjadikan ayat itu satu baris panjang yang mata melompati. */
.pt-modal-sahkan { width: min(440px, calc(100vw - 32px)); }
.pt-sahkan-mesej {
  margin: var(--sp-3) 0 0;
  color: var(--ink-2);
  font-size: 14px;
  line-height: 1.6;
}
.pt-sahkan-tindakan {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  margin-top: var(--sp-5);
}
/* Butang teruskan mengambil warna tindakan asal: merah untuk yang merah. */
.pt-sahkan-tindakan .pt-btn.is-bahaya {
  background: var(--stop-ink);
  border-color: var(--stop-ink);
}

.pt-modal-kepala {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--line-2);
}
.pt-modal-tutup {
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.pt-modal-tutup:hover { background: var(--line-2); color: var(--ink); }

.pt-modal-kaki {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-2);
}

/* Menu tindakan dalam jadual. <details> dan bukan JavaScript: ia buka dan
   tutup sendiri, boleh dicapai dengan papan kekunci, dan berfungsi
   walaupun skrip gagal dimuat. */
.pt-menu { position: relative; }
.pt-menu > summary {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 32px;
  padding: 0 var(--sp-3);
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--plum);
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  list-style: none;
  white-space: nowrap;
}
.pt-menu > summary::-webkit-details-marker { display: none; }
.pt-menu > summary::after { content: "▾"; font-size: 10px; opacity: .6; }
.pt-menu > summary:hover { border-color: var(--purple-2); color: var(--purple); }
.pt-menu[open] > summary { border-color: var(--purple-2); color: var(--purple); }

.pt-menu-isi {
  position: absolute;
  z-index: 25;
  top: calc(100% + 4px);
  right: 0;
  min-width: 190px;
  padding: var(--sp-1);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
  box-shadow: var(--sh-2);
}
.pt-menu-isi a,
.pt-menu-isi button {
  display: block;
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border: none;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.pt-menu-isi a:hover,
.pt-menu-isi button:hover { background: var(--purple-soft); color: var(--purple); }
/* Dua nama kelas untuk perkara yang sama: konsol admin menandakan butang
   merah dengan .is-bahaya, konsol centre dengan .bahaya (warisan
   .pt-tindakan .bahaya, yang mendahuluinya). Kedua-duanya diterima di
   sini supaya "Tolak" dan "Batalkan sesi" kekal merah selepas lajur
   Tindakan centre bertukar menjadi menu. */
.pt-menu-isi button.is-bahaya,
.pt-menu-isi button.bahaya { color: var(--stop-ink); }
.pt-menu-isi button.is-bahaya:hover,
.pt-menu-isi button.bahaya:hover { background: var(--stop-bg); }
.pt-menu-isi form { margin: 0; }

/* Kepala menu: menamakan apa yang tindakan di bawahnya akan kenakan.
   Bukan item boleh klik, jadi ia tidak mengambil gaya hover. */
.pt-menu-kepala {
  padding: var(--sp-2) var(--sp-3) var(--sp-3);
  margin-bottom: var(--sp-1);
  border-bottom: 1px solid var(--line-2);
  line-height: 1.4;
}
.pt-menu-kepala b { display: block; font-size: 13px; color: var(--ink); }
.pt-menu-kepala span { display: block; color: var(--muted); font-size: 12px; }

/* ------------------------------- susun / tapis / halaman untuk jadual */

/* Kawalan untuk jadual konsol, meniru susunan DataTables dalam PTPK:
   tapisan di atas, kiraan di sebelahnya, dan kaki yang memberitahu
   julat baris berserta butang halaman. Dibina dalam sistem .pt-* kerana
   DataTables datang bersama jQuery dan tema Bootstrapnya sendiri. */
.pt-jadual-alat {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.pt-jadual-tapis {
  flex: 1 1 220px;
  max-width: 320px;
  min-height: 40px;
  padding: 0 var(--sp-3);
  border: 1.5px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
  font-size: 14px;
}
.pt-jadual-tapis:focus { outline: none; border-color: var(--purple-2); }
/* Kiraan baris dahulunya teks kelabu kecil yang terapung sendirian di
   kanan — betul, tetapi terlalu senyap untuk dibaca sebagai jawapan
   kepada penapis yang baru ditekan. Latar lembut memberinya bentuk tanpa
   menjadikannya butang. */
.pt-jadual-kira {
  padding: 3px var(--sp-3);
  border-radius: 999px;
  background: var(--purple-soft);
  color: var(--plum);
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
}
/* Tanpa kotak tapis, kiraan sahaja yang tinggal — rapatkan ke kanan. */
.pt-jadual-alat.is-kira-sahaja { justify-content: flex-end; }

/* Tajuk lajur yang boleh disusun. Anak panah muncul pada lajur aktif
   sahaja; lajur lain hanya menunjukkannya semasa tetikus di atasnya,
   supaya baris tajuk tidak menjadi deretan anak panah. */
.pt-jadual th.is-boleh-susun {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.pt-jadual th.is-boleh-susun::after {
  content: "↕";
  margin-left: 6px;
  opacity: 0;
  font-size: 11px;
}
.pt-jadual th.is-boleh-susun:hover::after { opacity: .45; }
.pt-jadual th[aria-sort="ascending"]::after { content: "↑"; opacity: 1; color: var(--purple); }
.pt-jadual th[aria-sort="descending"]::after { content: "↓"; opacity: 1; color: var(--purple); }
.pt-jadual th.is-boleh-susun:focus-visible {
  outline: 3px solid rgba(93, 47, 165, .35);
  outline-offset: -3px;
}

.pt-jadual-kosong td {
  padding: var(--sp-5) var(--sp-4);
  color: var(--muted);
  text-align: center;
}

.pt-jadual-kaki {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-3);
}
/* display: flex di atas mengalahkan peraturan [hidden] helaian ejen, jadi
   menetapkan kaki.hidden = true tidak menyembunyikan apa-apa tanpa ini. */
.pt-jadual-kaki[hidden] { display: none; }

.pt-jadual-nota { color: var(--muted); font-size: 12.5px; }
.pt-jadual-halaman { display: flex; align-items: center; gap: var(--sp-2); }

.pt-jadual-saiz,
.pt-jadual-btn {
  min-height: 36px;
  padding: 0 var(--sp-3);
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--plum);
  font-size: 13px;
  font-weight: 700;
}
.pt-jadual-btn:hover:not([disabled]) { background: var(--purple-soft); border-color: var(--purple-2); }
.pt-jadual-btn[disabled] { opacity: .45; cursor: default; }

/* --------------------------------------------- skrin log masuk (auth) */

/* Tiga skrin berkongsi susunan ini: log masuk centre, log masuk admin,
   dan pintu kata laluan tapak.
   
   Kad tertumpu di TENGAH ruang yang ada. Susunan lama meletakkannya di
   puncak lajur sempit dengan tajuk di LUAR kad, dijajar kiri sementara
   kad di tengah — jadi tajuk kelihatan seperti label tergantung, dan
   ruang kosong sebesar sepertiga skrin tertinggal di bawahnya. */
.pt-masuk {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);

  /* Tolak tinggi kepala, footer dan padding .pt-main supaya kad benar-benar
     di tengah kawasan yang tinggal, bukan di tengah keseluruhan dokumen. */
  min-height: calc(100vh - 220px);
  padding: var(--sp-5) 0;
}

.pt-masuk-kad {
  width: 100%;
  max-width: 400px;
  padding: var(--sp-7) var(--sp-6) var(--sp-6);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--card);
  box-shadow: var(--sh-2);
  text-align: center;
}

.pt-masuk-ikon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin: 0 auto var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--purple-soft);
  color: var(--purple);
}
.pt-masuk-ikon svg { width: 24px; height: 24px; }

.pt-masuk-tajuk {
  margin: 0;
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--plum);
}
.pt-masuk-lead {
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* Medan dijajar kiri walaupun kepala kad di tengah — label dan ralat
   dibaca dari tepi kiri, dan borang yang di tengah menyusahkannya. */
.pt-masuk-kad form { text-align: left; }

.pt-masuk-nota {
  max-width: 400px;
  margin: 0;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.55;
  text-align: center;
}

/* ------------------------------------- medan kata laluan + butang mata */

.pt-kl { position: relative; }

/* Ruang di kanan untuk butang, supaya teks tidak bergerak di bawahnya. */
.pt-kl .pt-input { padding-right: 46px; }

.pt-kl-mata {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: none;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.pt-kl-mata svg { width: 19px; height: 19px; }

/* Mata terbuka bermaksud "tekan untuk menunjukkan"; mata bergaris
   bermaksud "tekan untuk menyembunyikan". Ditukar dengan kelas dan bukan
   atribut `hidden` — lihat komen dalam _medan-kata-laluan.php. */
.pt-kl-tutup { display: none; }
.pt-kl-mata.is-tunjuk .pt-kl-buka { display: none; }
.pt-kl-mata.is-tunjuk .pt-kl-tutup { display: inline; }
.pt-kl-mata:hover { color: var(--purple); background: var(--purple-soft); }
.pt-kl-mata:focus-visible {
  outline: 3px solid rgba(93, 47, 165, .35);
  outline-offset: 1px;
}

/* Teks untuk pembaca skrin sahaja — kekal dalam pokok kebolehcapaian,
   tetapi tidak mengambil ruang mahupun menolak apa-apa ke bawah. */
.pt-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------- senarai cadangan carian */

/* Meniru dropdown carian institusi PTPK: satu panel putih melayang di
   bawah medan, baris disorot semasa tetikus atau anak panah melaluinya.
   Dibina dengan CSS sendiri kerana Select2 datang bersama jQuery. */
/* Senarai diletakkan pada BARIS penuh (medan + butang) dan bukan pada
   medan sahaja. Medan itu sempit kerana ia berkongsi baris dengan butang
   "Cari taska"; senarai selebar medan memaksa setiap nama taska
   membaluti dua baris dan memotong yang panjang. */
.pt-lp-cari-medan { position: relative; }

.pt-cadangan {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  max-height: 264px;
  overflow-y: auto;
  margin: 0;
  padding: var(--sp-1);
  list-style: none;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--card);
  box-shadow: var(--sh-2);
  text-align: left;
}

.pt-cadangan-baris {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  cursor: pointer;
}
.pt-cadangan-baris:hover,
.pt-cadangan-baris.is-fokus { background: var(--purple-soft); }

.pt-cadangan-ikon { flex: none; font-size: 17px; line-height: 1; }

.pt-cadangan-teks { display: flex; flex-direction: column; min-width: 0; }
.pt-cadangan-teks b {
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pt-cadangan-teks small { font-size: 12px; color: var(--muted); }

.pt-cadangan-kosong {
  padding: var(--sp-3);
  font-size: 13px;
  color: var(--muted);
}

.pt-lp-nota { margin-top: var(--sp-3); font-size: 12px; color: var(--muted); }
.pt-lp-salah { margin-top: var(--sp-3); font-size: 13px; font-weight: 700; color: var(--stop-ink); }

/* ---- gambar blob + hiasan ---- */

.pt-lp-hero-gambar { position: relative; }

/* Bentuk blob organik, bukan segi empat bulat. Nilai border-radius yang
   tidak sekata inilah yang memberi rasa dilukis tangan dalam mockup. */
.pt-lp-blob {
  overflow: hidden;
  border: 7px solid #fff;
  border-radius: 62% 38% 55% 45% / 45% 52% 48% 55%;
  box-shadow: var(--sh-2);

  /* Gambar sumber 16:9, dan anak itu duduk pada satu pertiga KANAN —
     dua pertiga selebihnya dinding krim kosong. Dibiarkan pada nisbah
     asalnya, blob memaparkan sebahagian besar dinding itu dan menghimpit
     anak ke tepi lengkung kanan. Bingkai yang lebih persegi, dengan
     gambar dipangkas ke arah kanan, membingkai anak itu sendiri. */
  aspect-ratio: 5 / 4;
}
.pt-lp-blob img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 70% 42%;
}

.pt-lp-hias { position: absolute; z-index: 1; }
.pt-lp-matahari { width: 54px; height: 54px; top: -14px; left: -6px; }
.pt-lp-bintang  { width: 26px; height: 26px; top: 6px; right: 2px; }

/* Pelangi di BAWAH KIRI, bukan bawah kanan.
   Di kanan ia terperangkap antara dua tepi: lengkung blob memotongnya
   dari dalam, dan hero (overflow: hidden) memotongnya dari luar — jadi
   ia sentiasa separuh. Di kiri, blob melengkung menjauh dan ruang itu
   kosong, jadi pelangi kelihatan penuh. Ketiga-tiga corat-coret kini
   membentuk segi tiga mengelilingi gambar. */
.pt-lp-pelangi  { width: 72px; height: 40px; bottom: 2px; left: 10px; fill: none; }
@media (max-width: 899px) {
  .pt-lp-matahari { width: 42px; height: 42px; }
  .pt-lp-pelangi  { width: 56px; height: 31px; }
}

/* --------------------------------------------------------- jaminan */

.pt-lp-jaminan {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  margin-top: var(--sp-6);
  padding: var(--sp-5) 0;
  border-bottom: 1px solid var(--line-2);
}
.pt-lp-jamin { text-align: center; padding: 0 var(--sp-3); }
.pt-lp-jamin-ikon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin: 0 auto var(--sp-3);
  border-radius: var(--r-pill);
  font-size: 24px;
}
.pt-lp-jamin-tajuk {
  display: block;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 800;
  color: var(--plum);
}
.pt-lp-jamin-nota {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
}

.pt-lp-biru   { background: #e3effb; color: var(--lp-biru); }
.pt-lp-kuning { background: #fdf0d9; color: var(--lp-kuning); }
.pt-lp-hijau  { background: #ddf3e9; color: var(--lp-hijau); }
.pt-lp-merah  { background: #ffe8e4; color: var(--lp-merah); }

/* -------------------------------------------------- seksyen umum */

.pt-lp-seksyen { margin-top: var(--sp-7); }
.pt-lp-h2 {
  font-family: var(--font-display);
  font-size: clamp(21px, 3vw, 27px);
  font-weight: 800;
  letter-spacing: -.025em;
  color: var(--plum);
  text-align: center;
}
.pt-lp-sub {
  margin-top: 6px;
  font-size: 14px;
  color: var(--muted);
  text-align: center;
}

/* ---------------------------------------------- kad taska popular */

.pt-lp-kad-grid {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  margin-top: var(--sp-5);
}

.pt-lp-kad {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--card);
  box-shadow: var(--sh-1);
  text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s;
}
.pt-lp-kad:hover {
  transform: translateY(-3px);
  border-color: var(--purple-2);
  box-shadow: var(--sh-2);
}

.pt-lp-kad-foto {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  background: var(--purple-soft) center / cover no-repeat;
}
/* Lencana bilangan gambar, di penjuru BAWAH-KANAN gambar kad.

   Penjuru atas-kiri sudah dipegang oleh lencana "JKM disahkan", dan dua
   lencana bertindan di sudut yang sama membaca seperti satu blok. Kanan
   bawah juga tempat mata jatuh terakhir sebelum meninggalkan gambar —
   saat yang tepat untuk memberitahu ada lagi di dalam.

   Latar gelap separa lutsinar, bukan putih seperti lencana JKM: putih
   hilang pada gambar cerah, dan gambar bilik main selalunya cerah. */
.pt-foto-kira {
  position: absolute;
  right: var(--sp-2);
  bottom: var(--sp-2);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  background: rgba(36, 16, 68, .72);
  color: #fff;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .01em;
  line-height: 1.5;
  pointer-events: none;
}

.pt-lp-lencana {
  position: absolute;
  top: var(--sp-2);
  left: var(--sp-2);
  padding: 3px 9px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .94);
  color: var(--ok-ink);
  font-size: 10.5px;
  font-weight: 800;
}

/* Isi kad ialah flex menegak supaya baris harga duduk pada paras yang
   sama merentas satu barisan, walaupun nama taska berlainan panjang. */
.pt-lp-kad-isi {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
}
.pt-lp-kad-nama {
  font-family: var(--font-display);
  font-size: 15.5px;
  font-weight: 800;
  line-height: 1.3;
  color: var(--plum);
}
.pt-lp-kad-lokasi { margin-top: 3px; font-size: 13px; color: var(--lp-biru); font-weight: 700; }
.pt-lp-kad-fakta  { margin-top: 3px; font-size: 12.5px; color: var(--muted); }

.pt-lp-kad-kaki {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-top: auto;
  padding-top: var(--sp-3);
}
.pt-lp-kad-harga small { font-size: 10.5px; color: var(--muted); }
.pt-lp-kad-harga small:first-child { display: block; }
.pt-lp-kad-harga b {
  font-family: var(--font-display);
  font-size: 19px;
  color: var(--lp-pink);
  letter-spacing: -.02em;
}
.pt-lp-kad-btn {
  padding: 7px var(--sp-4);
  border: 1.5px solid var(--purple);
  border-radius: var(--r-pill);
  color: var(--purple);
  font-size: 12.5px;
  font-weight: 800;
  white-space: nowrap;
}
.pt-lp-kad:hover .pt-lp-kad-btn { background: var(--purple); color: #fff; }

/* ------------------------------------------------------- 4 langkah */

.pt-lp-langkah-grid {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  margin-top: var(--sp-5);
}
.pt-lp-langkah {
  position: relative;
  padding: var(--sp-5) var(--sp-4) var(--sp-4);
  border-radius: var(--r-lg);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--sh-1);
  text-align: center;
}
.pt-lp-langkah-no {
  position: absolute;
  top: -13px;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: var(--r-pill);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
}
.pt-lp-langkah-ikon { display: block; font-size: 28px; }
.pt-lp-langkah-tajuk {
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 800;
  color: var(--plum);
}
.pt-lp-langkah-nota {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
}

/* ------------------------------------------- jenama Playtime + menu */

/* Logo rumah + wordmark dua baris, mengikut rujukan Zarul. Nama dan
   sarikata dikumpul dalam satu blok supaya kedua-duanya sejajar kiri
   walaupun ikon berubah saiz. */

/* Menu utama — baris kedua di bawah jenama, bukan di sebelahnya.
   Empat pautan di sebelah logo pada telefon akan memaksa salah satu
   daripadanya keluar skrin; baris sendiri membolehkan ia menatal
   mendatar sebagai gantinya. */
.pt-nav { border-top: 1px solid var(--line-2); }
.pt-nav-in {
  width: min(var(--w-wide), calc(100% - var(--sp-6)));
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: var(--sp-5);

  /* Tatalan mendatar kekal sebagai jaring keselamatan untuk telefon yang
     sangat sempit, tetapi ia TIDAK sepatutnya berlaku dalam keadaan biasa:
     bar tatal disembunyikan, jadi apa-apa yang terkeluar hilang tanpa
     petunjuk. Jurang dirapatkan pada skrin kecil supaya keempat-empat item
     muat tanpa menatal. */
  overflow-x: auto;
  scrollbar-width: none;
  padding: var(--sp-2) 0;
}
.pt-nav-in::-webkit-scrollbar { display: none; }
/* Pada telefon menu MEMBALUTI, bukan menatal.
 *
 * Empat item memerlukan 365px selepas "Cara tempah" memendekkannya;
 * telefon 390px memberi 366px dan telefon 360px memberi 336px. Menatal
 * mendatar dengan bar tatal tersembunyi bermakna "Log masuk centre"
 * hilang di luar skrin tanpa sebarang petunjuk bahawa ia ada — dan itulah
 * satu-satunya jalan centre ke skrin log masuk.
 *
 * Dengan flex-wrap, tiga pautan teks duduk pada baris pertama dan butang
 * log masuk turun ke baris kedua HANYA apabila ia benar-benar tidak muat.
 * Ia melaras sendiri pada setiap lebar, tanpa memerlukan satu lagi
 * perkataan dipotong. */
@media (max-width: 619px) {
  .pt-nav-in {
    gap: var(--sp-3) var(--sp-4);
    flex-wrap: wrap;
    overflow-x: visible;
  }
  .pt-nav-masuk { padding: 6px 12px; }
}

.pt-nav-in a {
  position: relative;
  padding: 5px 0;
  color: var(--ink-2);
  font-size: 13.5px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  transition: color .15s;
}
.pt-nav-in a:hover { color: var(--purple); }
.pt-nav-in a.is-on { color: var(--purple); }
.pt-nav-in a.is-on::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--lp-pink, #ff4d8d);
}

/* Log masuk centre ditolak ke hujung kanan dan diberi bentuk butang —
   ia tindakan, bukan bahagian halaman seperti tiga yang lain. */
.pt-nav-masuk {
  margin-left: auto;
  padding: 6px var(--sp-4) !important;
  border: 1.5px solid var(--purple);
  border-radius: var(--r-pill);
  color: var(--purple) !important;
}
.pt-nav-masuk:hover { background: var(--purple); color: #fff !important; }

.pt-head-kiri { justify-content: flex-start; gap: var(--sp-5); }

/* ------------------------------- halaman butiran centre: dua lajur */

/* Butiran di kiri, pemilih sesi + butang tempah di kanan.
 *
 * Lajur kanan berlebar TETAP (340px) dan bukan pecahan: pemilih slot ialah
 * senarai baris pendek, dan ia tidak menjadi lebih berguna dengan menjadi
 * lebih lebar. Lajur kiri mengambil baki, jadi galeri mendapat ruang yang
 * sebenarnya membantu. */
.pt-sesi-grid {
  display: grid;
  gap: var(--sp-6);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) {
  .pt-sesi-grid { grid-template-columns: minmax(0, 1fr) 340px; }
}

/* Kandungan bacaan di bawah grid dihadkan kepada lebar yang selesa dibaca.
   Polisi pembatalan pada 1120px penuh menjadi baris teks yang terlalu
   panjang untuk diikuti mata. */
.pt-sesi-bawah {
  max-width: 720px;
  margin-top: var(--sp-6);
}

/* Panel sisi melekat semasa menatal pada skrin lebar. Ibu bapa membaca
   polisi dan aktiviti di lajur kiri; butang yang mereka datang untuk tekan
   tidak sepatutnya hilang dari skrin semasa mereka buat begitu. */
@media (min-width: 900px) {
  .pt-sesi-sisi {
    position: sticky;
    top: 76px;
  }
}

/* Dock dalam lajur sisi bukan lagi bar melekat di bawah skrin — ia sudah
   berada dalam panel yang melekat, jadi position: sticky kedua hanya akan
   bertarung dengan yang pertama. */
.pt-dock-sisi {
  position: static;
  margin-top: var(--sp-4);
  padding: 0;
  background: none;
}

/* Pada telefon panel sisi jatuh ke bawah butiran, dan dock kembali melekat
   di bahagian bawah skrin seperti sebelum ini — di situ ia satu-satunya
   cara butang itu kekal dalam jangkauan ibu jari. */
@media (max-width: 899px) {
  .pt-dock-sisi {
    position: sticky;
    bottom: 0;
    padding: var(--sp-3) 0 var(--sp-4);
    background: linear-gradient(180deg, rgba(251, 250, 247, 0), var(--paper) 22%);
  }
}

/* ------------------------------- kalendar ketersediaan 28 hari (P-03) */

/* Teks untuk pembaca skrin sahaja. Setiap kotak membawa ayat penuh
   ("Selasa, 15 Sep — slot terbuka (4 daripada 5 slot)") supaya maklumat
   yang warna sampaikan juga wujud sebagai perkataan. */
.pt-lihat-pembaca {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.pt-kal-hari,
.pt-kal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
}
.pt-kal-hari {
  margin-bottom: 5px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .06em;
  color: var(--muted);
  text-align: center;
}

.pt-kal-kotak {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  aspect-ratio: 1;
  border: 1.5px solid transparent;
  border-radius: var(--r-sm);
  text-decoration: none;
  line-height: 1;
  transition: transform .12s ease, border-color .12s;
}
a.pt-kal-kotak:hover { transform: translateY(-2px); border-color: var(--purple); }
a.pt-kal-kotak:focus-visible { outline: 3px solid rgba(93, 47, 165, .35); outline-offset: 1px; }

.pt-kal-no   { font-size: 12.5px; font-weight: 800; line-height: 1.05; }
.pt-kal-slot { font-size: 9.5px; font-weight: 700; opacity: .75; }

/* Singkatan bulan dalam kotak pertama setiap bulan. Ia duduk di bawah
   nombor dan bukan di sebelahnya: kotak selebar satu pertujuh lajur, dan
   "1 Okt" pada satu baris memaksa nombor mengecil pada telefon. */
.pt-kal-no i {
  display: block;
  font-size: 8.5px;
  font-style: normal;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .85;
}

/* Kapsyen julat bulan di atas grid. */
.pt-kal-kapsyen {
  margin: 0 0 var(--sp-2);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  color: var(--plum);
}

/* "untuk 1 slot" di bawah harga — kecil, tetapi ia yang menghalang
   harga daripada dibaca sebagai harga untuk kesemua baki slot. */
.pt-slot-unit {
  margin-top: -3px;
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
}

/* Tajuk hari yang dipilih, dengan cip bilangan slot di sebelahnya. */
.pt-kal-tajuk {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
}

/* Empat keadaan.
 *
 * Cerah = terbuka, pekat = tinggal separuh — skim Zarul. Kotak penuh dan
 * tutup kekal kelabu dan tidak boleh diklik, tetapi DIBEZAKAN antara satu
 * sama lain: "penuh" membawa tanda silang kerana ia bermakna cuba semula
 * nanti, manakala "tutup" kosong kerana ia bermakna cuba hari lain. */
.pt-kal-kotak.is-ada {
  background: #e4f6ec;
  border-color: #bfe7d1;
  color: #14663f;
}
.pt-kal-kotak.is-sikit {
  background: #1f7a52;
  border-color: #1f7a52;
  color: #fff;
}
.pt-kal-kotak.is-sikit .pt-kal-slot { opacity: .9; }
.pt-kal-kotak.is-penuh {
  background: var(--stop-bg);
  border-color: var(--stop-line);
  color: var(--stop-ink);
  cursor: not-allowed;
}
.pt-kal-kotak.is-tutup {
  background: var(--line-2);
  color: var(--muted);
}
.pt-kal-kosong { aspect-ratio: 1; }

/* Hari yang sedang dilihat. Cincin ungu di luar sempadan keadaan, supaya
   "hari mana saya berada" dan "hari ini ada berapa slot" tidak bertarung
   untuk warna yang sama. */
.pt-kal-kotak.is-pilih {
  box-shadow: 0 0 0 2px var(--purple);
  border-color: var(--purple);
}

/* Petunjuk dalam dua lajur, bukan baris yang membaluti.
   Dengan flex-wrap, lima item meninggalkan "Belum dibuka" sendirian pada
   baris kedua dan petunjuk itu kelihatan seperti tersasar. Dua lajur
   memberi susunan yang sama pada setiap lebar. */
.pt-kal-kunci {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 5px var(--sp-3);
  margin-top: var(--sp-3);
  font-size: 11px;
  color: var(--muted);
}
.pt-kal-kunci span { display: inline-flex; align-items: center; gap: 5px; }
.pt-kal-kunci i {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  border: 1.5px solid transparent;
}
.pt-kal-kunci i.is-ada   { background: #e4f6ec; border-color: #bfe7d1; }
.pt-kal-kunci i.is-sikit { background: #1f7a52; }
.pt-kal-kunci i.is-penuh { background: var(--stop-bg); border-color: var(--stop-line); }
.pt-kal-kunci i.is-tutup { background: var(--line-2); }

/* "Belum dibuka" — jadual belum dijana untuk hari itu, bukan centre tutup.
   Sempadan putus-putus dan bukan warna baharu: ia membawa maksud "belum
   ada apa-apa di sini lagi" tanpa menambah warna kelima untuk dihafal. */
.pt-kal-kotak.is-belum {
  background: transparent;
  border: 1.5px dashed var(--line);
  color: var(--muted);
  opacity: .7;
}
.pt-kal-kunci i.is-belum { background: transparent; border: 1.5px dashed var(--line); }

/* Kad centre yang penuh: diredupkan tetapi masih boleh diklik.
   Berbeza daripada .pt-off yang lama, yang mematikan penunjuk sepenuhnya
   — kalendar di halaman centre ialah satu-satunya skrin yang menjawab
   "bila saya boleh dapat tempat", jadi jalan ke sana mesti kekal terbuka. */
.pt-listing.pt-penuh { opacity: .72; }
.pt-listing.pt-penuh:hover { opacity: 1; }

/* =====================================================================
   Konsol: cangkerang sidebar (admin + centre)
   =====================================================================
   Bentuk diambil daripada templat rujukan Zarul — sidebar tetap di kiri,
   kepala nipis, kandungan menatal. Kodnya ditulis di sini dan bukan
   diimport, supaya konsol kekal dalam sistem .pt-* yang sama seperti
   seluruh tapak.
   ===================================================================== */

.pt-main-konsol { padding: 0; }

.pt-konsol {
  display: flex;
  align-items: flex-start;
  min-height: calc(100vh - 0px);
}

/* ------------------------------------------------------------ sidebar */

.pt-sb {
  position: sticky;
  top: 0;
  flex: none;
  display: flex;
  flex-direction: column;
  width: 236px;
  height: 100vh;
  padding: var(--sp-4) var(--sp-3);
  background: #fff;
  border-right: 1px solid var(--line);
}

.pt-sb-jenama {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0 var(--sp-2) var(--sp-4);
}
.pt-sb-jenama-teks {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -.04em;
  line-height: 1.15;
  color: var(--plum);
}
.pt-sb-jenama-teks i { font-style: normal; color: var(--coral); }

.pt-sb-menu { display: flex; flex-direction: column; gap: 2px; }

.pt-sb-pautan {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 40px;
  padding: 0 var(--sp-3);
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  transition: background .13s, color .13s;
}
.pt-sb-pautan:hover { background: var(--purple-soft); color: var(--purple); }
.pt-sb-pautan.is-on { background: var(--purple); color: #fff; }
.pt-sb-ikon { width: 19px; height: 19px; flex: none; }

/* Kaki sidebar ditolak ke bawah, jadi "Keluar" sentiasa di tempat yang
   sama tanpa mengira panjang menu. */
.pt-sb-kaki {
  margin-top: auto;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line-2);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Penanda "buka dalam tab baharu" pada pautan sidebar. Kecil dan pudar:
   ia memberitahu apa yang akan berlaku tanpa bersaing dengan label. */
/* Jalur "anda log masuk sebagai admin/centre" di atas tapak awam.

   Kuning amaran, bukan ungu jenama: ia bukan sebahagian tapak yang ibu
   bapa lihat, dan ia perlu kelihatan seperti sesuatu yang tidak
   sepatutnya ada di situ. Ia melekat di atas supaya jalan pulang tidak
   hilang selepas menatal. */
.pt-jalur-konsol {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2) var(--sp-4);
  padding: 9px var(--sp-4);
  background: var(--warn-bg, #fff3d1);
  border-bottom: 1px solid var(--warn-line, #f2dfa4);
  color: var(--warn-ink, #6b4f00);
  font-size: 12.5px;
  line-height: 1.45;
  text-align: center;
}
.pt-jalur-konsol a {
  flex: 0 0 auto;
  font-weight: 800;
  color: inherit;
  text-decoration: underline;
  white-space: nowrap;
}

.pt-sb-luar { margin-left: 4px; font-size: 11px; opacity: .55; }

.pt-sb-keluar {
  width: 100%;
  min-height: 38px;
  margin-top: 2px;
  border: 1.5px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--stop-ink);
  font-size: 13px;
  font-weight: 800;
}
.pt-sb-keluar:hover { border-color: var(--stop-line); background: var(--stop-bg); }

/* ---------------------------------------------------------- kandungan */

.pt-konsol-isi {
  flex: 1;
  min-width: 0;                     /* jadual lebar tidak menolak sidebar */
  padding: 0 var(--sp-5) var(--sp-8);
}

.pt-konsol-kepala {
  position: sticky;
  top: 0;
  z-index: 15;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 62px;
  margin: 0 calc(var(--sp-5) * -1) var(--sp-2);
  padding: 0 var(--sp-5);
  background: rgba(251, 250, 247, .9);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line-2);
}
.pt-konsol-tajuk { display: flex; flex-direction: column; line-height: 1.2; }
.pt-konsol-tajuk b {
  font-family: var(--font-display);
  font-size: 16px;
  color: var(--plum);
}
.pt-konsol-tajuk small { font-size: 12px; color: var(--muted); }

/* ------------------------------------------- buka/tutup pada telefon */

/* Butang hamburger dan lapisan gelap hanya wujud di bawah 900px; pada
   skrin lebar sidebar sentiasa kelihatan dan suis tidak berkaitan. */
.pt-sb-butang,
.pt-sb-litup { display: none; }

@media (max-width: 899px) {
  .pt-sb {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 40;
    transform: translateX(-100%);
    transition: transform .2s ease;
    box-shadow: var(--sh-3);
  }
  .pt-sb-suis:checked ~ .pt-konsol .pt-sb { transform: translateX(0); }

  .pt-sb-litup {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 35;
    background: rgba(20, 8, 40, .45);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
  }
  .pt-sb-suis:checked ~ .pt-konsol .pt-sb-litup { opacity: 1; pointer-events: auto; }

  .pt-sb-butang {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 38px;
    height: 38px;
    padding: 0 8px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--card);
    cursor: pointer;
  }
  .pt-sb-butang span {
    display: block;
    height: 2px;
    border-radius: 2px;
    background: var(--plum);
  }

  .pt-konsol-isi { padding: 0 var(--sp-4) var(--sp-7); }
  .pt-konsol-kepala { margin: 0 calc(var(--sp-4) * -1) var(--sp-2); padding: 0 var(--sp-4); }
}

/* ----------------------------------------------------------- carta */

/* Kad carta. Tinggi ditetapkan supaya ApexCharts mempunyai kotak untuk
   diukur — carta dalam bekas setinggi auto akan dilukis setinggi sifar. */
.pt-carta-grid {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  margin-top: var(--sp-4);
}
.pt-carta {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  box-shadow: var(--sh-1);
}
.pt-carta-tajuk {
  display: block;
  margin-bottom: var(--sp-2);
  font-family: var(--font-display);
  font-size: 14.5px;
  font-weight: 800;
  color: var(--plum);
}
.pt-carta-kotak { min-height: 260px; }

/* ------------------------------- dashboard: susun atur tiga lajur */

/* Carta lebar di kiri, donat di tengah, panel bertindan di kanan —
   bentuk yang sama seperti rujukan Zarul. Runtuh kepada satu lajur di
   bawah 1100px, di mana tiga lajur bermakna tiga jalur kurus. */
.pt-dash-grid {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: 1fr;
  margin-top: var(--sp-4);
  align-items: start;
}
@media (min-width: 1100px) {
  .pt-dash-grid { grid-template-columns: 1.45fr 1fr; }
}
@media (min-width: 1500px) {
  .pt-dash-grid { grid-template-columns: 1.5fr 1fr 1fr; }
}

/* Grid carta dalaman tidak lagi membuat lajurnya sendiri — grid induk
   sudah melakukannya. */
.pt-dash-grid .pt-carta-grid {
  display: contents;
  margin: 0;
}

/* --------------------------------------------- kad statistik berikon */

/* Ikon dalam bulatan berwarna, mengikut rujukan. Jalur tepi yang lama
   digantikan: bulatan membawa warna DAN memberi kad titik fokus, yang
   jalur nipis tidak boleh lakukan. */
.pt-statkad::before { display: none; }
.pt-statkad { padding: var(--sp-4); }

.pt-statkad-atas {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 38px;
}
.pt-statkad-ikon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: var(--r-pill);
  font-size: 18px;
  background: color-mix(in srgb, var(--pt-stat-warna) 13%, #fff);
}
.pt-statkad-atas .pt-statkad-label { min-height: 0; }

.pt-statkad-angka { margin-top: var(--sp-3); }

/* ----------------------------------------------------- panel sisi */

.pt-panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  box-shadow: var(--sh-1);
}
.pt-panel + .pt-panel { margin-top: var(--sp-4); }
.pt-panel-kepala {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.pt-panel-kepala .pt-carta-tajuk { margin: 0; }
.pt-panel-lagi {
  padding: 4px var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  color: var(--purple);
  font-size: 11.5px;
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
}
.pt-panel-lagi:hover { border-color: var(--purple-2); }

/* ---- suapan aktiviti ---- */

.pt-aktiviti, .pt-payout { list-style: none; margin: 0; padding: 0; }
.pt-aktiviti li, .pt-payout li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-top: 1px solid var(--line-2);
}
.pt-aktiviti li:first-child, .pt-payout li:first-child { border-top: none; padding-top: 0; }

.pt-aktiviti-ikon {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: var(--r-sm);
  font-size: 15px;
}
.pt-aktiviti-teks { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pt-aktiviti-teks b {
  font-size: 13px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--ink);
}
.pt-aktiviti-teks small { font-size: 11.5px; color: var(--muted); }
.pt-aktiviti-masa {
  flex: none;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  padding-top: 2px;
}

/* ---- senarai payout ---- */

.pt-payout-huruf {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: var(--r-sm);
  background: var(--purple-soft);
  color: var(--purple);
  font-family: var(--font-display);
  font-weight: 800;
}
.pt-payout-teks { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.pt-payout-teks b {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pt-payout-teks small { font-size: 11.5px; color: var(--muted); }
.pt-payout-wang { flex: none; text-align: right; display: flex; flex-direction: column; }
.pt-payout-wang b {
  font-family: var(--font-display);
  font-size: 14px;
  color: var(--plum);
}
.pt-payout-wang small { font-size: 11px; color: var(--coral); font-weight: 700; }

/* Dua panel sisi bertindan dalam SATU sel grid, bukan dua sel
   berasingan — jika tidak, panel kedua terkeluar ke baris baharu dan
   meninggalkan lubang di sebelah carta. */
.pt-panel-lajur { display: flex; flex-direction: column; gap: var(--sp-4); }
.pt-panel-lajur .pt-panel + .pt-panel { margin-top: 0; }

/* ---------------------------------------------------------- toast */

/* Mesej kilat di penjuru kanan atas, mengikut toastr.js dalam PTPK.
   position: fixed supaya ia tidak menolak kandungan ke bawah — kotak
   nota lama menganjak keseluruhan halaman setiap kali satu muncul. */
.pt-toast-bekas {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 80;
  width: min(380px, calc(100vw - 32px));
}

/* Warna diambil daripada token semantik yang sama dengan .pt-note, dan
   bukan warna pekat tersendiri. Versi pertama menggunakan latar gelap
   seperti toastr lalai; ia betul untuk PTPK tetapi kelihatan berat dan
   asing di atas halaman Playtime yang serba lembut. Setiap jenis hanya
   menukar tiga pemboleh ubah di bawah — selebihnya satu peraturan. */
.pt-toast.is-ok     { --t-bg: var(--ok-bg);   --t-ink: var(--ok-ink);   --t-line: var(--ok-line); }
.pt-toast.is-ralat  { --t-bg: var(--stop-bg); --t-ink: var(--stop-ink); --t-line: var(--stop-line); }
.pt-toast.is-amaran { --t-bg: var(--warn-bg); --t-ink: var(--warn-ink); --t-line: var(--warn-line); }

.pt-toast {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  overflow: hidden;
  padding: var(--sp-4);
  border: 1px solid var(--t-line);
  border-radius: var(--r-lg);
  background: var(--t-bg);
  box-shadow: var(--sh-3);
  color: var(--t-ink);
  animation: pt-toast-masuk .22s ease-out;
}
.pt-toast.is-keluar { animation: pt-toast-keluar .2s ease-in forwards; }

@keyframes pt-toast-masuk {
  from { opacity: 0; transform: translateX(24px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes pt-toast-keluar {
  to { opacity: 0; transform: translateX(24px); }
}

/* Lencana bulat membawa simbol jenis. Warna sahaja tidak membawa makna;
   simbol dan tajuk di sebelahnya menyampaikan perkara yang sama kepada
   sesiapa yang tidak membezakan hijau daripada merah. */
.pt-toast-ikon {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--r-pill);
  background: var(--card);
  border: 1px solid var(--t-line);
  font-size: 14px;
  font-weight: 800;
  line-height: 1;
}

.pt-toast-isi { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pt-toast-isi b {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 800;
}
.pt-toast-isi span { font-size: 13.5px; line-height: 1.5; }

.pt-toast-tutup {
  flex: none;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: var(--r-sm);
  background: transparent;
  color: inherit;
  opacity: .55;
  font-size: 17px;
  line-height: 1;
}
.pt-toast-tutup:hover { opacity: 1; background: var(--card); }

/* Bar kemajuan mengecil selama lima saat — petunjuk visual berapa lama
   lagi sebelum toast hilang, sama seperti progressBar toastr. */
.pt-toast-bar {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: 100%;
  background: currentColor;
  opacity: .28;
  transform-origin: left;
  animation: pt-toast-bar 5s linear forwards;
}
.pt-toast.is-tahan .pt-toast-bar { animation-play-state: paused; }

@keyframes pt-toast-bar { to { transform: scaleX(0); } }

/* Pengguna yang meminta kurang animasi tetap mendapat mesej — cuma tanpa
   gelongsor masuk dan tanpa bar yang bergerak. */
@media (prefers-reduced-motion: reduce) {
  .pt-toast { animation: none; }
  .pt-toast-bar { display: none; }
}

/* ==========================================================================
   GARIS STATUS TEMPAHAN

   Satu komponen, tiga pembaca: ibu bapa, centre, admin. Mendatar apabila
   ada ruang, menegak pada telefon — bukan kerana telefon sempit, tetapi
   kerana lima label mendatar pada 360px menjadi lima perkataan terpotong.
   ========================================================================== */
.pt-garis {
  display: grid;
  gap: 0;
  margin-top: var(--sp-4);
}
.pt-garis-langkah {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: 0 0 var(--sp-4);
}

/* Garis penyambung ialah ::before pada langkah, bukan elemen berasingan:
   ia bermula di bawah titik dan berhenti pada titik seterusnya, jadi ia
   tidak pernah terjuntai selepas langkah terakhir. */
.pt-garis-langkah::before {
  content: "";
  position: absolute;
  left: 13px;
  top: 28px;
  bottom: 0;
  width: 2px;
  background: var(--line);
}
.pt-garis-langkah:last-child { padding-bottom: 0; }
.pt-garis-langkah:last-child::before { display: none; }
.pt-garis-langkah.is-selesai::before { background: var(--ok-line, #b9e0c6); }

.pt-garis-titik {
  position: relative;
  z-index: 1;
  flex: 0 0 28px;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: var(--card);
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
}
.pt-garis-teks { display: grid; gap: 1px; font-size: 13.5px; line-height: 1.4; }
.pt-garis-teks b { color: var(--ink-2); font-weight: 800; }
.pt-garis-nota { color: var(--muted); font-size: 12px; }

.pt-garis-langkah.is-selesai .pt-garis-titik {
  border-color: var(--ok-line, #b9e0c6);
  background: var(--ok-bg, #e7f6ec);
  color: var(--ok-ink);
}
.pt-garis-langkah.is-selesai .pt-garis-teks b { color: var(--ink); }

/* Langkah SEMASA ialah satu-satunya yang berwarna jenama. Ia menjawab
   "jadi sekarang apa?" dalam satu pandangan, tanpa membaca apa-apa. */
.pt-garis-langkah.is-kini .pt-garis-titik {
  border-color: var(--purple);
  background: var(--purple);
  color: #fff;
  box-shadow: 0 0 0 4px var(--purple-soft);
}
.pt-garis-langkah.is-kini .pt-garis-teks b { color: var(--purple); }
.pt-garis-langkah.is-belum .pt-garis-teks b,
.pt-garis-langkah.is-mati .pt-garis-teks b { color: var(--muted); font-weight: 700; }
.pt-garis-langkah.is-mati .pt-garis-titik { opacity: .55; }

.pt-garis-henti {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--stop-line);
  border-radius: var(--r-lg);
  background: var(--stop-bg);
  color: var(--stop-ink);
  font-size: 13px;
  line-height: 1.5;
}
.pt-garis-henti-tanda {
  flex: 0 0 22px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--stop-ink);
  color: #fff;
  font-size: 14px;
  font-weight: 800;
  line-height: 1;
}

/* Mendatar apabila ada ruang: lima langkah sebaris, garis penyambung
   membentang antara titik. */
@media (min-width: 720px) {
  .pt-garis { grid-template-columns: repeat(5, 1fr); gap: var(--sp-2); }
  .pt-garis-langkah {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-2);
    padding: 0 var(--sp-2) 0 0;
  }
  .pt-garis-langkah::before {
    left: 28px;
    right: 0;
    top: 13px;
    bottom: auto;
    width: auto;
    height: 2px;
  }
  .pt-garis-teks { font-size: 12.5px; }
  .pt-garis-nota { font-size: 11.5px; }
}

/* Mod padat garis status — lima titik dalam sel jadual.

   Saiz dipilih supaya lima titik plus jurang sama lebar dengan satu cip
   status di atasnya: dua baris yang berjajar membaca sebagai satu blok,
   bukan dua maklumat berasingan. */
.pt-garis-padat {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 5px;
}
.pt-garis-padat-titik {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--line);
}
.pt-garis-padat-titik.is-selesai { background: var(--ok-ink); }
.pt-garis-padat-titik.is-kini {
  width: 9px;
  height: 9px;
  background: var(--purple);
  box-shadow: 0 0 0 2px var(--purple-soft);
}
/* Perjalanan yang terhenti: titik yang sudah dilalui kekal, tetapi
   warnanya bertukar merah supaya baris itu tidak terbaca sebagai
   "separuh jalan dan masih bergerak". */
.pt-garis-padat.is-henti .pt-garis-padat-titik.is-selesai { background: var(--stop-ink); }
