/* ============================================================
   Page: Ticketing (WebDev) — 360eDash
   Design tokens sama persis dengan halaman lain (lihat
   css/admin-view.css) supaya terasa satu sistem. Class di-prefix
   "tk-" supaya tidak bentrok dengan halaman lain.

   Catatan: pages/ticketing.html dimuat sebagai FRAGMENT murni,
   TIDAK punya wrapper .edash-layout/.edash-main/.edash-content/
   #sidebar-root/#header-root sendiri — semua sudah didefinisikan
   sekali oleh shell utama di index.html. JANGAN tambahkan rule
   itu lagi di sini.
============================================================= */
:root {
  --tk-primary: #0f6a71;
  --tk-primary-dark: #0b4f54;
  --tk-primary-soft: #e4f1f1;

  --tk-success: #2f9e6e;
  --tk-warning: #e3a21a;
  --tk-danger: #d64545;
  --tk-info: #3e7cb1;
  --tk-success-soft: #e6f5ef;
  --tk-warning-soft: #fbf1e0;
  --tk-danger-soft: #fbe9e9;
  --tk-info-soft: #e9f0f7;

  --tk-ink: #25343f;
  --tk-muted: #7c8b8d;
  --tk-border: #e7edee;
  --tk-surface: #ffffff;
  --tk-page-bg: #f4f7f7;

  /* Activity heatmap intensity scale (0 = no activity that day ... 4 =
     busiest days) — kept as its own token family so dark mode can just
     redefine these 5 like it already does for the other --tk-* tokens. */
  --tk-heat-0: #eef3f3;
  --tk-heat-1: #cfe8e6;
  --tk-heat-2: #8fd0cb;
  --tk-heat-3: #3fa79e;
  --tk-heat-4: #0f6a71;
}

#sidebar-root:empty, #header-root:empty { display: none; }

.tk-wrap { width: 100%; max-width: 1320px; margin: 0 auto; }

/* ---------- Head ---------- */
.tk-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.tk-head h1 { font-size: 26px; font-weight: 700; letter-spacing: -0.01em; color: var(--tk-ink); margin-bottom: 4px; }
.tk-head p { font-size: 13px; font-weight: 400; line-height: 1.6; color: var(--tk-muted); max-width: 560px; }

/* ---------- Buttons ---------- */
.tk-btn {
  border: none;
  border-radius: 10px;
  padding: 11px 18px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.05s ease;
}
.tk-btn:active { transform: translateY(1px); }
.tk-btn-primary { background: var(--tk-primary); color: #fff; }
.tk-btn-success { background: var(--tk-success); color: #fff; }
.tk-btn-danger { background: var(--tk-danger); color: #fff; }
.tk-btn-success:hover { filter: brightness(1.08); }
.tk-btn-danger:hover { filter: brightness(1.08); }
.tk-btn-primary:hover { background: var(--tk-primary-dark); }
.tk-btn-secondary { background: var(--tk-page-bg); color: var(--tk-ink); border: 1px solid var(--tk-border); }
.tk-btn-secondary:hover { background: #e9eeee; }

/* ---------- Stat cards ---------- */
.tk-stats {
  display: grid;
  /* FIX: sebelumnya auto-fit + minmax(200px,1fr) -- 6 kartu butuh sekitar
     1280px (6*200px + 5*16px gap), sedikit lebih lebar dari kontainer di
     zoom 100%, jadi browser cuma muat 5 kartu per baris dan 1 kartu
     kepental ke baris ke-2. Dipaksa PERSIS 6 kolom di lebar desktop (>1200px)
     supaya selalu 1 baris; breakpoint di bawah 1200px (lihat media query
     paling bawah file ini) tetap override ke kolom lebih sedikit seperti
     sebelumnya, tidak berubah. */
  grid-template-columns: repeat(6, 1fr);
  gap: 16px;
  margin-bottom: 20px;
}
.tk-stat-card {
  background: var(--tk-surface);
  border: 1px solid var(--tk-border);
  border-radius: 14px;
  padding: 18px 20px;
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
  display: flex;
  align-items: center;
  gap: 14px;
}
.tk-stat-icon {
  width: 42px; height: 42px;
  border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
  background: var(--tk-primary-soft);
  color: var(--tk-primary);
}
.tk-stat-icon.is-danger { background: var(--tk-danger-soft); color: var(--tk-danger); }
.tk-stat-icon.is-warning { background: var(--tk-warning-soft); color: var(--tk-warning); }
.tk-stat-icon.is-success { background: var(--tk-success-soft); color: var(--tk-success); }
.tk-stat-icon.is-info { background: var(--tk-info-soft); color: var(--tk-info); }
.tk-stat-label { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--tk-muted); margin-bottom: 4px; }
.tk-stat-value { font-size: 20px; font-weight: 700; color: var(--tk-ink); line-height: 1.1; }

/* ---------- Activity heatmap (GitHub-style "tickets worked per day") ---------- */
/* --tk-heat-cell/--tk-heat-gap/--tk-heat-monthgap are recalculated in
   JS every render (see tkFitHeatmapMetrics() in ticketing.js) so the
   whole Aug-Jul strip fits the card's current width without a
   horizontal scrollbar -- the px values below are just the fallback
   used before the first measurement (and if JS ever fails to run). */
.tk-heatmap-card {
  --tk-heat-cell: 11px;
  --tk-heat-gap: 3px;
  --tk-heat-monthgap: 8px;
  background: var(--tk-surface);
  border: 1px solid var(--tk-border);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
  margin-bottom: 20px;
  /* Header/filters stay pinned to the top; the graphic group below is
     free to grow and center itself in whatever height is left over
     when this card is stretched to match a taller Leaderboard card
     alongside it (see .tk-heatmap-graphic + .tk-lb-heatmap-row) --
     instead of sitting glued to the top with dead space underneath. */
  display: flex;
  flex-direction: column;
}
.tk-heatmap-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.tk-heatmap-head h3 { font-size: 15px; font-weight: 700; color: var(--tk-ink); margin-bottom: 2px; }
.tk-heatmap-subtitle { font-size: 12px; color: var(--tk-muted); }

/* Group holding the actual chart (scroll strip + legend) -- flexes to
   fill any leftover height in the card and centers its contents in
   it, so the graphic reads as intentionally placed rather than
   stranded at the top with a big blank area below it. Has no visual
   effect when the card's height is only as tall as its own content
   (mobile/tablet stacked layout, ≤900px). */
.tk-heatmap-graphic {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 0;
}

/* Horizontal scroller -- kept as a graceful fallback for viewports too
   narrow for the squares to stay legible even at the minimum size (see
   TK_HEATMAP_CELL_MIN in ticketing.js); on anything roomier, JS sizes
   the cells to fit exactly so this never actually needs to scroll. */
.tk-heatmap-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 2px;
}
.tk-heatmap-inner { display: inline-block; min-width: 100%; }

/* 2 baris @ 6 bulan (bukan 1 strip 12-bulan) supaya tinggi card ini enak
   dibaca. flex column + align-items:center: kalau cap cell (lihat
   TK_HEATMAP_CELL_MAX di ticketing.js) bikin grid nggak 100% mepet ke
   tepi card, sisa ruangnya kebagi simetris kiri-kanan -- bukan numpuk
   jadi gap kosong sepihak di kanan. */
.tk-heatmap-row-block { display: flex; flex-direction: column; align-items: center; }
.tk-heatmap-row-block + .tk-heatmap-row-block { margin-top: 12px; }

.tk-heatmap-months {
  display: flex;
  gap: var(--tk-heat-gap);
  margin-left: 30px; /* aligns with grid start, past the day-label column */
  height: 14px;
  margin-bottom: 3px;
}
.tk-heatmap-month-label {
  flex: 0 0 auto;
  text-align: center;
  font-size: 10px;
  font-weight: 600;
  color: var(--tk-muted);
  white-space: nowrap;
}
/* Extra breathing room where one month's column block ends and the next
   begins, so months read as distinct blocks instead of one long ribbon. */
.tk-heatmap-month-label.tk-heatmap-month-gap { margin-left: var(--tk-heat-monthgap); }

.tk-heatmap-body { display: flex; gap: 6px; }
.tk-heatmap-daylabels {
  display: grid;
  grid-template-rows: repeat(7, var(--tk-heat-cell));
  gap: var(--tk-heat-gap);
  width: 24px;
  flex-shrink: 0;
}
.tk-heatmap-daylabels span {
  font-size: 9.5px;
  font-weight: 500;
  color: var(--tk-muted);
  line-height: var(--tk-heat-cell);
}

.tk-heatmap-grid {
  display: flex;
  gap: var(--tk-heat-gap);
}
.tk-heatmap-monthblock {
  display: flex;
  gap: var(--tk-heat-gap);
}
.tk-heatmap-monthblock.tk-heatmap-month-gap { margin-left: var(--tk-heat-monthgap); }
.tk-heatmap-week {
  display: grid;
  grid-template-rows: repeat(7, var(--tk-heat-cell));
  gap: var(--tk-heat-gap);
}
.tk-heatmap-cell {
  width: var(--tk-heat-cell);
  height: var(--tk-heat-cell);
  border-radius: 3px;
  background: var(--tk-heat-0);
  border: 1px solid rgba(0, 0, 0, 0.04);
}
.tk-heatmap-cell.tk-heat-0 { background: var(--tk-heat-0); }
.tk-heatmap-cell.tk-heat-1 { background: var(--tk-heat-1); border-color: transparent; }
.tk-heatmap-cell.tk-heat-2 { background: var(--tk-heat-2); border-color: transparent; }
.tk-heatmap-cell.tk-heat-3 { background: var(--tk-heat-3); border-color: transparent; }
.tk-heatmap-cell.tk-heat-4 { background: var(--tk-heat-4); border-color: transparent; }
.tk-heatmap-cell.tk-heat-pad { background: transparent; border-color: transparent; }

.tk-heatmap-legend {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 12px;
  font-size: 10.5px;
  color: var(--tk-muted);
  flex-shrink: 0;
}
.tk-heatmap-legend .tk-heatmap-cell { cursor: default; }

/* Floating hover tooltip -- positioned via JS (fixed, so it's never
   clipped by the heatmap's horizontal scroll container) instead of the
   native title attribute, which is slow to appear and easy to miss. */
.tk-heatmap-tooltip {
  position: fixed;
  left: 0;
  top: 0;
  transform: translate(-50%, calc(-100% - 8px));
  /* SENGAJA warna gelap tetap (bukan var(--tk-ink), yang di dark mode
     jadi TERANG -- background terang + teks putih hardcode di bawah
     jadi nyaris tidak kebaca, itu bug-nya). Tooltip kecil begini aman
     selalu gelap+teks putih di kedua tema, sama kayak heatmap tooltip
     GitHub yang tidak ikut berubah sesuai tema halaman. */
  background: #1f2937;
  color: #fff;
  font-size: 11.5px;
  font-weight: 600;
  padding: 5px 9px;
  border-radius: 6px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.1s ease;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  z-index: 1000;
}
.tk-heatmap-tooltip.is-visible { opacity: 1; visibility: visible; }

/* ---------- Toolbar ---------- */
.tk-toolbar {
  background: var(--tk-surface);
  border: 1px solid var(--tk-border);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.tk-search { position: relative; flex: 1 1 240px; min-width: 200px; }
.tk-search i { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); font-size: 13px; color: var(--tk-muted); }
.tk-search input {
  width: 100%;
  font-family: inherit;
  border: 1px solid var(--tk-border);
  border-radius: 9px;
  padding: 10px 12px 10px 34px;
  font-size: 13.5px;
  color: var(--tk-ink);
  background: var(--tk-page-bg);
  outline: none;
}
.tk-search input:focus { border-color: var(--tk-primary); box-shadow: 0 0 0 3px var(--tk-primary-soft); background: var(--tk-surface); }

.tk-toolbar select {
  font-family: inherit;
  border: 1px solid var(--tk-border);
  border-radius: 9px;
  padding: 10px 12px;
  font-size: 13.5px;
  color: var(--tk-ink);
  background: var(--tk-surface);
  outline: none;
  min-width: 150px;
}
.tk-toolbar select:focus { border-color: var(--tk-primary); box-shadow: 0 0 0 3px var(--tk-primary-soft); }

/* ---------- Status subtabs ---------- */
.tk-status-tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
  background: var(--tk-surface);
  border: 1px solid var(--tk-border);
  border-radius: 12px;
  padding: 6px;
  margin-bottom: 18px;
}
.tk-status-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  flex: 1 1 0;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--tk-muted);
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 8px 14px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.tk-status-tab:hover { background: var(--tk-page-bg); color: var(--tk-ink); }
.tk-status-tab.is-active { background: var(--tk-primary); color: #fff; }
.tk-status-tab-count {
  font-size: 11px;
  font-weight: 700;
  background: var(--tk-page-bg);
  color: var(--tk-muted);
  border-radius: 999px;
  padding: 1px 7px;
  min-width: 18px;
  text-align: center;
}
.tk-status-tab.is-active .tk-status-tab-count { background: rgba(255, 255, 255, 0.25); color: #fff; }

.tk-status-approve-hint { margin-top: 6px; font-size: 12px; color: var(--tk-muted); }

/* ---------- Table ---------- */
.tk-table-card {
  background: var(--tk-surface);
  border: 1px solid var(--tk-border);
  border-radius: 14px;
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
  overflow: hidden;
  margin-bottom: 28px;
}
.tk-table-scroll { overflow-x: auto; }
table.tk-table { width: 100%; border-collapse: collapse; min-width: 880px; }
.tk-table th {
  text-align: left;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--tk-muted);
  padding: 13px 16px;
  background: var(--tk-page-bg);
  border-bottom: 1px solid var(--tk-border);
  white-space: nowrap;
}
.tk-table td {
  padding: 13px 16px;
  font-size: 13.5px;
  color: var(--tk-ink);
  border-bottom: 1px solid var(--tk-border);
  vertical-align: middle;
  white-space: nowrap;
}
.tk-table tbody tr:last-child td { border-bottom: none; }
.tk-table tbody tr:hover { background: var(--tk-page-bg); }

.tk-cell-title { font-weight: 600; white-space: normal; max-width: 280px; }
.tk-cell-id { font-family: 'SFMono-Regular', Consolas, monospace; font-size: 11.5px; color: var(--tk-muted); margin-top: 1px; }
.tk-cell-unassigned { color: var(--tk-muted); font-style: italic; }

/* ---------- Pills (type / priority / status) ---------- */
.tk-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.tk-pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex-shrink: 0; }

.tk-pill-type-bug { background: var(--tk-danger-soft); color: var(--tk-danger); }
.tk-pill-type-feature-request { background: var(--tk-info-soft); color: var(--tk-info); }
.tk-pill-type-ui-ux-feedback { background: var(--tk-primary-soft); color: var(--tk-primary); }
.tk-pill-type-data-issue { background: var(--tk-warning-soft); color: var(--tk-warning); }
.tk-pill-type-performance-issue { background: var(--tk-danger-soft); color: var(--tk-danger); }
.tk-pill-type-question { background: var(--tk-page-bg); color: var(--tk-muted); }
.tk-pill-type-other { background: var(--tk-page-bg); color: var(--tk-muted); }

.tk-pill-priority-low { background: var(--tk-page-bg); color: var(--tk-muted); }
.tk-pill-priority-medium { background: var(--tk-warning-soft); color: var(--tk-warning); }
.tk-pill-priority-high { background: var(--tk-danger-soft); color: var(--tk-danger); }
.tk-pill-priority-critical { background: var(--tk-danger); color: #fff; }

.tk-pill-status-open { background: var(--tk-info-soft); color: var(--tk-info); }
.tk-pill-status-in_progress { background: var(--tk-warning-soft); color: var(--tk-warning); }
.tk-pill-status-waiting_approval { background: var(--tk-info-soft); color: var(--tk-info); }
.tk-pill-status-resolved { background: var(--tk-success-soft); color: var(--tk-success); }
.tk-pill-status-rejected { background: var(--tk-danger-soft); color: var(--tk-danger); }

.tk-pill-team-r1 { background: var(--tk-page-bg); color: var(--tk-ink); border: 1px solid var(--tk-border); }
.tk-pill-team-r2 { background: var(--tk-page-bg); color: var(--tk-ink); border: 1px solid var(--tk-border); }
.tk-pill-team-r3 { background: var(--tk-page-bg); color: var(--tk-ink); border: 1px solid var(--tk-border); }

/* ---------- Team filter toggle (toolbar, di samping All Types) ---------- */
.tk-team-toggle { display: flex; border: 1px solid var(--tk-border); border-radius: 8px; overflow: hidden; flex: 0 0 auto; }
.tk-team-toggle-btn {
  border: none; background: transparent; color: var(--tk-muted);
  padding: 8px 14px; font-size: 12.5px; font-weight: 600; cursor: pointer;
  border-right: 1px solid var(--tk-border); white-space: nowrap;
}
.tk-team-toggle-btn:last-child { border-right: none; }
.tk-team-toggle-btn.is-active { background: var(--tk-primary); color: #fff; }
.tk-team-toggle-btn:hover:not(.is-active) { background: var(--tk-page-bg); }

/* Varian team toggle khusus card Ticket Activity -- REVISI: awalnya
   sengaja dibuat beda (pill lonjong 999px) dari .tk-team-toggle biasa
   di toolbar supaya 2 toggle tim di halaman yang sama tidak identik.
   Tapi per revisi terbaru, user justru mau keduanya SAMA PERSIS
   look-nya (segmented control kotak membulat, tombol nempel dipisah
   garis tipis, seperti .tk-team-toggle toolbar) -- jadi varian ini
   sekarang cuma "alias" visual dari base .tk-team-toggle. */
.tk-team-toggle--pill {
  border: 1px solid var(--tk-border);
  border-radius: 8px;
  background: var(--tk-surface);
  padding: 0;
  gap: 0;
  overflow: hidden;
}
.tk-team-toggle--pill .tk-team-toggle-btn {
  border-radius: 0;
  border-right: 1px solid var(--tk-border);
}
.tk-team-toggle--pill .tk-team-toggle-btn:last-child { border-right: none; }
.tk-team-toggle--pill .tk-team-toggle-btn:hover:not(.is-active) { background: var(--tk-page-bg); }

/* Varian "compact" status tabs khusus card Ticket Activity -- ukurannya
   sedikit dikecilkan + tanpa count badge supaya muat berdampingan
   dengan team toggle di 1 baris filter. REVISI: look-nya disamakan
   dengan segmented control (.tk-team-toggle) di sebelahnya -- tombol
   nempel dipisah garis tipis, radius kotak membulat, BUKAN pill
   lonjong dengan gap seperti .tk-status-tabs utama. */
.tk-status-tabs--compact {
  margin-bottom: 0;
  /* FIX (visual): sebelumnya "flex: 1 1 auto" bikin container ini maksa
     melebar ngisi sisa ruang di .tk-heatmap-filters, jadi border-nya
     nyampe ke ujung kanan card walau isinya (pill-pill status) cuma
     sepanjang "Rejected" -- whitespace kosong lebar di sisa areanya.
     "flex: 0 1 auto" (tumbuh 0, boleh menyusut, lebar dasar dari
     kontennya sendiri) bikin border ngepas sama isi. */
  flex: 0 1 auto;
  border-radius: 8px;
  border: 1px solid var(--tk-border);
  background: var(--tk-surface);
  padding: 0;
  gap: 0;
  flex-wrap: nowrap;
  overflow: hidden;
}
.tk-status-tabs--compact .tk-status-tab {
  flex: 0 0 auto;
  border-radius: 0;
  border-right: 1px solid var(--tk-border);
  padding: 7px 12px;
  font-size: 12.5px;
}
.tk-status-tabs--compact .tk-status-tab:last-child { border-right: none; }

/* ---------- Rows-per-page + pagination (table footer) ---------- */
.tk-pagesize { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--tk-muted); }
.tk-pagesize select, .tk-pagesize input {
  border: 1px solid var(--tk-border); border-radius: 6px; padding: 5px 8px;
  font-size: 12px; background: var(--tk-surface); color: var(--tk-ink);
}
.tk-pagesize input { width: 80px; }
.tk-pagination { display: flex; align-items: center; gap: 4px; }
.tk-pagination button {
  border: 1px solid var(--tk-border); background: var(--tk-surface); color: var(--tk-ink);
  border-radius: 6px; padding: 5px 10px; font-size: 12px; cursor: pointer; min-width: 30px;
}
.tk-pagination button.is-active { background: var(--tk-primary); color: #fff; border-color: var(--tk-primary); }
.tk-pagination button:disabled { opacity: 0.4; cursor: not-allowed; }

/* ---------- Baris tiket berstatus Rejected -- digelapin, penanda visual
   tanpa perlu buka detail dulu. ---------- */
.tk-table tbody tr.is-rejected { opacity: 0.55; filter: grayscale(0.3); }
.tk-table tbody tr.is-rejected:hover { opacity: 0.8; }

.tk-view-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: var(--tk-primary-soft);
  color: var(--tk-primary-dark);
  font-family: inherit;
  font-size: 12px;
  font-weight: 500;
  padding: 7px 13px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease;
}
.tk-view-btn:hover { background: #d3e7e8; }

.tk-row-actions-cell { padding-top: 0; padding-bottom: 0; width: 1%; white-space: nowrap; }
.tk-row-actions { display: flex; align-items: center; justify-content: flex-start; gap: 6px; height: 100%; }

.tk-empty { padding: 60px 20px; text-align: center; color: var(--tk-muted); }
.tk-empty i { font-size: 26px; color: var(--tk-primary-soft); margin-bottom: 10px; display: block; }
.tk-empty p { font-size: 13.5px; }

.tk-table-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-top: 1px solid var(--tk-border);
  flex-wrap: wrap;
}
.tk-table-footer span { font-size: 12px; color: var(--tk-muted); }

.hidden { display: none !important; }

/* ---------- Fields (shared by Create/Detail modals) ---------- */
.tk-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.tk-field:last-child { margin-bottom: 0; }
.tk-field-row { display: flex; gap: 14px; }
.tk-field-row .tk-field { flex: 1; }
.tk-field label { font-size: 13.5px; font-weight: 500; color: var(--tk-ink); }
.tk-field input,
.tk-field select,
.tk-field textarea {
  width: 100%;
  font-family: inherit;
  font-weight: 400;
  border: 1px solid var(--tk-border);
  border-radius: 9px;
  padding: 10px 12px;
  font-size: 14px;
  color: var(--tk-ink);
  background: var(--tk-surface);
  outline: none;
  resize: vertical;
}
.tk-field input::placeholder,
.tk-field textarea::placeholder { color: #a8b0b8; }
.tk-field input:focus,
.tk-field select:focus,
.tk-field textarea:focus {
  border-color: var(--tk-primary);
  box-shadow: 0 0 0 3px var(--tk-primary-soft);
}
.tk-field-error { font-size: 11px; color: var(--tk-danger); display: none; }
.tk-field.has-error input,
.tk-field.has-error textarea,
.tk-field.has-error select { border-color: var(--tk-danger); }
.tk-field.has-error .tk-field-error { display: block; }

.tk-hint { display: flex; align-items: flex-start; gap: 8px; font-size: 12.5px; line-height: 1.55; color: var(--tk-muted); margin-top: 4px; }
.tk-hint i {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--tk-primary-soft);
  color: var(--tk-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
}
.tk-hint strong { color: var(--tk-ink); font-weight: 600; }

/* ---------- Attachment (photo) — New Ticket modal ---------- */
.tk-attach-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.tk-attach-btn { padding: 9px 14px; font-size: 13px; flex-shrink: 0; background: var(--tk-surface); }
.tk-attach-dropzone {
  position: relative;
  border: 1px dashed var(--tk-border);
  border-radius: 10px;
  padding: 12px;
  margin: 0;
  background: var(--tk-page-bg);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.tk-attach-dropzone:focus-within,
.tk-attach-dropzone.is-dragover {
  border-color: var(--tk-primary);
  border-style: solid;
  background: var(--tk-primary-soft);
}
.tk-attach-drop-hint {
  font-size: 11px;
  color: var(--tk-muted);
  flex-basis: 100%;
  margin-left: 2px;
}
.tk-attach-filename {
  font-size: 12.5px;
  color: var(--tk-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 220px;
}
.tk-attach-filename.has-file { color: var(--tk-ink); font-weight: 500; }
.tk-attach-hint { font-size: 11.5px; color: var(--tk-muted); margin: 6px 0 0; }

/* Grid dipakai untuk preview di modal New Ticket MAUPUN gallery di
   modal Detail — thumbnail persegi seragam, wrap otomatis. */
.tk-attach-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  gap: 10px;
  margin-top: 10px;
}
.tk-attach-thumb {
  position: relative;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--tk-border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--tk-page-bg);
}
.tk-attach-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.tk-attach-thumb a {
  display: block;
  width: 100%;
  height: 100%;
  cursor: zoom-in;
}

/* Attachment image lightbox -- popup di tempat pas foto attachment
   diklik (New Ticket preview, Edit mode, Detail view, Resolution
   proof), pengganti "pindah tab baru" lewat target="_blank". Ditutup
   dengan tombol X atau klik area gelap di luar foto. */
.tk-lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 20, 23, 0.82);
  display: none;
  align-items: center;
  justify-content: center;
  /* Padding kiri-kanan-atas-bawah diperbesar (dari 40/20 ke 64/72) --
     ini sengaja nyisain "zona aman" kosong di pinggir supaya foto
     besar TIDAK pernah nutupin/mepet ke panah prev-next atau dots di
     bawahnya, di ukuran layar/zoom manapun. */
  padding: 64px 72px;
  z-index: 1100;
}
.tk-lightbox-overlay.is-open { display: flex; }
/* Wrapper ini yang membatasi ukuran maksimum foto (bukan img
   langsung) -- cuma buat naruh foto di tengah dan nyisain jarak aman
   dari panah prev-next/dots di sekitarnya (lihat padding overlay). */
.tk-lightbox-img-wrap {
  max-width: 100%;
  max-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tk-lightbox-img {
  /* Dikunci langsung ke satuan viewport (vw/vh), bukan cuma persen
     dari parent -- vw/vh itu dihitung dari lebar/tinggi viewport
     dalam CSS-px, yang OTOMATIS MENGECIL kalau browser di-zoom makin
     besar (100% -> 110% -> ...). Jadi fotonya ikut menyesuaikan/
     mengecil sesuai sisa ruang yang ada, bukan malah kelihatan makin
     "membesar"/kepotong waktu di-zoom. min(...) tetap jaga foto kecil
     supaya gak dipaksa melebar penuh kalau memang ukuran aslinya kecil. */
  max-width: min(100%, 82vw);
  max-height: min(100%, 78vh);
  border-radius: 8px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4);
  cursor: default;
}
.tk-lightbox-close {
  position: fixed;
  top: 18px;
  right: 20px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s ease;
}
.tk-lightbox-close:hover { background: rgba(255, 255, 255, 0.24); }

/* Panah prev/next -- style DISAMAKAN PERSIS dengan tombol close (X):
   lingkaran, background putih transparan, ikon putih, transisi hover
   yang sama. Cuma diposisikan di tengah kiri/kanan, bukan pojok atas. */
.tk-lightbox-nav {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s ease;
  z-index: 1101;
}
.tk-lightbox-nav:hover { background: rgba(255, 255, 255, 0.24); }
.tk-lightbox-nav:disabled {
  opacity: 0.35;
  cursor: default;
  pointer-events: none; /* di foto pertama/terakhir, panahnya gak bisa diklik lagi */
}
.tk-lightbox-prev { left: 20px; }
.tk-lightbox-next { right: 20px; }
/* Disembunyikan otomatis lewat JS (tkRefreshLightboxNav) kalau
   fotonya cuma 1 -- gak ada gunanya nampilin panah/dots buat galeri
   1 foto. */
.tk-lightbox-nav.hidden { display: none; }

/* Titik-titik indikator di bawah foto, nunjukin ada berapa foto dan
   lagi di foto ke berapa -- cuma muncul kalau fotonya lebih dari 1. */
.tk-lightbox-dots {
  position: fixed;
  bottom: 22px;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  z-index: 1101;
}
.tk-lightbox-dots.hidden { display: none; }
.tk-lightbox-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.35);
  border: none;
  padding: 0;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.15s ease;
}
.tk-lightbox-dot:hover { background: rgba(255, 255, 255, 0.6); }
.tk-lightbox-dot.is-active { background: #fff; transform: scale(1.2); }
@media (max-width: 640px) {
  .tk-lightbox-overlay { padding: 48px 16px; }
  .tk-lightbox-close { top: 12px; right: 12px; }
  .tk-lightbox-nav { width: 34px; height: 34px; font-size: 14px; }
  .tk-lightbox-prev { left: 8px; }
  .tk-lightbox-next { right: 8px; }
  .tk-lightbox-dots { bottom: 12px; }
}

/* Non-image attachment (PDF/Word/video) di preview New Ticket --
   sama-sama pakai .tk-attach-thumb sebagai wrapper, tapi isinya ikon +
   nama file, bukan <img>. */
.tk-attach-file-icon {
  width: 100%;
  height: 60%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  color: var(--tk-primary);
}
.tk-attach-file-meta {
  padding: 0 6px 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: hidden;
}
.tk-attach-file-name {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--tk-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tk-attach-file-size {
  font-size: 9.5px;
  color: var(--tk-muted);
}

/* Non-image attachment link di modal Detail (bukan grid thumb, tapi
   baris ikon + nama file selebar penuh, karena tidak ada gambar untuk
   ditampilkan sebagai thumbnail). */
.tk-attach-file-link {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  height: 100%;
  padding: 10px;
  color: var(--tk-ink);
  text-decoration: none;
}
.tk-attach-file-link i {
  font-size: 20px;
  color: var(--tk-primary);
  flex-shrink: 0;
}
.tk-attach-file-link .tk-attach-file-name {
  font-size: 11.5px;
  font-weight: 600;
}

/* Badge kolom "Due" di tabel + nilai "Estimated completion" di modal
   Detail -- warna beda tergantung urgensinya. */
.tk-due-badge {
  font-size: 12px;
  font-weight: 600;
  color: var(--tk-muted);
}
.tk-due-soon { color: var(--tk-ink); }
.tk-due-today { color: var(--tk-warning); font-weight: 700; }
.tk-due-overdue { color: var(--tk-danger); font-weight: 700; }
.tk-due-done { color: var(--tk-success); font-weight: 600; }
.tk-due-rejected { color: var(--tk-muted); font-weight: 600; }
.tk-detail-meta-value.tk-due-overdue,
.tk-detail-meta-value.tk-due-today { font-weight: 700; }

.tk-attach-remove {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 50%;
  background: rgba(37, 52, 63, 0.72);
  color: #fff;
  font-size: 10.5px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease;
  z-index: 2;
}
.tk-attach-remove:hover { background: var(--tk-danger); }

/* ---------- Attachments — Ticket Detail modal ---------- */
.tk-detail-attachment { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.tk-resolution-card {
  border-radius: 14px;
  padding: 16px;
}
.tk-resolution-card h5 { display: flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 700; color: var(--tk-ink); margin-bottom: 10px; }
.tk-resolution-card h5 i { color: var(--tk-primary); }
.tk-resolution-card.is-view {
  background: var(--tk-page-bg);
  border: 1px solid var(--tk-border);
  margin-top: 14px;
}
.tk-resolution-card.is-view .tk-detail-desc { margin: 0 0 4px; }
.tk-resolution-card.is-view .tk-detail-attachment { margin-bottom: 0; }
.tk-resolution-card.is-input {
  background: var(--tk-page-bg);
  border: 1px solid var(--tk-border);
}
.tk-resolution-card.is-input .tk-hint { margin-bottom: 4px; }
.tk-resolution-card.is-input .tk-field textarea,
.tk-resolution-card.is-input .tk-field input { background: var(--tk-surface); }
.tk-detail-resolution {
  background: var(--tk-primary-soft);
  border-radius: 10px;
  padding: 12px 14px;
}
.tk-detail-resolution .tk-detail-desc { margin: 4px 0 0; white-space: pre-wrap; }

/* ---------- Modal shell ---------- */
.tk-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 30, 34, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 1000;
}
.tk-modal-overlay.is-open { display: flex; }
.tk-modal {
  position: relative;
  background: var(--tk-surface);
  border-radius: 16px;
  width: 100%;
  max-width: 480px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 60px rgba(16, 24, 32, 0.28);
  overflow: hidden;
}
.tk-modal-lg { max-width: 620px; }
.tk-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 20px 22px 16px;
  border-bottom: 1px solid var(--tk-border);
  flex-shrink: 0;
}
.tk-modal-head h3 {
  font-size: 16.5px;
  font-weight: 700;
  color: var(--tk-ink);
  display: flex;
  align-items: center;
  gap: 9px;
}
.tk-modal-head h3 i { color: var(--tk-primary); font-size: 15px; }
.tk-modal-head-copylink {
  margin-left: auto;
  padding: 6px 12px;
  font-size: 12.5px;
}
.tk-modal-head-edit {
  padding: 6px 12px;
  font-size: 12.5px;
}
/* Icon jam version-history ala Google Docs -- icon doang, gak ada teks. */
.tk-modal-head-icon-btn {
  margin-left: auto;
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 1px solid var(--tk-border);
  background: var(--tk-surface);
  color: var(--tk-muted);
  font-size: 13px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.tk-modal-head-icon-btn:hover { background: var(--tk-page-bg); color: var(--tk-ink); border-color: var(--tk-primary); }

/* ---------- Drawer "Version history" (ala Google Docs) ----------
   .tk-modal sudah dikasih position:relative di atas supaya drawer ini
   bisa absolute nutupin tk-modal-body pas dibuka, geser dari kanan.
   Beda sama Docs yang panel-nya di SAMPING (karena Docs full-page),
   punya kita modal-nya sempit jadi drawer ini OVERLAY, bukan side-by-side. */
.tk-history-drawer {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: min(280px, 100%);
  background: var(--tk-surface);
  border-left: 1px solid var(--tk-border);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform .22s ease;
  z-index: 30;
  box-shadow: -8px 0 20px rgba(16, 24, 32, 0.10);
}
.tk-history-drawer.is-open { transform: translateX(0); }
.tk-history-drawer-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 14px;
  border-bottom: 1px solid var(--tk-border);
  font-size: 14px;
  font-weight: 700;
  color: var(--tk-ink);
  flex-shrink: 0;
}
.tk-history-drawer-close {
  width: 28px; height: 28px;
  border-radius: 8px;
  border: none;
  background: none;
  color: var(--tk-muted);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.tk-history-drawer-close:hover { background: var(--tk-page-bg); color: var(--tk-ink); }
.tk-history-drawer-list { overflow-y: auto; padding: 8px 0; }
.tk-history-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  padding: 10px 16px;
  cursor: pointer;
  font-family: inherit;
  border-left: 3px solid transparent;
}
.tk-history-item:hover { background: var(--tk-page-bg); }
.tk-history-item.is-current { cursor: default; }
.tk-history-item.is-current:hover { background: none; }
.tk-history-item-when { font-size: 12.5px; font-weight: 700; color: var(--tk-ink); }
.tk-history-item-current-label { font-size: 11px; color: var(--tk-muted); }
.tk-history-item-who {
  display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; color: var(--tk-muted);
}
.tk-history-item-who::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: #2fa86b; flex-shrink: 0;
}
.tk-history-item-fields { font-size: 11px; color: var(--tk-primary-dark); font-style: italic; }
html[data-theme="dark"] .tk-history-drawer { background: #17262a; border-color: rgba(255,255,255,0.1); }
html[data-theme="dark"] .tk-history-item:hover { background: rgba(255,255,255,0.04); }

.tk-editlog-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--tk-warning-soft);
  border: 1px solid #e3c25a;
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 16px;
  font-size: 12.5px;
  color: #6b5218;
}
.tk-editlog-banner i { color: #e3a21a; }
.tk-editlog-banner span { flex: 1; }
html[data-theme="dark"] .tk-editlog-banner { background: rgba(227,162,26,0.14); border-color: rgba(227,162,26,0.4); color: #f0d488; }
.tk-modal-close {
  width: 30px; height: 30px;
  border-radius: 8px;
  border: none;
  background: none;
  color: var(--tk-muted);
  font-size: 15px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s ease, color 0.15s ease;
}
.tk-modal-close:hover { background: var(--tk-page-bg); color: var(--tk-ink); }
.tk-modal-body {
  padding: 20px 22px;
  overflow-y: auto;
  /* FIX: tanpa flex-basis + min-height:0 di sini, flex item ini defaultnya
     min-height:auto -- artinya dia nggak mau menyusut di bawah tinggi
     kontennya sendiri. Begitu konten body lebih tinggi dari sisa ruang
     (mis. root buka detail sambil field Assigned to + section "Override
     Estimated Completion" sama-sama muncul), .tk-modal-body ikut
     membesar ngelewatin batas, dan yang motong sisanya adalah
     overflow:hidden punya .tk-modal DI LUAR -- BUKAN scrollbar internal
     body ini. Makanya bagian bawah kelihatan "kepotong" beneran walau
     sudah di-scroll (karena scroll internalnya sendiri nggak pernah
     kepakai). flex:1 1 auto + min-height:0 memaksa body ini menyusut
     pas ruang tersisa dari head/foot, supaya overflow-y:auto di atas
     benar-benar aktif dan seluruh konten selalu bisa dijangkau lewat
     scroll di dalam modal. */
  flex: 1 1 auto;
  min-height: 0;
}
.tk-modal-foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  padding: 16px 22px;
  border-top: 1px solid var(--tk-border);
  flex-shrink: 0;
}

/* ---------- Detail modal specifics ---------- */
.tk-detail-top { margin-bottom: 10px; }
.tk-detail-top h4 { font-size: 17px; font-weight: 700; color: var(--tk-ink); margin-bottom: 8px; }
.tk-detail-badges { display: flex; gap: 8px; flex-wrap: wrap; }
.tk-detail-desc { font-size: 13.5px; line-height: 1.65; color: var(--tk-ink); white-space: pre-wrap; margin-bottom: 16px; }

.tk-detail-meta {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  background: var(--tk-page-bg);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 4px;
}
.tk-detail-meta-item { display: flex; flex-direction: column; gap: 3px; }
.tk-detail-meta-label { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--tk-muted); }
.tk-detail-meta-value { font-size: 13px; font-weight: 500; color: var(--tk-ink); }

.tk-divider { height: 1px; background: var(--tk-border); margin: 18px 0; }

.tk-detail-actions-row { display: flex; justify-content: flex-end; align-items: center; gap: 10px; margin-top: 4px; flex-wrap: wrap; }
.tk-detail-actions-row .tk-btn { flex-shrink: 0; }
/* Baris tombol utama (Assign to me/Approve & Resolve/Reject/dst) butuh
   jarak lebih dari 4px default di atas -- field Assigned to/Status
   (atau card Proof of Completion) suka nempel kalau cuma 4px. Discope
   ke #tkPrimaryActionsRow aja biar gak ikut narik baris tombol
   Confirm Claim di #tkClaimPanel yang jaraknya udah pas. */
#tkPrimaryActionsRow { margin-top: 16px; }

/* ---------- Comments (chat-style bubbles + compose box) ---------- */
.tk-comments-header { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.tk-comments-header h5 { font-size: 13.5px; font-weight: 700; color: var(--tk-ink); }
.tk-comments h5 { font-size: 13.5px; font-weight: 600; color: var(--tk-ink); margin-bottom: 10px; }
.tk-comments-count {
  min-width: 19px;
  height: 19px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--tk-danger);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.tk-comments-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 320px;
  overflow-y: auto;
  margin-bottom: 12px;
  padding: 4px 4px 2px;
}
.tk-comments-list:empty { display: none; }

.tk-comment-item {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  max-width: 82%;
}
.tk-comment-avatar {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--tk-primary);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* Foto profil aktif (kalau user sudah pernah upload di Settings) --
   fallback inisial di atas tetap dipakai kalau photoUrl kosong (lihat
   avatarInnerHtml di js/ticketing.js renderComments()). */
.tk-comment-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.tk-comment-body { min-width: 0; }
/* Head-di-atas-bubble: komentar diri sendiri cuma nampilin jam di
   head-nya (JS gak render span author buat isOwn), komentar orang lain
   tetap nama + jam. */
.tk-comment-item-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 3px; }
.tk-comment-author { font-size: 12px; font-weight: 700; color: var(--tk-ink); }
.tk-comment-time { font-size: 10.5px; color: var(--tk-muted); white-space: nowrap; }
.tk-comment-bubble {
  background: var(--tk-page-bg);
  border-radius: 14px 14px 14px 4px;
  padding: 8px 12px;
}
.tk-comment-text { font-size: 13px; color: var(--tk-ink); line-height: 1.5; white-space: pre-wrap; word-break: break-word; }

/* Komentar milik user yang sedang login -- rata kanan, warna primary,
   avatar & nama disembunyikan (gak perlu liat "diri sendiri", cukup
   jamnya), efek "ekor" bubble dipindah ke pojok kanan bawah. */
.tk-comment-item.is-own {
  align-self: flex-end;
  flex-direction: row-reverse;
}
.tk-comment-item.is-own .tk-comment-avatar { display: none; }
.tk-comment-item.is-own .tk-comment-item-head { justify-content: flex-end; }
.tk-comment-item.is-own .tk-comment-bubble {
  background: var(--tk-primary);
  border-radius: 14px 14px 4px 14px;
}
.tk-comment-item.is-own .tk-comment-text { color: #fff; }

.tk-comments-empty {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  color: var(--tk-muted);
  padding: 10px 2px;
}
.tk-comments-empty i { color: var(--tk-border); font-size: 15px; }

.tk-comment-form { display: flex; }
.tk-comment-input-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: var(--tk-surface);
  border: 1px solid var(--tk-border);
  border-radius: 12px;
  padding: 10px 10px 8px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.tk-comment-input-wrap:focus-within {
  border-color: var(--tk-primary);
  box-shadow: 0 0 0 3px var(--tk-primary-soft);
}
.tk-comment-input-wrap textarea {
  width: 100%;
  border: none;
  outline: none;
  resize: vertical;
  min-height: 44px;
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--tk-ink);
  background: transparent;
  padding: 2px 2px 6px;
}
.tk-comment-input-wrap textarea::placeholder { color: #a8b0b8; }
.tk-comment-form-actions { display: flex; justify-content: flex-end; }
.tk-comment-submit-btn { padding: 8px 16px; font-size: 12.5px; }

.tk-delete-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: none;
  background: none;
  color: var(--tk-danger);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  padding: 4px 2px;
}
.tk-delete-link:hover { text-decoration: underline; }

/* ---------- Delete confirm (alert-style) modal ---------- */
.tk-modal-alert { max-width: 380px; border-radius: 24px; position: relative; }
.tk-alert-close {
  position: absolute;
  top: 14px; right: 14px;
  width: 28px; height: 28px;
  border-radius: 8px;
  border: none;
  background: none;
  color: var(--tk-muted);
  font-size: 14px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s ease, color 0.15s ease;
  z-index: 1;
}
.tk-alert-close:hover { background: var(--tk-page-bg); color: var(--tk-ink); }
.tk-alert-body { padding: 40px 30px 30px; display: flex; flex-direction: column; align-items: center; text-align: center; }
.tk-alert-icon {
  width: 68px; height: 68px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 26px;
  background: #fff;
  margin-bottom: 18px;
}
.tk-alert-icon.is-danger-solid { background: var(--tk-danger-soft); color: var(--tk-danger); }
.tk-alert-icon.is-primary-solid { background: var(--tk-primary-soft); color: var(--tk-primary); }
.tk-alert-icon.is-success-solid { background: var(--tk-success-soft); color: var(--tk-success); }
.tk-alert-title { font-size: 19px; font-weight: 700; color: var(--tk-ink); margin-bottom: 8px; }
.tk-alert-text { font-size: 13.5px; color: var(--tk-muted); line-height: 1.6; max-width: 300px; }
.tk-alert-actions { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 24px; width: 100%; }
.tk-pill.tk-pill-muted,
.tk-pill.tk-pill-danger,
.tk-pill.tk-pill-primary,
.tk-pill.tk-pill-success {
  border: none;
  border-radius: 14px;
  padding: 11px 22px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  transition: filter 0.15s ease, background 0.15s ease;
}
.tk-pill.tk-pill-muted::before { display: none; }
.tk-pill.tk-pill-danger::before { display: none; }
.tk-pill.tk-pill-primary::before { display: none; }
.tk-pill.tk-pill-success::before { display: none; }
.tk-pill-muted { background: #fff; color: var(--tk-muted); border: 1.5px solid var(--tk-border) !important; }
.tk-pill-muted:hover { background: var(--tk-page-bg); }
.tk-pill-danger { background: var(--tk-danger); color: #fff; }
.tk-pill-danger:hover { filter: brightness(0.92); }
.tk-pill-primary { background: var(--tk-primary); color: #fff; }
.tk-pill-primary:hover { filter: brightness(0.92); }
.tk-pill-success { background: var(--tk-success); color: #fff; }
.tk-pill-success:hover { filter: brightness(0.92); }

/* ---------- Toast ---------- */
.tk-toast {
  position: fixed;
  bottom: 22px;
  right: 22px;
  z-index: 1100;
  display: flex;
  align-items: center;
  gap: 10px;
  background: #fff;
  border: 1px solid var(--tk-border);
  border-left: 3px solid var(--tk-success);
  border-radius: 10px;
  padding: 12px 16px;
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: var(--tk-ink);
  box-shadow: 0 12px 28px rgba(11, 79, 84, 0.16);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  /* Toast sekarang bisa berisi nama-nama kolaborator (mis. "Ticket
     claimed — working with Elvi, Naila & Rifa"), jadi dikasih batas
     lebar + boleh wrap ke baris ke-2, biar tim yang banyak orangnya
     tidak bikin toast nge-print keluar layar di kanan. */
  max-width: min(360px, calc(100vw - 44px));
}
.tk-toast.is-show { opacity: 1; transform: translateY(0); }
.tk-toast i { color: var(--tk-success); font-size: 15px; flex-shrink: 0; }
.tk-toast span { white-space: normal; }

/* ============================================================
   Responsive -- semua breakpoint dari desktop besar sampai layar
   telepon paling sempit (Galaxy Z Fold saat DILIPAT, ~280-320px).
   Mobile-first bukan berarti CSS-nya ditulis mobile-first; base
   style di atas memang didesain untuk desktop/laptop, jadi
   breakpoint di bawah OVERRIDE turun bertahap:
     1200px -> laptop kecil / tablet lanskap besar
      900px -> iPad/tablet potret, Surface, dsb
      768px -> iPad Mini/potret & phablet lanskap
      480px -> kebanyakan HP (iPhone, Galaxy S/Note, dsb) potret
      360px -> HP kecil & Galaxy Z Fold saat dilipat
============================================================= */
@media (max-width: 1200px) {
  .tk-wrap { padding: 0 4px; }
  .tk-stats { grid-template-columns: repeat(3, 1fr); }
  .tk-leaderboard-podium { gap: 10px; }
}

@media (max-width: 1100px) {
  .tk-stats { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px) {
  .tk-head { align-items: flex-start; }
  .tk-head h1 { font-size: 22px; }
  .tk-open-create-btn { max-width: 100%; padding: 16px 18px; font-size: 14.5px; }
  .tk-toolbar { padding: 12px; gap: 10px; }
  .tk-toolbar select { min-width: 130px; }
  .tk-heatmap-filters { gap: 8px; }
  .tk-leaderboard-podium { gap: 8px; }
  .tk-leaderboard-row { grid-template-columns: 30px 30px 1fr auto auto; gap: 8px; padding: 9px 10px; }
  .tk-modal-lg { max-width: 90vw; }
}

@media (max-width: 768px) {
  .tk-wrap { padding: 0; }
  .tk-head { flex-direction: column; align-items: stretch; gap: 10px; }
  .tk-head p { max-width: none; }
  .tk-stats { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .tk-stat-card { padding: 14px 14px; gap: 10px; }
  .tk-stat-icon { width: 36px; height: 36px; font-size: 14px; }
  .tk-stat-value { font-size: 17px; }
  .tk-heatmap-card, .tk-leaderboard-card { padding: 14px 14px; }
  .tk-toolbar { flex-direction: column; align-items: stretch; }
  .tk-search { flex: 1 1 auto; min-width: 0; }
  .tk-toolbar select { width: 100%; min-width: 0; }
  .tk-team-toggle { width: 100%; }
  .tk-team-toggle-btn { flex: 1 1 0; }
  .tk-status-tabs { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .tk-status-tab { flex: 0 0 auto; }
  .tk-modal { max-width: 100vw; width: 100vw; height: 100%; max-height: 100vh; border-radius: 0; }
  .tk-modal-overlay { padding: 0; }
  .tk-modal-lg { max-width: 100vw; }
  .tk-history-drawer { width: 100%; }
}

@media (max-width: 640px) {
  .tk-stats { grid-template-columns: 1fr; }
  .tk-toolbar select { flex: 1 1 100%; }
  .tk-status-tabs { overflow-x: auto; flex-wrap: nowrap; }
  .tk-status-tab { flex: 0 0 auto; }
  .tk-field-row { flex-direction: column; }
  .tk-detail-meta { grid-template-columns: 1fr; }
  .tk-detail-actions-row { flex-direction: column-reverse; }
  .tk-detail-actions-row .tk-btn { width: 100%; }
  .tk-comment-submit-btn { width: 100%; justify-content: center; }
  .tk-comment-item { max-width: 92%; }
  .tk-leaderboard-row {
    grid-template-columns: 18px 26px 1fr auto auto;
    column-gap: 6px;
    row-gap: 0;
    padding: 8px 10px;
    align-items: center;
  }
  .tk-leaderboard-rank { font-size: 11px; }
  .tk-leaderboard-avatar { width: 26px; height: 26px; font-size: 10px; align-self: center; }
  .tk-leaderboard-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 12.5px; }
  .tk-leaderboard-tickets { white-space: nowrap; font-size: 10.5px; }
  .tk-leaderboard-points { white-space: nowrap; font-size: 12.5px; }
  .tk-leaderboard-list { gap: 6px; }
  .tk-leaderboard-card { padding: 12px 12px; margin-bottom: 14px; }
  .tk-leaderboard-head { margin-bottom: 8px; }
  .tk-leaderboard-columns { gap: 10px; }
  .tk-modal-head { padding: 14px 16px 12px; flex-wrap: wrap; }
  .tk-modal-body { padding: 14px 16px; }
  .tk-modal-foot { padding: 12px 16px; flex-wrap: wrap; }
  .tk-modal-head-copylink span, .tk-modal-head-edit span { display: none; }
  .tk-modal-head-copylink, .tk-modal-head-edit { padding: 7px 9px; }
}

@media (max-width: 480px) {
  .tk-head h1 { font-size: 19px; }
  .tk-head p { font-size: 12.5px; }
  .tk-open-create-btn { font-size: 13.5px; padding: 14px 14px; }
  .tk-stat-label { font-size: 9.5px; }
  .tk-stat-value { font-size: 16px; }
  .tk-status-tab { font-size: 12px; padding: 7px 11px; }
  .tk-podium-avatar { width: 38px; height: 38px; font-size: 13px; }
  .tk-leaderboard-name { font-size: 12.5px; }
  .tk-leaderboard-points { font-size: 13px; }
  .tk-detail-top h4 { font-size: 15.5px; }
  .tk-detail-badges { gap: 6px; }
  .tk-pill { font-size: 10px; padding: 3px 8px; }
  .tk-claim-panel { padding: 12px 14px; }
}

/* Galaxy Z Fold (folded, ~280-344px), very old/small phones. Cuma
   selisih kecil dari breakpoint 480px -- fokus ke elemen yang masih
   berisiko overflow horizontal di lebar sesempit ini. */
@media (max-width: 360px) {
  .tk-stats { grid-template-columns: 1fr; }
  .tk-stat-card { flex-direction: row; }
  .tk-leaderboard-row {
    grid-template-columns: 20px 28px 1fr auto;
    grid-template-areas:
      "rank avatar name name"
      "rank avatar tickets points";
    column-gap: 6px;
    row-gap: 2px;
    padding: 9px 8px;
  }
  .tk-leaderboard-avatar { width: 28px; height: 28px; font-size: 11px; }
  .tk-podium-card { padding: 10px 8px; }
  .tk-btn { font-size: 12.5px; padding: 9px 12px; }
}

/* Layar lebar (desktop besar/4K) -- .tk-wrap sudah dibatasi max-width
   1320px & di-center lewat margin:auto di aturan dasar, jadi di sini
   cuma perlu pastikan leaderboard tidak melar terlalu tinggi/lebar. */
@media (min-width: 1600px) {
  .tk-wrap { max-width: 1480px; }
}
/* ---------- Priority info tooltip (i) ---------- */
.tk-priority-info {
  margin-left: 5px;
  font-size: 12px;
  color: var(--tk-muted);
  cursor: help;
  position: relative;
}
.tk-priority-info:hover::after,
.tk-priority-info:focus::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: 260px;
  padding: 10px 12px;
  border-radius: 8px;
  /* Sama seperti .tk-heatmap-tooltip -- sengaja gelap tetap di kedua
     tema (bukan var(--tk-text) yang undefined/rapuh), supaya teks
     putih di bawah selalu kontras. */
  background: #1f2937;
  color: #fff;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.5;
  white-space: normal;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.18);
  z-index: 40;
  pointer-events: none;
}
.tk-priority-info:hover::before,
.tk-priority-info:focus::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #1f2937;
  z-index: 40;
}

/* ============================================================
   DARK MODE — dipindah ke sini (self-contained di ticketing.css)
   supaya tidak tergantung pada file terpisah (dark-mode-v8.css).
   Menimpa token --tk-* yang didefinisikan di :root paling atas.
============================================================= */
html[data-theme="dark"] {
  --tk-primary: #21a7ae;
  --tk-primary-dark: #16868d;
  --tk-primary-soft: rgba(33,167,174,.16);
  --tk-success: #4fbd8a;
  --tk-warning: #e8b34a;
  --tk-danger: #ef6b6b;
  --tk-info: #69a8d6;
  --tk-success-soft: rgba(79,189,138,.14);
  --tk-warning-soft: rgba(232,179,74,.14);
  --tk-danger-soft: rgba(239,107,107,.14);
  --tk-info-soft: rgba(105,168,214,.14);
  --tk-ink: #e7eff0;
  --tk-muted: #9ab0b4;
  --tk-border: #2a3d42;
  --tk-surface: #18272c;
  --tk-page-bg: #101b1f;
  /* Heatmap intensity scale -- kalau tidak di-override, cell tetap
     pakai warna terang :root di atas background gelap (kontras aneh,
     mirip bug judul-nyaru-background yang sama sudah pernah kejadian
     di halaman ini sebelum dark mode di-implementasikan). */
  --tk-heat-0: #1c2b30;
  --tk-heat-1: #1f4e4d;
  --tk-heat-2: #2a7a72;
  --tk-heat-3: #34a396;
  --tk-heat-4: #4fd6c4;
}

html[data-theme="dark"] .tk-alert-icon,
html[data-theme="dark"] .tk-pill-muted,
html[data-theme="dark"] .tk-toast {
  background: var(--tk-surface) !important;
}
html[data-theme="dark"] .tk-view-btn:hover {
  background: rgba(33,167,174,.24) !important;
}
html[data-theme="dark"] .tk-btn-secondary:hover {
  background: #203238 !important;
}
html[data-theme="dark"] .tk-attach-remove {
  background: rgba(16, 27, 31, 0.72) !important;
}
html[data-theme="dark"] .tk-priority-info {
  color: var(--tk-muted) !important;
}
html[data-theme="dark"] .tk-priority-info:hover::after,
html[data-theme="dark"] .tk-priority-info:focus::after {
  background: #0b1a1d !important;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
}
html[data-theme="dark"] .tk-priority-info:hover::before,
html[data-theme="dark"] .tk-priority-info:focus::before {
  border-top-color: #0b1a1d !important;
}

/* Multi-assignee selector */
.tk-field select[multiple] { min-height: 116px; padding: 6px 8px; }
.tk-field select[multiple] option { padding: 6px 8px; border-radius: 5px; }
.tk-field select[multiple]:disabled { opacity: .7; cursor: not-allowed; }

/* Team-scoped multi-assignee picker */
.tk-assignee-current {
  min-height: 42px;
  padding: 10px 12px;
  border: 1px solid var(--tk-border);
  border-radius: 10px;
  background: var(--tk-page-bg);
  margin-bottom: 10px;
  font-size: 0.92rem;
  line-height: 1.4;
  color: var(--tk-ink);
}
.tk-assignee-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
}
.tk-assignee-choice {
  /* FIX: WAJIB ada supaya .tk-assignee-choice input (position:absolute
     di bawah) ke-contain di DALAM chip ini sendiri. Tanpa ini, browser
     nyari ancestor positioned terdekat dan malah ketemu .tk-modal
     (position:relative, paling luar, di luar area yang discroll) --
     checkbox jadi "kabur" dari posisi visualnya. Efeknya: tiap toggle
     checkbox (dapet fokus), browser auto-scroll buat mastiin elemen
     fokus itu keliatan, tapi karena posisinya nempel ke .tk-modal
     (bukan ke .tk-modal-body yang discroll), perhitungan scroll-nya
     ngaco -- bikin scrollHeight .tk-modal-body ke-inflate, jadi bagian
     atas keliatan "kepotong"/ke-scroll ngilang + nyisa ruang putih
     kosong di bawah tiap kali chip di-klik. */
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px 7px 10px;
  border: 1px solid var(--tk-border);
  border-radius: 999px;
  background: var(--tk-surface);
  color: var(--tk-ink);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.tk-assignee-choice:hover:not(:has(input:disabled)) {
  border-color: var(--tk-primary);
}
/* Checkbox aslinya disembunyikan (bukan display:none, tetap fokusable
   buat keyboard/screen reader) -- indikator "terpilih" cukup dari warna
   chip-nya sendiri, sama seperti .tk-pill-status-* lain di halaman ini,
   bukan kotak checkbox generik. */
.tk-assignee-choice input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.tk-assignee-choice::before {
  content: "";
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1.5px solid var(--tk-border);
  flex-shrink: 0;
  transition: border-color .15s ease, background .15s ease;
}
.tk-assignee-choice.is-selected::before {
  border-color: var(--tk-primary);
  background: var(--tk-primary);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 10px 10px;
}
.tk-assignee-choice span {
  min-width: 0;
  white-space: nowrap;
}
.tk-assignee-choice.is-selected {
  border-color: var(--tk-primary);
  background: var(--tk-primary-soft, rgba(15, 106, 113, 0.08));
  color: var(--tk-primary);
}
.tk-assignee-choice:has(input:disabled) {
  cursor: not-allowed;
  opacity: .6;
}
.tk-assignee-empty {
  padding: 10px 12px;
  border: 1px dashed var(--tk-border);
  border-radius: 10px;
  color: var(--tk-muted);
}

/* ---------- Status picker (pengganti <select> polos di detail ticket) ----------
   Tombol pill, satu aktif pada satu waktu, meniru bahasa visual
   .tk-pill-status-* (warna per status) tapi dalam bentuk yang bisa
   diklik langsung -- bukan dropdown generik. Underlying <select
   id="tkDetailStatus"> tetap ada (hidden) sebagai sumber kebenaran
   value/opsi yang disabled, lihat fillStatusPicker() di ticketing.js. */
.tk-status-picker {
  display: flex;
  gap: 8px;
  width: 100%;
}
.tk-status-choice {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 1 1 0;
  gap: 8px;
  padding: 10px 16px;
  border: 1.5px solid var(--tk-border);
  border-radius: 10px;
  background: var(--tk-surface);
  color: var(--tk-muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, color .15s ease, box-shadow .15s ease;
}
.tk-status-choice i { font-size: 12px; }
.tk-status-choice:hover:not(:disabled) {
  border-color: var(--tk-primary);
  color: var(--tk-ink);
}
.tk-status-choice:disabled {
  cursor: not-allowed;
  opacity: .5;
}
.tk-status-choice.tk-status-choice-in_progress.is-selected {
  border-color: var(--tk-warning);
  background: var(--tk-warning-soft);
  color: var(--tk-warning);
  box-shadow: 0 0 0 1px var(--tk-warning) inset;
}
.tk-status-choice.tk-status-choice-waiting_approval.is-selected {
  border-color: var(--tk-info);
  background: var(--tk-info-soft);
  color: var(--tk-info);
  box-shadow: 0 0 0 1px var(--tk-info) inset;
}

/* ============================================================
   STAGE 2 ADDITIONS -- alur Ticketing baru (Open/claim/timer/
   points/edit-log). Ditambahkan di akhir file supaya diff-nya
   gampang dipisah dari CSS lama.
============================================================= */

/* ---------- Open stat icon ---------- */
.tk-stat-icon.is-open { background: var(--tk-info-soft); color: var(--tk-info); }

/* ---------- Big "New Ticket" button di atas tabel ---------- */
.tk-open-create-bar {
  display: flex;
  justify-content: center;
  margin-bottom: 20px;
}
.tk-open-create-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 18px 24px;
  border: 2px dashed var(--tk-primary);
  border-radius: 16px;
  background: var(--tk-primary-soft);
  color: var(--tk-primary-dark);
  font-size: 15.5px;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, border-style 0.15s ease, transform 0.05s ease;
}
.tk-open-create-btn i { font-size: 16px; }
.tk-open-create-btn:hover { background: #d9ecec; border-style: solid; }
.tk-open-create-btn:active { transform: translateY(1px); }
html[data-theme="dark"] .tk-open-create-btn { background: rgba(15, 106, 113, 0.18); color: #9fd8d6; }
html[data-theme="dark"] .tk-open-create-btn:hover { background: rgba(15, 106, 113, 0.28); }

/* ---------- Leaderboard + Ticket Activity row ---------- */
/* Leaderboard dan heatmap disandingkan (side-by-side) di layar lebar;
   masing-masing card jadi flex item lebar-sama (flex: 1 1 0), lalu
   stack vertikal lagi di tablet/mobile supaya tidak kesempitan. */
.tk-lb-heatmap-row {
  display: flex;
  align-items: stretch;
  gap: 20px;
  margin-bottom: 20px;
}
.tk-lb-heatmap-row .tk-leaderboard-card,
.tk-lb-heatmap-row .tk-heatmap-card {
  flex: 1 1 0;
  min-width: 0;
  margin-bottom: 0;
}
@media (max-width: 900px) {
  .tk-lb-heatmap-row { flex-direction: column; }
}
/* Di layar sempit, TOP PERFORMERS | CONTENDERS gak muat sebelahan lagi --
   stack ke bawah. Podium tetap list vertikal seperti biasa, cuma
   dikasih sedikit ruang napas lebih karena kolomnya jadi full-width. */
@media (max-width: 560px) {
  /* Dulu di sini di-stack vertikal (flex-direction: column) supaya
     muat di layar sempit -- sekarang diganti scroll horizontal (lihat
     overflow-x: auto di .tk-leaderboard-columns) supaya layout 2-kolom
     (TOP PERFORMERS | CONTENDERS) tetap identik seperti tampilan
     normal, baik di layar HP asli maupun karena efek zoom browser. */
  .tk-leaderboard-top-performers .tk-podium-card { padding: 10px 12px; gap: 10px; }
  .tk-leaderboard-top-performers .tk-podium-avatar { width: 38px; height: 38px; font-size: 13px; }
  .tk-leaderboard-top-performers .tk-podium-name { font-size: 12.5px; }
  .tk-leaderboard-top-performers .tk-podium-points { font-size: 13px; }
  .tk-leaderboard-top-performers .tk-podium-tickets { font-size: 11px; }
}

/* ---------- Leaderboard ---------- */
/* Dikecilin (compact) -- padding/gap/font-size di seluruh card ini
   diperkecil dikit supaya Leaderboard tidak jauh lebih tinggi daripada
   Ticket Activity di sebelahnya (lihat .tk-lb-heatmap-row). */
.tk-leaderboard-card {
  background: var(--tk-surface);
  border: 1px solid var(--tk-border);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.05);
  margin-bottom: 20px;
  /* Card ini di-stretch setinggi Ticket Activity di sebelahnya lewat
     align-items:stretch di .tk-lb-heatmap-row -- flex column di sini
     supaya .tk-leaderboard-body di bawah bisa ikut melar ngisi tinggi
     itu (bukan cuma nangkring di atas nyisain ruang kosong). */
  display: flex;
  flex-direction: column;
}
.tk-leaderboard-head h3 { font-size: 14px; font-weight: 700; color: var(--tk-ink); margin-bottom: 2px; display: flex; align-items: center; gap: 8px; }
.tk-leaderboard-head {
  margin-bottom: 10px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
}

/* Tombol bantuan (?) + collapse (chevron) di pojok kanan-atas card. */
.tk-leaderboard-head-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.tk-leaderboard-icon-btn {
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--tk-border);
  background: var(--tk-page-bg);
  color: var(--tk-muted);
  font-size: 11px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, transform 0.15s;
}
.tk-leaderboard-icon-btn:hover { background: var(--tk-primary-soft); color: var(--tk-primary-dark); }
.tk-leaderboard-icon-btn#tkLeaderboardCollapseBtn i { transition: transform 0.2s; }
.tk-leaderboard-icon-btn#tkLeaderboardCollapseBtn.is-collapsed i { transform: rotate(180deg); }

/* Popover "how points are calculated" buat tombol bantuan (?) --
   GANTI tooltip teks-polos lama (CSS attr() + background gelap) yang
   susah dibaca sekilas. Sekarang berupa card terang beneran di DOM
   (bukan attr()) supaya bisa nampilin tier prioritas + bonus kecepatan
   secara terstruktur (bukan satu paragraf panjang), dibuka/ditutup lewat
   klik (lihat initPointsHelpPopover() di ticketing.js) biar juga enak
   dipakai di touch device, bukan cuma hover. */
.tk-points-help { position: relative; }
.tk-points-help-popover {
  position: absolute;
  top: calc(100% + 10px);
  right: -6px;
  width: 250px;
  max-width: min(250px, 80vw);
  background: var(--tk-surface, #fff);
  color: var(--tk-ink);
  border: 1px solid var(--tk-border);
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(16, 24, 32, 0.14);
  padding: 12px 13px;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
  pointer-events: none;
  z-index: 30;
}
.tk-points-help-popover::before {
  content: "";
  position: absolute;
  bottom: 100%;
  right: 8px;
  width: 10px;
  height: 10px;
  background: var(--tk-surface, #fff);
  border-left: 1px solid var(--tk-border);
  border-top: 1px solid var(--tk-border);
  transform: rotate(45deg) translateY(6px);
}
.tk-points-help-popover.is-open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}
.tk-points-help-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--tk-ink);
  margin-bottom: 9px;
}
.tk-points-help-tiers {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.tk-points-tier {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.tk-points-tier-badge {
  font-size: 11px;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: 999px;
  line-height: 1.5;
}
.tk-points-tier-value {
  font-size: 12px;
  font-weight: 600;
  color: var(--tk-muted);
}
.tk-points-tier--low .tk-points-tier-badge { background: #e3f6ec; color: #1f8a4c; }
.tk-points-tier--medium .tk-points-tier-badge { background: #fef3d6; color: #a4720b; }
.tk-points-tier--high .tk-points-tier-badge { background: #ffe6d6; color: #c05a1c; }
.tk-points-tier--critical .tk-points-tier-badge { background: #fde0e0; color: #c72c2c; }
.tk-points-help-bonus {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  padding-top: 9px;
  border-top: 1px dashed var(--tk-border);
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--tk-ink);
}
.tk-points-help-bonus i { color: #d99a1b; margin-top: 2px; font-size: 12px; flex-shrink: 0; }
.tk-points-help-bonus strong { font-weight: 700; }

html[data-theme="dark"] .tk-points-tier--low .tk-points-tier-badge { background: rgba(46, 160, 96, 0.18); color: #5fd493; }
html[data-theme="dark"] .tk-points-tier--medium .tk-points-tier-badge { background: rgba(200, 150, 20, 0.2); color: #f0c04e; }
html[data-theme="dark"] .tk-points-tier--high .tk-points-tier-badge { background: rgba(210, 105, 30, 0.22); color: #ff9c5c; }
html[data-theme="dark"] .tk-points-tier--critical .tk-points-tier-badge { background: rgba(210, 40, 40, 0.22); color: #ff8080; }

/* Body (podium + contenders) yang di-toggle sama tombol collapse.
   flex:1 + min-height:0 supaya body ini nurunin tinggi ekstra dari
   stretch (lihat .tk-leaderboard-card) ke .tk-leaderboard-columns di
   bawahnya. */
.tk-leaderboard-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.tk-leaderboard-body.is-collapsed { display: none; }

/* Layout 2 kolom: TOP PERFORMERS (sempit, fixed) | CONTENDERS (lebar, sisa ruang).
   align-items: stretch supaya kolom TOP PERFORMERS ikut setinggi kolom
   CONTENDERS (bukan cuma setinggi isinya sendiri) -- lihat juga
   .tk-leaderboard-top-performers & .tk-leaderboard-podium di bawah yang
   bikin 3 kartu podium-nya ikut melar ngisi tinggi itu, jadi tidak ada
   spasi kosong nganggur di bawah podium. */
.tk-leaderboard-columns {
  display: flex;
  align-items: stretch;
  gap: 14px;
  flex: 1 1 auto;
  min-height: 0;
  /* TOP PERFORMERS harus tetap kelihatan diam di tempat -- yang scroll
     ke samping cuma isi list CONTENDERS-nya sendiri (lihat overflow-x
     di .tk-leaderboard-contenders .tk-leaderboard-list di bawah), jadi
     baris ini TIDAK ikut scroll sebagai satu kesatuan. */
}
.tk-leaderboard-top-performers {
  flex: 0 0 150px;
  min-width: 150px; /* kunci lebar, tidak boleh menyempit, selalu kelihatan */
  display: flex; flex-direction: column;
}
.tk-leaderboard-contenders {
  flex: 1 1 0;
  min-width: 0; /* boleh menyempit sampai sekecil ruang tersisa -- scroll-nya
                   ditangani di dalam .tk-leaderboard-list, bukan di sini,
                   supaya kolom TOP PERFORMERS di sebelahnya tetap diam. */
  display: flex; flex-direction: column; min-height: 0;
  /* container query di bawah (pada .tk-leaderboard-list) ngukur lebar
     kolom INI sendiri, bukan lebar layar -- jadi ngikutin persis kapan
     kolom ini menyempit gara-gara zoom, bukan cuma nebak dari lebar
     viewport. */
  container-type: inline-size;
  container-name: tk-rankings;
}
.tk-leaderboard-col-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--tk-muted);
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
}
.tk-leaderboard-col-label--top i { color: #e3a21a; }
.tk-leaderboard-col-label-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.tk-leaderboard-ranked-badge {
  font-size: 10px;
  font-weight: 600;
  color: var(--tk-muted);
  background: var(--tk-page-bg);
  border: 1px solid var(--tk-border);
  border-radius: 999px;
  padding: 2px 8px;
  flex-shrink: 0;
}
/* Contenders list scrollable supaya kolom kanan tidak makin tinggi terus
   kalau pesertanya banyak. flex:1 supaya list ini ngisi penuh sisa
   tinggi dari stretch (nyamain tinggi Ticket Activity di sebelahnya,
   lihat .tk-lb-heatmap-row) -- max-height cuma plafon aman, bukan
   target yang mau dikejar. */
.tk-leaderboard-contenders .tk-leaderboard-list {
  flex: 1 1 auto;
  max-height: 320px;
  overflow-y: auto;
  padding-right: 4px;
}
/* Default (sekitar 100% zoom ke bawah): tetap responsif seperti biasa
   -- baris ranking boleh menyempit/wrap seperlunya, TIDAK scroll. Baru
   kalau kolom RANKINGS ini sendiri sudah lebih sempit dari 300px (kira-
   kira mulai ~110% zoom di layar biasa), kita kunci lebar barisnya dan
   nyalain scroll ke samping, alih-alih terus dipepetin/dipotong.
   Angka "300px" ini cuma titik awal -- coba di browser lalu naik/
   turunin sesuai di zoom berapa persis kamu mau scroll-nya mulai aktif. */
@container tk-rankings (max-width: 300px) {
  .tk-leaderboard-contenders .tk-leaderboard-list {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .tk-leaderboard-contenders .tk-leaderboard-row {
    min-width: 300px;
  }
}

/* Podium di kolom TOP PERFORMERS (~168px) sekarang list vertikal 3 baris
   (bukan 3 kartu disejajarkan ke samping lagi), jadi cuma perlu
   dikecilin dikit biar muat di kolom sempit -- tidak perlu lagi
   flex-wrap/nowrap khusus kayak versi sejajar sebelumnya. */
.tk-leaderboard-top-performers .tk-podium-card { padding: 6px 8px; gap: 6px; }
.tk-leaderboard-top-performers .tk-podium-avatar { width: 26px; height: 26px; font-size: 9.5px; }
.tk-leaderboard-top-performers .tk-podium-rank-badge { width: 12px; height: 12px; font-size: 7px; }
.tk-leaderboard-top-performers .tk-podium-name { font-size: 10.5px; }
.tk-leaderboard-top-performers .tk-podium-points { font-size: 11px; }
.tk-leaderboard-top-performers .tk-podium-tickets { font-size: 9px; }

/* Badge kecil bulat isi angka rank (1/2/3), nempel di pojok avatar --
   pengganti baris "#N" + icon crown/medal terpisah yang bikin card
   kepanjangan. Warna badge = warna medali (emas/perak/perunggu). */
.tk-podium-rank-badge {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 800;
  color: #fff;
  border: 2px solid var(--tk-page-bg);
}
.tk-podium-card.is-gold .tk-podium-rank-badge { background: #e3a21a; }
.tk-podium-card.is-silver .tk-podium-rank-badge { background: #97a1a6; }
.tk-podium-card.is-bronze .tk-podium-rank-badge { background: #b97a42; }

.tk-leaderboard-podium {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
  flex: 1;
}
.tk-leaderboard-top-performers .tk-leaderboard-podium { margin-bottom: 0; }
.tk-leaderboard-top-performers .tk-podium-card { flex: 1; }
/* Kartu podium sekarang baris horizontal (avatar kiri, nama+poin
   kanan) dan ditumpuk ke BAWAH, bukan disejajarkan 3 kartu sempit ke
   samping -- supaya tidak dempet lagi di kolom TOP PERFORMERS yang
   sempit. Aksen warna rank dipindah ke garis kiri (border-left). */
.tk-podium-card {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  background: var(--tk-page-bg);
  border: 1px solid var(--tk-border);
  border-left: 3px solid var(--tk-border);
  border-radius: 10px;
  padding: 10px 12px;
  text-align: left;
}
.tk-podium-card.is-gold { border-left-color: #e3a21a; }
.tk-podium-card.is-silver { border-left-color: #97a1a6; }
.tk-podium-card.is-bronze { border-left-color: #b97a42; }
.tk-podium-avatar-wrap { position: relative; display: inline-flex; flex-shrink: 0; }
.tk-podium-avatar {
  width: 40px; height: 40px;
  border-radius: 50%;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--tk-primary);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
}
.tk-podium-avatar img { width: 100%; height: 100%; object-fit: cover; object-position: center; border-radius: 50%; display: block; }
.tk-podium-card.is-gold .tk-podium-avatar { background: #e3a21a; }
.tk-podium-card.is-silver .tk-podium-avatar { background: #97a1a6; }
.tk-podium-card.is-bronze .tk-podium-avatar { background: #b97a42; }
.tk-podium-info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.tk-podium-name { font-size: 13px; font-weight: 700; color: var(--tk-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tk-podium-meta { display: flex; align-items: baseline; gap: 8px; }
.tk-podium-points { font-size: 13px; font-weight: 800; color: var(--tk-primary-dark); }
.tk-podium-tickets { font-size: 11px; color: var(--tk-muted); }

.tk-leaderboard-list { display: flex; flex-direction: column; gap: 5px; }
.tk-leaderboard-row {
  display: grid;
  grid-template-columns: 30px 28px 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 6px 9px;
  border-radius: 9px;
  background: var(--tk-page-bg);
  border: 1px solid transparent;
}
.tk-leaderboard-row.is-gold { border-color: #e3c25a; background: #fff8e6; }
.tk-leaderboard-row.is-silver { border-color: #c9cfd3; background: #f3f5f6; }
.tk-leaderboard-row.is-bronze { border-color: #d9a870; background: #fbeee0; }
.tk-leaderboard-rank { font-size: 11.5px; font-weight: 700; color: var(--tk-muted); text-align: center; }
.tk-leaderboard-avatar {
  width: 26px; height: 26px;
  border-radius: 50%;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  background: var(--tk-primary-soft);
  color: var(--tk-primary-dark);
  font-size: 10.5px;
  font-weight: 700;
}
.tk-leaderboard-avatar img { width: 100%; height: 100%; object-fit: cover; object-position: center; border-radius: 50%; display: block; }
.tk-leaderboard-name { font-size: 12.5px; font-weight: 600; color: var(--tk-ink); }
.tk-leaderboard-tickets { font-size: 11px; color: var(--tk-muted); }
.tk-leaderboard-points { font-size: 13px; font-weight: 800; color: var(--tk-primary-dark); }
.tk-leaderboard-empty {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 24px 12px;
  color: var(--tk-muted);
  font-size: 12.5px;
}
.tk-leaderboard-empty i { font-size: 20px; color: var(--tk-border); }

html[data-theme="dark"] .tk-podium-card,
html[data-theme="dark"] .tk-leaderboard-row { background: rgba(255,255,255,0.03); border-color: rgba(255,255,255,0.08); }
html[data-theme="dark"] .tk-podium-card.is-gold,
html[data-theme="dark"] .tk-leaderboard-row.is-gold { background: rgba(227,162,26,0.12); }
html[data-theme="dark"] .tk-podium-card.is-silver,
html[data-theme="dark"] .tk-leaderboard-row.is-silver { background: rgba(151,161,166,0.14); }
html[data-theme="dark"] .tk-podium-card.is-bronze,
html[data-theme="dark"] .tk-leaderboard-row.is-bronze { background: rgba(185,122,66,0.14); }

/* ---------- Ticket Activity filters ---------- */
/* REVISI: "All Teams" dan "All Status" sekarang masing-masing jadi
   barisnya sendiri (2 baris), bukan disandingkan di 1 baris yang bisa
   overflow/scroll horizontal. Tiap baris dibuat penuh selebar card
   (width:100%) dan tombol-tombol di dalamnya di-flex:1 supaya
   menyebar rata ngisi seluruh lebar baris -- jadi tidak ada whitespace
   kosong nganggur di ujung kanan seperti versi 1-baris yang lama. */
.tk-heatmap-filters {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 10px;
  flex-shrink: 0; /* stays pinned under the head, doesn't get squeezed by .tk-heatmap-graphic centering below it */
}
/* FIX v3: v2 (flex:1 1 auto, ukuran natural ikut panjang teks) emang
   sukses gak lagi bocor ngelewatin card, TAPI hasilnya kotak-kotak
   tombolnya jadi gak rata (lebar "Open" vs "Waiting Approval" beda
   jauh) -- keliatan berantakan. Solusi final: pakai CSS GRID dengan
   kolom "1fr" sejumlah tombolnya (4 buat team, 6 buat status) --
   dengan grid, kolom PASTI sama rata & totalnya PASTI persis 100%
   lebar container (gak akan pernah lebih), beda dari flex yang lebar
   kolomnya ngikutin konten. Supaya label panjang ("Waiting Approval")
   tetap kebaca penuh di kolom yang jadi sempit, teks dibolehin wrap ke
   2 baris (bukan dipotong ellipsis) -- baris tombol lain di grid yang
   sama otomatis ikut setinggi itu juga, jadi semua kotak tetap rata
   tinggi & lebarnya. Ini yang bikin baris toggle SELALU rata kotak +
   SELALU pas di dalam card di lebar layar berapa pun. */
/* REVISI lagi: grid kolom sama rata (1fr) bikin "Open" (kata pendek)
   jadi kebanyakan ruang kosong, sementara "Waiting Approval" (kata
   panjang) malah kepepet di lebar kolom yang sama persis -- gak adil
   karena keduanya dipaksa selebar yang sama padahal panjang teksnya
   beda jauh. Baris ini dibalikin ke FLEX (lebar tombol ngikutin
   panjang konten teksnya masing-masing, "Open" jadi ramping, "Waiting
   Approval" dapat jatah lebih lebar), dikombinasikan sama font yang
   lebih kecil (di bawah) supaya semua label tetap muat 1 baris tanpa
   kepotong. overflow-x:auto di container jadi jaring pengaman terakhir
   HANYA kalau di lebar layar yang benar-benar ekstrem sempit teks
   masih belum muat semua -- baris di-scroll horizontal di dalam card
   (tetap gak akan bocor keluar card), bukan teksnya yang kepotong. */
.tk-heatmap-filters #tkHeatmapTeamToggle,
.tk-heatmap-filters #tkHeatmapStatusToggle {
  display: flex;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.tk-heatmap-filters #tkHeatmapTeamToggle::-webkit-scrollbar,
.tk-heatmap-filters #tkHeatmapStatusToggle::-webkit-scrollbar {
  height: 3px;
}
.tk-heatmap-filters #tkHeatmapTeamToggle::-webkit-scrollbar-thumb,
.tk-heatmap-filters #tkHeatmapStatusToggle::-webkit-scrollbar-thumb {
  background: var(--tk-border);
  border-radius: 999px;
}
/* Dibikin lebih kecil/ringkas (font + padding) daripada toggle biasa.
   Label 1-2 kata (mis. "In Progress", "Waiting Approval") sekarang
   boleh jadi 2 baris (white-space: normal) kalau ruangnya sempit,
   BUKAN dipepetin ellipsis/numpuk kayak sebelumnya -- overflow-x:auto
   di container (di atas) tetap jadi jaring pengaman terakhir kalau
   sudah super sempit dan 2 baris pun belum cukup. */
.tk-heatmap-filters .tk-team-toggle-btn,
.tk-heatmap-filters .tk-status-tab {
  flex: 1 1 auto;
  min-width: 0;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  text-align: center;
  padding: 6px 8px;
  font-size: 10px;
  line-height: 1.25;
  word-break: normal;
  overflow-wrap: break-word;
}

/* ---------- Claim collaborator panel ---------- */
.tk-claim-panel {
  background: var(--tk-page-bg);
  border: 1px solid var(--tk-border);
  border-radius: 12px;
  padding: 16px 18px;
  margin-top: 14px;
}
.tk-claim-panel h5 { font-size: 13.5px; font-weight: 700; color: var(--tk-ink); margin-bottom: 6px; }
.tk-claim-panel .tk-assignee-picker { margin: 10px 0 14px; }

html[data-theme="dark"] .tk-claim-panel { background: rgba(255,255,255,0.03); border-color: rgba(255,255,255,0.08); }

/* ---------- Expected-time field error (matches existing .tk-field-error pattern) ---------- */
#tkFormExpectedHoursError { display: none; }
#tkFormExpectedHoursError.is-visible { display: block; }
/* ---------- FIX: Leaderboard hilang/overflow di mobile ----------
   Root cause: Leaderboard & Ticket Activity disandingkan pakai flex
   row + align-items:stretch (lihat .tk-lb-heatmap-row), dan supaya
   isi Leaderboard (body -> columns -> contenders -> list) ikut melar
   ngisi tinggi stretch itu, semuanya dikasih flex:1.../min-height:0
   berlapis. Begitu breakpoint <=900px bikin row ini flex-direction:
   column (card ditumpuk), acuan tinggi "stretch" dari sibling itu
   HILANG, tapi rantai flex:1.../min-height:0 di dalamnya masih aktif
   -- flex-basis:0 tanpa ada extra space buat di-grow bikin
   .tk-leaderboard-contenders collapse ke tinggi 0, sementara
   .tk-leaderboard-list (child-nya) tetap treng flex-grow +
   min-height:160px sendiri, jadi dia "kejeblos" keluar dari box
   parent-nya (makanya keliatan kepotong / nongol di luar card).
   Fix: begitu ditumpuk, matikan seluruh rantai flex:1.../min-height:0
   itu (balik ke auto block-flow biasa) supaya card ikut tinggi
   sesuai isinya, dan .tk-leaderboard-list dikasih tinggi tetap +
   overflow-y:auto supaya list-nya sendiri yang scroll (bukan card-nya
   yang collapse). Diletakkan di akhir file supaya menang cascade dari
   base rules .tk-leaderboard-body/-columns/-contenders di atas. */
@media (max-width: 900px) {
  .tk-lb-heatmap-row .tk-leaderboard-card,
  .tk-lb-heatmap-row .tk-heatmap-card {
    flex: none;
  }
  .tk-leaderboard-body,
  .tk-leaderboard-columns,
  .tk-leaderboard-top-performers,
  .tk-leaderboard-contenders {
    flex: none;
    min-height: 0;
  }
  .tk-leaderboard-contenders .tk-leaderboard-list {
    flex: none;
    height: 260px;
    max-height: 260px;
    min-height: 0;
    overflow-y: auto;
  }
}