/* Kerangka catalog. SETIAP nama class di file ini berawalan `catalog-`.

   Bukan gaya penamaan, melainkan pemisah namespace. Shell ini dimuat di halaman
   yang sama dengan komponen yang sedang dipajang, jadi nama yang wajar untuk
   sebuah komponen (`.panel`, `.nav`, `.shell`) adalah persis nama yang paling
   mungkin bertabrakan. Sudah terbukti sekali: `.sidebar` milik shell ini
   `position: sticky`, dan saat komponen Sidebar lahir di Batch 15 sticky itu
   merebut titik acuan posisi panelnya — tanpa satu pun error.

   Yang TIDAK ikut diganti: `id` (`#panel`, `#nav`, `#theme-switch`). ID punya
   namespace sendiri, tidak pernah dipakai untuk gaya di sini, dan ratusan
   assertion menempel padanya.


   === ARAH VISUAL: NEUTRAL INK (redesign Sep 2026) ===

   Catalog adalah meja kerja netral; satu-satunya warna di layar milik
   komponen yang sedang diperiksa. Shell sepenuhnya achromatic (graphite, hue
   255 mengikuti slate DS), state aktif = tinta foreground + indikator 2px,
   bukan fill berwarna. Menggantikan aksen oranye Batch 34 — alasan kedua
   Batch 34 ("chrome harus terbaca beda dari komponen") justru lebih terpenuhi
   oleh shell tanpa hue sama sekali. Detail di DESIGN.md §"Shell catalog".

   Latar shell TETAP `--color-background`, bukan token shell sendiri:
   komponen seperti Outline Button memakai `--color-background` sebagai
   latarnya, jadi latar yang berbeda di bawah preview akan menggambar kotak
   belang di sekeliling tiap tombol.


   === LARANGAN KERAS: TITIK ACUAN `position: fixed` ===

   ENAM BELAS file CSS komponen memakai `position: fixed` dan mengandalkan
   VIEWPORT sebagai titik acuannya — toast, sheet, drawer, dialog, alert-dialog,
   select, tooltip, popover, hover-card, dropdown-menu, context-menu, menubar,
   combobox, autocomplete, data-table, chart.

   Properti berikut DILARANG di setiap LELUHUR canvas — yaitu
   `.catalog-shell`, `.catalog-body`, `#panel`, `.catalog-content`,
   `.catalog-canvas`, `.catalog-demo`, dan sejak redesign neutral ink juga
   `.catalog-demo__frame` dan `.catalog-demo__preview`:

       transform          filter            backdrop-filter
       perspective        will-change: transform
       contain: layout | paint | strict | content

   Masing-masing membuat titik acuan baru untuk `position: fixed`, dan keenam
   belas komponen itu berpindah acuan SEKALIGUS, tanpa satu pun error.

   Yang AMAN: `position: sticky`, `position: relative`, `z-index`, `opacity`
   (stacking context, BUKAN titik acuan — dipakai fade masuk route), dan
   `overflow` — dengan catatan di bawah. Efek apa pun di SAUDARA jalur canvas
   (`.catalog-topbar`, `.catalog-sidebar`, `.catalog-toc`, `.catalog-scrim`)
   juga aman: topbar berkaca dan laci sidebar yang digeser `translate` di
   mobile tidak memindahkan acuan apa pun.

   `overflow` di `#panel`, `.catalog-content`, `.catalog-canvas`,
   `.catalog-demo`, `.catalog-demo__frame`, atau `.catalog-demo__preview`
   adalah KEPUTUSAN, bukan default. Selain `visible`, ia mengubah tempat
   `position: sticky` di dalam demo menempel, dan Sidebar serta Table
   dua-duanya memakainya. Sengaja dibiarkan `visible` di semuanya.

   Penjaganya ADA: `tests/geometry.mjs` rule 4 menempelkan elemen uji
   `position: fixed; inset: 0` di dalam kotak demo terdalam dan menuntutnya
   seukuran viewport, lalu menelusuri rantai leluhurnya.


   === GEOMETRI SHELL ADA DI SATU BLOK ===

   Seluruh ukuran shell lewat custom property di blok `:root` tepat di bawah.

   1. `--catalog-sidebar-width` + 2 × `--catalog-panel-padding` tidak boleh
      melebihi 240px + 2 × --space-6. `tests/geometry.mjs` jalan di viewport
      900×700 dan memeriksa `panel.scrollWidth <= panel.clientWidth + 2`;
      `tests/rtl.mjs` di 1100×800. Padding yang lebih lega baru dipasang di
      ≥1280px, di atas kedua viewport uji itu.

   2. `--catalog-topbar-height` maksimum 60px — tiap piksel topbar dibayar dari
      ruang demo di viewport 700px. Sekarang 56px (brand satu baris).

   3. Setiap elemen chrome yang menggeser AWAL wilayah ukur (bar canvas,
      baris install) wajib bertinggi BILANGAN BULAT piksel — lihat komentar
      `.catalog-canvas-bar`. */

:root {
  /* --- Geometri --- */
  --catalog-topbar-height: 56px;
  --catalog-sidebar-width: 240px;
  --catalog-toc-width: 240px;
  --catalog-panel-padding: var(--space-6);
  /* WAJIB bilangan bulat piksel — lihat alasan di `.catalog-canvas-bar`. */
  --catalog-canvas-bar-height: 40px;
  --catalog-canvas-bar-height-mobile: 82px;
  --catalog-meta-height: 40px;
  --catalog-row-height: 30px;
  --catalog-seg-height: 32px;
  --catalog-seg-btn: 28px;
  --catalog-icon-btn: 32px;
  --catalog-search-width: 240px;
  --catalog-drawer-width: 300px;
  --catalog-preview-min: 176px;
  --catalog-code-max: 480px;
  /* Tinggi awal iframe block — kira-kira satu layar laptop. Frame tumbuh
     sendiri kalau isi block lebih tinggi (`fitBlockFrame` di catalog.js). */
  --catalog-block-frame-height: 800px;
  /* Lebar simulasi viewport (tombol Mobile/Tablet di bar canvas). */
  --catalog-sim-mobile: 375px;
  --catalog-sim-tablet: 768px;
  --catalog-swatch-size: 20px;
  --catalog-ramp-chip: 48px;
  --catalog-index-col: 200px;
  --catalog-token-card-min: 220px;
  --catalog-token-name-col: 10rem;
  --catalog-token-value-col: 6.5rem;
  --catalog-token-px-col: 3.5rem;
  --catalog-token-alias-col: 8rem;
  --catalog-type-leading-max: 24rem;
  --catalog-changelog-date: 7.5rem;
  --catalog-tooltip-max: 480px;
  --catalog-topbar-blur: 12px;
  /* Lebar kolom isi. Components memakai kolom baca (880px — demo Data Table
     dan Chart masih lega di sini, dan rel TOC di kanan butuh ruangnya);
     Blocks dan Charts memakai kolom lebar karena isinya layar utuh. */
  --catalog-content-max: 880px;
  --catalog-content-wide: 1200px;
  --catalog-page-max: 720px;
  --catalog-token-category-max: 880px;

  /* --- Tipografi shell (IBM Plex Sans + JetBrains Mono) ---
     Skala sendiri, bukan `--typography-size-*` DS: chrome docs butuh langkah
     13/15/17/22px yang tidak ada di skala Tailwind, dan tipografi shell
     bukan milik konsumen DS. Line-height ditulis rem supaya jatuh di piksel
     bulat — lihat aturan bilangan bulat di atas. */
  --catalog-text-xxs: 0.6875rem;
  --catalog-text-xs: 0.75rem;
  --catalog-text-sm: 0.8125rem;
  --catalog-text-md: 0.875rem;
  --catalog-text-base: 0.9375rem;
  --catalog-text-lg: 1.0625rem;
  --catalog-text-xl: 1.375rem;
  --catalog-text-display: 2.25rem;
  --catalog-text-display-mobile: 1.75rem;
  --catalog-lh-xxs: 0.875rem;
  --catalog-lh-xs: 1rem;
  --catalog-lh-sm: 1.25rem;
  --catalog-lh-code: 1.375rem;
  --catalog-lh-base: 1.5rem;
  --catalog-lh-prose: 1.625rem;
  --catalog-lh-lg: 1.75rem;
  --catalog-lh-display: 2.5rem;
  --catalog-lh-display-mobile: 2.25rem;
  /* Plex menyempit di ukuran besar; tracking negatif cuma untuk heading. */
  /* Kode inline di prosa: sedikit lebih kecil dari teks di sekitarnya —
     mono JetBrains terlihat lebih besar dari Plex di ukuran yang sama. */
  --catalog-code-inline: 0.86em;
  --catalog-track-display: -0.022em;
  --catalog-track-heading: -0.012em;
  --catalog-track-tight: -0.006em;
  --catalog-track-label: 0.01em;

  /* --- Gerak --- */
  --catalog-dur-fast: 120ms;
  --catalog-dur: 200ms;
  --catalog-ease: cubic-bezier(0.2, 0, 0, 1);

  /* --- Warna shell (light) ---
     Semua achromatic, hue 255 mengikuti slate DS supaya abu shell dan abu
     komponen satu keluarga. */
  --catalog-ink: var(--color-foreground);
  /* Teks sekunder. Sedikit lebih gelap dari `--color-muted-foreground`
     (slate-500, 4,38:1 di atas permukaan abu) supaya lolos 4,5:1 di SEMUA
     permukaan shell, termasuk hover dan panel kode. */
  --catalog-muted: oklch(0.5 0.016 255);
  --catalog-border-hairline: oklch(0 0 0 / 8%);
  --catalog-border-strong: oklch(0 0 0 / 14%);
  --catalog-hover: color-mix(in oklch, var(--color-foreground) 4%, var(--color-background));
  --catalog-active: color-mix(in oklch, var(--color-foreground) 7%, var(--color-background));
  --catalog-sunken: oklch(0.975 0.004 255);
  --catalog-topbar-bg: color-mix(in oklch, var(--color-background) 86%, transparent);
  --catalog-scrim: oklch(0 0 0 / 35%);

  /* Nama lama dipertahankan sebagai ALIAS supaya `tests/contrast.mjs` dan
     sisa pemakai tidak patah: "aksen" shell sekarang adalah tintanya. */
  --catalog-accent: var(--catalog-ink);
  --catalog-accent-soft: var(--catalog-active);
  --catalog-surface-alt: var(--catalog-sunken);

  /* Syntax highlight — satu-satunya hue di shell, chroma rendah, semuanya
     ≥4,5:1 di atas `--catalog-sunken` (diukur `test:contrast`). Keyword
     tidak berwarna: tinta tebal. */
  --catalog-code-keyword: var(--catalog-ink);
  --catalog-code-tag: oklch(0.48 0.15 262);
  --catalog-code-attr: oklch(0.47 0.09 200);
  --catalog-code-string: oklch(0.46 0.11 150);
  --catalog-code-comment: oklch(0.5 0.016 255);
  --catalog-code-punct: oklch(0.5 0.016 255);
  --catalog-code-linenum: oklch(0.53 0.012 255);

  --catalog-heading-foreground: var(--color-foreground);
  --catalog-body-foreground: oklch(0.34 0.016 255);
  /* Teks contoh di kartu Typography — ilustrasi, bukan konten yang harus
     dibaca, jadi sengaja TIDAK diuji kontras (lihat tests/contrast.mjs). */
  --catalog-sample-foreground: var(--color-slate-700);

  interpolate-size: allow-keywords;
}

/* Pasangan gelap. Ditulis dua kali — `.dark` dan blok media — mengikuti
   RULES §Tema, karena pilihan pengguna harus bisa menang atas setelan
   sistem. Hover/active tidak perlu ditulis ulang: keduanya color-mix dari
   token DS yang sudah berganti sendiri. */
.dark {
  --catalog-muted: oklch(0.72 0.012 255);
  --catalog-border-hairline: oklch(1 0 0 / 9%);
  --catalog-border-strong: oklch(1 0 0 / 16%);
  --catalog-sunken: oklch(0.165 0.01 255);
  --catalog-scrim: oklch(0 0 0 / 55%);
  --catalog-code-tag: oklch(0.78 0.11 262);
  --catalog-code-attr: oklch(0.8 0.09 200);
  --catalog-code-string: oklch(0.8 0.11 150);
  --catalog-code-comment: oklch(0.7 0.014 255);
  --catalog-code-punct: oklch(0.7 0.014 255);
  --catalog-code-linenum: oklch(0.6 0.012 255);
  --catalog-body-foreground: oklch(0.8 0.01 255);
  --catalog-sample-foreground: var(--color-slate-300);
}

@media (prefers-color-scheme: dark) {
  :root:not(.light) {
    --catalog-muted: oklch(0.72 0.012 255);
    --catalog-border-hairline: oklch(1 0 0 / 9%);
    --catalog-border-strong: oklch(1 0 0 / 16%);
    --catalog-sunken: oklch(0.165 0.01 255);
    --catalog-scrim: oklch(0 0 0 / 55%);
    --catalog-code-tag: oklch(0.78 0.11 262);
    --catalog-code-attr: oklch(0.8 0.09 200);
    --catalog-code-string: oklch(0.8 0.11 150);
    --catalog-code-comment: oklch(0.7 0.014 255);
    --catalog-code-punct: oklch(0.7 0.014 255);
    --catalog-code-linenum: oklch(0.6 0.012 255);
    --catalog-body-foreground: oklch(0.8 0.01 255);
    --catalog-sample-foreground: var(--color-slate-300);
  }
}

/* Reduced motion: seluruh gerak shell lewat tiga token di atas, jadi
   mematikannya cukup di satu tempat. Komponen DS tidak tersentuh — mereka
   punya aturan reduced-motion sendiri. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --catalog-dur-fast: 0.01ms;
    --catalog-dur: 0.01ms;
  }
}

* { box-sizing: border-box; }

/* Jaring pengaman untuk atribut `hidden`. Tanpa ini, rule penulis apa pun
   yang memberi `display` ke elemen yang sama MENIMPA `[hidden]` bawaan
   browser — stylesheet penulis selalu menang atas user-agent. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  font: var(--typography-text-body);
  background: var(--color-background);
  color: var(--color-foreground);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.catalog-icon {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
}

/* Teks untuk pembaca layar saja. */
.catalog-sr {
  position: absolute;
  width: var(--border-1);
  height: var(--border-1);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.catalog-kbd {
  display: inline-flex;
  align-items: center;
  height: var(--space-5);
  padding-inline: var(--space-1-5);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-md);
  background: var(--color-background);
  color: var(--catalog-muted);
  font-family: var(--typography-family-sans);
  font-size: var(--catalog-text-xxs);
  font-weight: var(--typography-weight-medium);
  line-height: var(--typography-leading-none);
}

/* Tombol ikon (menu mobile, copy) = `btn btn--ghost btn--icon btn--sm` DS.
   Tidak ada gaya tiruan di sini: ukuran, hover, dan ring fokusnya ikut
   button.css, jadi perubahan di komponen Button langsung terlihat di chrome. */

/* --- Kerangka --- */

.catalog-shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

/* Flex row, bukan grid: topbar yang `sticky` butuh titik acuan setinggi
   seluruh halaman, dan di grid titik acuan sebuah item adalah area grid-nya
   sendiri. */
.catalog-body {
  display: flex;
  flex: 1;
  min-height: 0;
}

/* --- Lompat ke demo --- */

/* `fixed` di tombolnya sendiri, bukan `relative` di `.catalog-shell` —
   memposisikan shell akan menangkap elemen `absolute` di dalam demo. */
.catalog-skip {
  position: fixed;
  inset-block-start: var(--space-2);
  inset-inline-start: var(--space-2);
  z-index: calc(var(--z-sticky) + 3);
  padding: var(--space-2) var(--space-3);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-lg);
  background: var(--color-background);
  color: var(--color-foreground);
  font: var(--typography-text-label);
  font-family: inherit;
  cursor: pointer;
  /* Tidak `display: none` — elemen yang disembunyikan begitu tidak bisa
     difokus. */
  clip-path: inset(50%);
  white-space: nowrap;
}

.catalog-skip:focus-visible {
  clip-path: none;
  outline: none;
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

/* --- Topbar --- */

/* Berkaca: `backdrop-filter` di sini AMAN — topbar saudara jalur canvas,
   bukan leluhurnya (lihat larangan di kepala file). */
.catalog-topbar {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  gap: var(--space-6);
  height: var(--catalog-topbar-height);
  padding-inline: var(--space-4);
  border-block-end: var(--border-1) solid var(--catalog-border-hairline);
  background: var(--catalog-topbar-bg);
  backdrop-filter: saturate(1.4) blur(var(--catalog-topbar-blur));
}

/* Lebar brand dihitung supaya tabbar mulai tepat di garis kanan sidebar —
   satu sumbu vertikal dari topbar sampai isi. */
.catalog-brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
  width: calc(var(--catalog-sidebar-width) - var(--space-4) - var(--space-6));
  height: var(--catalog-icon-btn);
  color: var(--catalog-ink);
  text-decoration: none;
  border-radius: var(--radius-lg);
}

.catalog-brand:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

.catalog-brand__mark {
  width: var(--space-5);
  height: var(--space-5);
  fill: currentColor;
  flex-shrink: 0;
}

.catalog-brand__name {
  font-size: var(--catalog-text-base);
  font-weight: var(--typography-weight-semibold);
  letter-spacing: var(--catalog-track-heading);
  line-height: var(--catalog-lh-base);
}

.catalog-brand__suffix {
  padding-inline: var(--space-1-5);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-md);
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xxs);
  font-weight: var(--typography-weight-medium);
  line-height: var(--catalog-lh-xs);
  letter-spacing: var(--catalog-track-label);
}

/* Menu mobile — tersembunyi di desktop. */
.catalog-nav-toggle {
  display: none;
}

/* --- Tab bar section utama ---

   Teks saja; tab aktif = tinta penuh + garis 2px di dasar topbar yang
   digeser JS (`positionTabIndicator`). Bukan pil berisi: satu penanda aktif
   per baris, bukan setiap opsi berteriak sama keras.

   `role="tablist"` + roving tabindex — satu perhentian Tab untuk enam tab.
   Lihat alasan langit-langit 60 milik `tabTo` di tests/functional.mjs. */
.catalog-tabbar {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: var(--space-1);
  height: 100%;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}

.catalog-tabbar__tab {
  flex-shrink: 0;
  padding-inline: var(--space-2);
  border: 0;
  background: transparent;
  color: var(--catalog-muted);
  font-family: inherit;
  font-size: var(--catalog-text-md);
  font-weight: var(--typography-weight-medium);
  line-height: var(--catalog-lh-sm);
  cursor: pointer;
  transition: color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-tabbar__tab:hover {
  color: var(--catalog-ink);
}

.catalog-tabbar__tab[aria-selected="true"] {
  color: var(--catalog-ink);
}

.catalog-tabbar__tab:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--border-2) var(--color-ring);
  border-radius: var(--radius-md);
}

.catalog-tabbar__indicator {
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  height: var(--border-2);
  border-radius: var(--border-2) var(--border-2) 0 0;
  background: var(--catalog-ink);
  pointer-events: none;
}

/* Transisi baru dinyalakan sesudah posisi pertama (kelas `is-ready` dari
   JS), supaya indikator tidak meluncur dari tepi kiri saat halaman dibuka. */
.catalog-tabbar__indicator.is-ready {
  transition: translate var(--catalog-dur) var(--catalog-ease),
              width var(--catalog-dur) var(--catalog-ease);
}

/* Tab Playground: pembuka panel pilih alat. Chevron berputar saat panel
   terbuka — penanda bahwa klik membuka sesuatu, bukan langsung pindah. */
.catalog-tabbar__tab--switch {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.catalog-tabbar__chevron {
  width: var(--space-3-5);
  height: var(--space-3-5);
  transition: rotate var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-tabbar__tab--switch[aria-expanded="true"] .catalog-tabbar__chevron {
  rotate: 180deg;
}

/* Panel pilih alat (native popover di top layer). Posisi `top`/`left`
   diisi JS dari kotak tab; `margin: 0` mematikan pemusatan bawaan UA. */
.catalog-pg-switch {
  position: fixed;
  inset: auto;
  width: min(20rem, calc(100vw - var(--space-8)));
  margin: 0;
  padding: var(--space-1);
  border: var(--border-1) solid var(--catalog-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-background);
  color: var(--catalog-ink);
  box-shadow: var(--shadow-3);
}

.catalog-pg-switch:popover-open {
  animation: catalog-enter var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-pg-switch__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-0-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.catalog-pg-switch__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-0-5);
  padding: var(--space-2) var(--space-2-5);
  border-radius: var(--radius-md);
  color: inherit;
  text-decoration: none;
  transition: background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-pg-switch__link:hover {
  background: var(--catalog-hover);
}

.catalog-pg-switch__link[aria-current="page"] {
  background: var(--catalog-active);
}

.catalog-pg-switch__link:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--border-2) var(--color-ring);
}

.catalog-pg-switch__title {
  font-size: var(--catalog-text-md);
  font-weight: var(--typography-weight-medium);
  line-height: var(--catalog-lh-sm);
}

.catalog-pg-switch__desc {
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xs);
  line-height: var(--catalog-lh-xs);
}

@media (prefers-reduced-motion: reduce) {
  .catalog-pg-switch:popover-open { animation: none; }
  .catalog-tabbar__chevron { transition: none; }
}

/* --- Pencarian (pemicu palette ⌘K) --- */

.catalog-search {
  flex-shrink: 0;
  margin-inline-start: auto;
  display: flex;
  align-items: center;
}

/* Tombol yang berbentuk field — pola ui.shadcn.com. Kulitnya `btn btn--outline`
   DS (garis, latar, hover, fokus); yang diatur di sini cuma tata letak isinya:
   lebar tetap, isi rata awal, placeholder redup. */
.catalog-search__input {
  justify-content: flex-start;
  gap: var(--space-2);
  width: var(--catalog-search-width);
  padding-inline: var(--space-3) var(--space-1-5);
  color: var(--catalog-muted);
  font-weight: var(--typography-weight-normal);
  text-align: start;
}

.catalog-search__icon {
  width: var(--space-4);
  height: var(--space-4);
  flex-shrink: 0;
}

.catalog-search__placeholder {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Palette ⌘K (restyle neutral ink, 18 Sep 2026) ---

   Markup-nya tetap komponen Command (`dialog.command__dialog` +
   `.command--dialog`), jadi perilaku keyboard, filter, dan ARIA milik
   command.js. Yang ditimpa di sini cuma KULIT-nya supaya palette sama dengan
   shell: heading tanpa uppercase, item radius-md setinggi baris nav, sorotan
   `--catalog-active`, backdrop scrim shell. command.css tidak disentuh —
   Command di demo, Combobox, dan konsumen DS tetap bentuk aslinya.

   Scope lewat class `catalog-palette` (bukan ID) supaya snapshot statis di
   preview-fragments/search-palette.html ikut ter-style. Selector dasarnya
   tiga class: command.css dimuat lazy SESUDAH file ini, jadi selector dua
   class milik `.command--dialog` harus dikalahkan lewat spesifisitas. */

.dialog.command__dialog.catalog-palette-dialog {
  /* command.css menimpa max-width `.dialog` dengan lebar palette tanpa batas
     viewport, jadi di ponsel panelnya menempel ke tepi layar. Gutter 16px
     tiap sisi dikembalikan di sini. */
  max-width: min(var(--command-dialog-max-width), calc(100% - var(--space-8)));
}

/* Frame dan backdrop palette SENGAJA tidak ditimpa (keputusan Tony 19 Sep
   2026): border, shadow, radius, dan `::backdrop` milik dialog.css, sama
   dengan Open Preset dan Get Code di Create. Semua modal shell = Dialog DS
   apa adanya. Override ring border-strong + scrim 18 Sep dicabut. */

.command.catalog-palette {
  background-color: var(--color-background);
  color: var(--catalog-ink);
}

.command.catalog-palette .command__input-wrapper {
  height: var(--space-12);
  gap: var(--space-2-5);
  padding-inline: var(--space-4);
  border-bottom-color: var(--catalog-border-hairline);
}

.command.catalog-palette .command__input-wrapper svg {
  width: var(--space-4);
  height: var(--space-4);
  color: var(--catalog-muted);
  opacity: var(--opacity-100);
}

.command.catalog-palette .command__input {
  height: var(--space-12);
  font-size: var(--catalog-text-base);
  line-height: var(--catalog-lh-base);
}

.command.catalog-palette .command__input::placeholder {
  color: var(--catalog-muted);
}

.command.catalog-palette .command__list {
  padding-block: var(--space-1);
  scroll-padding-block: var(--space-2);
}

.command.catalog-palette .command__empty {
  color: var(--catalog-muted);
  font-size: var(--catalog-text-md);
}

.command.catalog-palette .command__group {
  padding: var(--space-1) var(--space-2);
  color: var(--catalog-ink);
}

.command.catalog-palette .command__group-heading {
  padding: var(--space-2) var(--space-2) var(--space-1);
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xs);
  font-weight: var(--typography-weight-medium);
  line-height: var(--catalog-lh-xs);
  letter-spacing: var(--catalog-track-label);
  text-transform: none;
}

.command.catalog-palette .command__item {
  min-height: var(--space-9);
  gap: var(--space-2-5);
  padding: var(--space-1-5) var(--space-2);
  border-radius: var(--radius-md);
  color: var(--catalog-ink);
  font-size: var(--catalog-text-md);
  line-height: var(--catalog-lh-sm);
  transition: background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.command.catalog-palette .command__item[aria-selected='true'] {
  background-color: var(--catalog-active);
  color: var(--catalog-ink);
}

/* Ikon dari `catalogIcon()` — SVG yang sama dengan kartu indeks, viewBox 20,
   digambar 16px di sini. Menimpa aturan `svg` 20px milik `.command--dialog`. */
.command.catalog-palette .command__item svg {
  width: var(--space-4);
  height: var(--space-4);
  color: var(--catalog-muted);
  transition: color var(--catalog-dur-fast) var(--catalog-ease);
}

.command.catalog-palette .command__item[aria-selected='true'] svg {
  color: var(--catalog-ink);
}

.catalog-palette__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Jenis entri (Component/Block/Chart). `margin-inline-start` supaya tetap
   di ujung baris saat RTL. */
.catalog-palette__meta {
  flex-shrink: 0;
  margin-inline-start: auto;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xs);
  line-height: var(--catalog-lh-xs);
}

/* Petunjuk keyboard. Di LUAR `.command__list`: apa pun di dalam list ikut
   disaring command.js dan dibacakan sebagai bagian listbox. */
.catalog-palette__footer {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  gap: var(--space-4);
  height: var(--catalog-meta-height);
  padding-inline: var(--space-4);
  border-top: var(--border-1) solid var(--catalog-border-hairline);
  background: var(--catalog-sunken);
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xs);
  line-height: var(--catalog-lh-xs);
}

.catalog-palette__hint {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
}

.catalog-palette__hint .catalog-kbd {
  justify-content: center;
  min-width: var(--space-5);
}

/* Tutup di ujung, sama seperti ui.shadcn.com. */
.catalog-palette__hint:last-child {
  margin-inline-start: auto;
}

/* Tanpa keyboard fisik petunjuk tombol tidak ada gunanya. */
@media (pointer: coarse) {
  .catalog-palette__footer {
    display: none;
  }
}

.catalog-topbar-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* --- Pemilih bersegmen (tema, arah, viewport, format warna) ---

   Satu bentuk, empat pemakai. Latar abu tipis sebagai rel, tombol aktif
   naik jadi permukaan halaman + bayangan 1 tingkat — terbaca sebagai saklar
   fisik, tanpa warna.

   SENGAJA bukan Toggle Group DS (dicoba 19 Sep 2026, dibatalkan atas
   keputusan Tony): DS tidak punya segmented dengan rel, dan warna aktif
   toggle (`--color-accent`) nyaris tidak terbaca di chrome ini. */
.catalog-segmented {
  display: inline-flex;
  align-items: center;
  gap: var(--space-0-5);
  height: var(--catalog-seg-height);
  padding: var(--space-0-5);
  border-radius: var(--radius-lg);
  background: var(--catalog-hover);
  box-shadow: inset 0 0 0 var(--border-1) var(--catalog-border-hairline);
}

.catalog-segmented__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: var(--catalog-seg-btn);
  height: var(--catalog-seg-btn);
  padding-inline: var(--space-2);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--catalog-muted);
  font-family: inherit;
  font-size: var(--catalog-text-xs);
  font-weight: var(--typography-weight-medium);
  letter-spacing: var(--catalog-track-label);
  cursor: pointer;
  transition: color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease),
              box-shadow var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-segmented--icon .catalog-segmented__btn {
  width: var(--catalog-seg-btn);
  padding-inline: 0;
  font-size: var(--typography-size-sm);
}

.catalog-segmented__btn:hover {
  color: var(--catalog-ink);
}

.catalog-segmented__btn.is-active {
  background: var(--color-background);
  color: var(--catalog-ink);
  box-shadow: var(--shadow-1), 0 0 0 var(--border-1) var(--catalog-border-hairline);
}

.catalog-segmented__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--border-2) var(--color-ring);
}

/* --- Sidebar --- */

.catalog-sidebar {
  width: var(--catalog-sidebar-width);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  height: calc(100vh - var(--catalog-topbar-height));
  position: sticky;
  inset-block-start: var(--catalog-topbar-height);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-block: var(--space-5) var(--space-10);
  padding-inline: var(--space-3);
  border-inline-end: var(--border-1) solid var(--catalog-border-hairline);
  background: var(--color-background);
  scrollbar-width: thin;
  scrollbar-color: var(--catalog-border-strong) transparent;
}

/* Docs tidak punya sidebar — panel mengambil seluruh lebar baris. */
[data-section="about"] .catalog-sidebar {
  display: none;
}

.catalog-mobile-sections {
  display: none;
}

.catalog-nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-0-5);
}

.catalog-nav-empty {
  margin: 0;
  padding-inline: var(--space-2);
  color: var(--catalog-muted);
  font-size: var(--catalog-text-sm);
}

/* Label di atas daftar (Foundations, Playground). */
.catalog-nav-heading {
  margin: 0 0 var(--space-1-5);
  padding-inline: var(--space-2);
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xs);
  font-weight: var(--typography-weight-medium);
  letter-spacing: var(--catalog-track-label);
  line-height: var(--catalog-lh-xs);
}

.catalog-nav-group + .catalog-nav-group {
  margin-block-start: var(--space-1);
}

/* Judul grup = pemicu lipat. Label kecil 12px, bukan tujuan navigasi, jadi
   ia sengaja kalah bobot dari item di bawahnya. */
.catalog-nav-group__title {
  display: flex;
  align-items: center;
  gap: var(--space-1-5);
  height: var(--catalog-row-height);
  padding-inline: var(--space-2);
  border-radius: var(--radius-md);
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xs);
  font-weight: var(--typography-weight-medium);
  letter-spacing: var(--catalog-track-label);
  cursor: pointer;
  user-select: none;
  list-style: none;
  transition: color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-nav-group__title::-webkit-details-marker { display: none; }

.catalog-nav-group__title:hover {
  color: var(--catalog-ink);
  background: var(--catalog-hover);
}

.catalog-nav-group[open] > .catalog-nav-group__title {
  color: var(--catalog-ink);
}

.catalog-nav-group__title:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--border-2) var(--color-ring);
}

.catalog-nav-group__label {
  flex: 1;
  min-width: 0;
}

.catalog-nav-group__count {
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xxs);
  font-variant-numeric: tabular-nums;
}

.catalog-nav-group__chevron {
  display: grid;
  place-items: center;
  width: var(--space-4);
  height: var(--space-4);
  color: var(--catalog-muted);
  transition: rotate var(--catalog-dur) var(--catalog-ease);
}

.catalog-nav-group__chevron svg {
  width: var(--space-3-5);
  height: var(--space-3-5);
}

.catalog-nav-group[open] > .catalog-nav-group__title .catalog-nav-group__chevron {
  rotate: 90deg;
}

/* RTL: panah menunjuk ke arah baca saat tertutup. */
[dir="rtl"] .catalog-nav-group__chevron svg {
  scale: -1 1;
}

/* Lipat beranimasi di engine yang mengenal `::details-content`; engine lain
   tetap membuka/menutup, cuma tanpa gerak. */
.catalog-nav-group::details-content {
  height: 0;
  overflow: clip;
  transition: height var(--catalog-dur) var(--catalog-ease),
              content-visibility var(--catalog-dur) var(--catalog-ease) allow-discrete;
}

.catalog-nav-group[open]::details-content {
  height: auto;
}

.catalog-nav-group__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-px, 0);
  padding-block: var(--space-0-5) var(--space-2);
}

/* Item navigasi: 14px, abu; aktif = tinta, weight 500, permukaan tipis, dan
   bar 2px di tepi awal. Garis panduan tipis di kiri menggantikan cabang
   pohon lama — tetap terbaca bersarang tanpa terlihat seperti file tree. */
.catalog-nav__link {
  position: relative;
  display: flex;
  align-items: center;
  min-height: var(--catalog-row-height);
  padding-inline: var(--space-5) var(--space-2);
  border-radius: var(--radius-md);
  color: var(--catalog-muted);
  font-size: var(--catalog-text-md);
  line-height: var(--catalog-lh-sm);
  text-decoration: none;
  transition: color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-nav-group__list .catalog-nav__link::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: var(--space-2-5);
  width: var(--border-1);
  background: var(--catalog-border-hairline);
  transition: background-color var(--catalog-dur-fast) var(--catalog-ease),
              width var(--catalog-dur-fast) var(--catalog-ease);
}

/* Daftar tanpa grup (Foundations) tidak butuh indent panduan. */
.catalog-nav > .catalog-nav-group__list .catalog-nav__link {
  padding-inline-start: var(--space-2);
}

.catalog-nav > .catalog-nav-group__list .catalog-nav__link::before {
  display: none;
}

.catalog-nav__link:hover {
  color: var(--catalog-ink);
  background: var(--catalog-hover);
}

.catalog-nav__link.active {
  color: var(--catalog-ink);
  font-weight: var(--typography-weight-medium);
  background: var(--catalog-active);
}

.catalog-nav__link.active::before {
  width: var(--border-2);
  background: var(--catalog-ink);
}

.catalog-nav__link:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--border-2) var(--color-ring);
}

/* --- Sidebar Playground (Create / Typeset) ---
   Kartu kontrol mengambang (`.catalog-pg`) menggantikan garis batas sidebar,
   persis panel kiri shadcn. */

[data-section="typeset"] .catalog-sidebar,
[data-section="create"] .catalog-sidebar {
  padding-block: var(--space-3);
  border-inline-end: 0;
}

/* --- Panel dan canvas --- */

.catalog-panel {
  flex: 1;
  min-width: 0;
  padding: var(--catalog-panel-padding);
  padding-block-start: var(--space-8);
}

.catalog-content {
  max-width: var(--catalog-content-max);
  margin-inline: auto;
}

[data-section="blocks"] .catalog-content,
[data-section="charts"] .catalog-content,
[data-section="typeset"] .catalog-content,
[data-section="create"] .catalog-content {
  max-width: var(--catalog-content-wide);
}

/* Halaman statis (Docs, Foundations, Playground) tidak punya bar canvas,
   kaki dokumen, atau canvas demo. */
[data-section="about"] .catalog-canvas-bar,
[data-section="token"] .catalog-canvas-bar,
[data-section="typeset"] .catalog-canvas-bar,
[data-section="create"] .catalog-canvas-bar,
[data-section="about"] #canvas,
[data-section="token"] #canvas,
[data-section="typeset"] #canvas,
[data-section="create"] #canvas {
  display: none;
}

/* Tingginya DIKUNCI ke bilangan bulat, dan itu bukan selera.

   Versi pertama bar ini memakai tinggi yang mengikuti isi, dan tingginya
   jatuh di 36,5px — jadi canvas mulai di offset pecahan. Akibatnya jarak
   panel yang tokennya 4px terbaca 5px di dua komponen, dan klik Playwright ke
   item di dalam panel meleset cukup jauh untuk memicu light dismiss. Lima
   komponen merah, satu setengah piksel.

   Aturan umumnya: elemen chrome yang menggeser awal wilayah ukur wajib
   bertinggi bilangan bulat. Tinggi yang mengikuti isi bergantung pada font,
   dan font itu pecahan. Redesign neutral ink menaikkannya ke 72px untuk
   judul 36/40px + breadcrumb 20px; breadcrumb lalu dihapus, jadi bar turun ke
   40px (tinggi baris judul) — angka bulat yang baru, aturan yang sama. */
.catalog-canvas-bar {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  height: var(--catalog-canvas-bar-height);
  margin-block-end: var(--space-4);
}

.catalog-canvas-heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
  min-width: 0;
}

.catalog-canvas-title {
  margin: 0;
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-display);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-display);
  letter-spacing: var(--catalog-track-display);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.catalog-canvas-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* --- Baris install + sumber ---

   Tinggi dikunci bilangan bulat, alasan sama dengan `.catalog-canvas-bar`:
   ia menggeser awal wilayah ukur. */
.catalog-doc-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  height: var(--catalog-meta-height);
  margin-block-end: var(--space-10);
}

.catalog-install {
  display: flex;
  align-items: center;
  gap: var(--space-2-5);
  min-width: 0;
  height: var(--catalog-meta-height);
  padding-inline: var(--space-3-5) var(--space-1);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-lg);
  background: var(--catalog-sunken);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
}

.catalog-install__prompt {
  color: var(--catalog-muted);
  user-select: none;
}

.catalog-install__cmd {
  min-width: 0;
  color: var(--catalog-ink);
  font-family: inherit;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.catalog-doc-meta__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  height: var(--catalog-meta-height);
  padding-inline: var(--space-3);
  border-radius: var(--radius-lg);
  color: var(--catalog-muted);
  font-size: var(--catalog-text-sm);
  font-weight: var(--typography-weight-medium);
  text-decoration: none;
  transition: color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease);
}

/* Berdiri sendiri (Charts, tanpa baris install): teksnya sejajar tepi
   judul, bukan tepi kotak hover-nya. */
.catalog-doc-meta > .catalog-doc-meta__link:first-child {
  margin-inline-start: calc(var(--space-3) * -1);
}

.catalog-doc-meta__link:hover {
  color: var(--catalog-ink);
  background: var(--catalog-hover);
}

.catalog-doc-meta__link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

.catalog-canvas:focus {
  outline: none;
}

/* Simulasi viewport: bingkai putus-putus di sekeliling lebar yang
   disimulasikan. `outline`, bukan `border` — tidak menggeser isi. */
.catalog-canvas[data-viewport='mobile'],
.catalog-canvas[data-viewport='tablet'] {
  margin-inline: auto;
  outline: var(--border-1) dashed var(--catalog-border-strong);
  outline-offset: var(--space-3);
}

/* Ditambah dua garis bingkai `.catalog-demo__frame`, supaya ISI bingkai —
   iframe block, "jendela" block itu — tepat 375/768px. Tanpa ini Tablet jatuh
   di 766px, di bawah ambang 768 Sidebar, dan block malah tampil mode ponsel. */
.catalog-canvas[data-viewport='mobile'] {
  max-width: calc(var(--catalog-sim-mobile) + 2 * var(--border-1));
}

.catalog-canvas[data-viewport='tablet'] {
  max-width: calc(var(--catalog-sim-tablet) + 2 * var(--border-1));
}

.catalog-empty-state {
  margin: 0;
  color: var(--catalog-muted);
}

/* Fade masuk route — OPACITY saja (lihat larangan di kepala file). */
.catalog-canvas.is-entering,
.catalog-page.is-entering {
  animation: catalog-enter var(--catalog-dur) var(--catalog-ease);
}

@keyframes catalog-enter {
  from { opacity: var(--opacity-0); }
  to { opacity: var(--opacity-100); }
}

/* --- Indeks section (`#/components` telanjang, dst) --- */

.catalog-index {
  display: flex;
  flex-direction: column;
  gap: var(--space-10);
}

.catalog-index__lede {
  margin: 0;
  max-width: 62ch;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-lg);
  line-height: var(--catalog-lh-lg);
}

.catalog-index__group {
  padding-block-start: var(--space-6);
  border-block-start: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-index__head {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.catalog-index__title {
  margin: 0;
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-lg);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-base);
  letter-spacing: var(--catalog-track-tight);
}

.catalog-index__count {
  color: var(--catalog-muted);
  font-size: var(--catalog-text-sm);
  font-variant-numeric: tabular-nums;
}

.catalog-index__desc {
  margin: var(--space-1) 0 0;
  max-width: 62ch;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-md);
  line-height: var(--catalog-lh-sm);
}

.catalog-index__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--catalog-index-col), 1fr));
  gap: var(--space-1) var(--space-4);
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}

/* Baris indeks: ubin ikon 32px + nama. Ubin memakai permukaan sunken +
   garis rambut supaya ikon punya "wadah" yang sama di tiap baris, dan saat
   hover ubin ikut naik ke tinta — satu-satunya perubahan warna di baris. */
.catalog-index__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-inline: calc(var(--space-2) * -1);
  padding: var(--space-1-5) var(--space-2);
  border-radius: var(--radius-md);
  color: var(--catalog-ink);
  font-size: var(--catalog-text-base);
  line-height: var(--catalog-lh-base);
  text-decoration: none;
  transition: background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-index__link:hover {
  background: var(--catalog-hover);
}

.catalog-index__icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: var(--catalog-icon-btn);
  height: var(--catalog-icon-btn);
  border-radius: var(--radius-lg);
  background: var(--catalog-sunken);
  box-shadow: inset 0 0 0 var(--border-1) var(--catalog-border-hairline);
  color: var(--catalog-muted);
  transition: color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-index__icon-svg {
  width: var(--space-5);
  height: var(--space-5);
}

.catalog-index__link:hover .catalog-index__icon {
  color: var(--catalog-ink);
  background: var(--color-background);
}

.catalog-index__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.catalog-index__link:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--border-2) var(--color-ring);
}

/* --- Kotak demo ---

   `.catalog-demo` (section), `.catalog-demo__frame`, dan
   `.catalog-demo__preview` LELUHUR setiap demo — seluruh larangan titik
   acuan `position: fixed` berlaku di ketiganya, dan `overflow` tetap
   `visible`. Kepala (nama + Preview/Code + copy) di LUAR bingkai, keterangan
   di bawahnya: bingkai cuma memuat hal yang diperiksa. */
.catalog-demo {
  width: 100%;
  scroll-margin-block-start: calc(var(--catalog-topbar-height) + var(--space-6));
  margin-block-end: var(--space-12);
}

.catalog-demo:last-child {
  margin-block-end: 0;
}

.catalog-demo__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--catalog-icon-btn);
  margin-block-end: var(--space-3);
}

.catalog-demo__name {
  margin: 0;
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-base);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-base);
  letter-spacing: var(--catalog-track-tight);
}

.catalog-demo__tools {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
}

/* Tab Preview/Code — bentuk segmented yang sama dengan `.catalog-segmented`
   di atas, bukan Tabs DS (alasan sama, lihat di sana). */
.catalog-demo__tabs {
  display: inline-flex;
  align-items: center;
  gap: var(--space-0-5);
  height: var(--catalog-seg-height);
  padding: var(--space-0-5);
  border-radius: var(--radius-lg);
  background: var(--catalog-hover);
  box-shadow: inset 0 0 0 var(--border-1) var(--catalog-border-hairline);
}

.catalog-demo__tab {
  height: var(--catalog-seg-btn);
  padding-inline: var(--space-2-5);
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--catalog-muted);
  font-family: inherit;
  font-size: var(--catalog-text-xs);
  font-weight: var(--typography-weight-medium);
  letter-spacing: var(--catalog-track-label);
  cursor: pointer;
  transition: color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease),
              box-shadow var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-demo__tab:hover {
  color: var(--catalog-ink);
}

.catalog-demo__tab[aria-selected="true"] {
  background: var(--color-background);
  color: var(--catalog-ink);
  box-shadow: var(--shadow-1), 0 0 0 var(--border-1) var(--catalog-border-hairline);
}

.catalog-demo__tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--border-2) var(--color-ring);
}

.catalog-demo__copy.is-copied {
  color: var(--catalog-ink);
}

/* Centang "muncul" — `scale` di ikon, elemen DAUN, bukan leluhur demo. */
.catalog-demo__copy.is-copied svg {
  animation: catalog-pop var(--catalog-dur) var(--catalog-ease);
}

@keyframes catalog-pop {
  from { opacity: var(--opacity-0); scale: 0.6; }
  to { opacity: var(--opacity-100); scale: 1; }
}

.catalog-demo__frame {
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  background: var(--color-background);
}

/* Grid satu kolom `minmax(0, 1fr)`: isi selebar bingkai (Data Table, Chart)
   tapi tidak bisa mendorong bingkai melebar; `align-content: center`
   menengahkan demo pendek secara vertikal di tinggi minimum. */
.catalog-demo__preview {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  min-height: var(--catalog-preview-min);
  padding: var(--space-8) var(--space-3);
  border-radius: inherit;
}

/* Block itu layar utuh — tampil rapat ke bingkai, tanpa padding preview.
   Specificity-nya di atas override padding di @media bawah. */
[data-section="blocks"] .catalog-demo__preview,
.catalog-demo__preview.catalog-demo__preview--framed {
  padding: 0;
}

/* Block dipajang di iframe (lihat kepala catalog/block-frame.js): media query
   dan matchMedia di dalamnya membaca lebar iframe ini, bukan jendela. Jadi
   lebarnya WAJIB penuh selebar kotak preview — itulah "layar" block.
   Tingginya TETAP (layar setinggi `--catalog-block-frame-height`, isi digulir
   di dalam) — lihat `buildBlockFrame` di catalog.js: satuan vh di dalam block
   membuat frame yang dipanjangkan setinggi isi tumbuh tanpa ujung. */
.catalog-demo__block-frame {
  display: block;
  width: 100%;
  height: var(--catalog-block-frame-height);
  border: 0;
  border-radius: inherit;
  background-color: var(--color-background);
}

/* Demo komponen di frame (Sidebar, `FRAMED_COMPONENTS` di catalog.js) punya
   tinggi tetap di markup-nya, bukan `100svh` seperti block. Tinggi awalnya
   dibuat pendek supaya `fitBlockFrame` mengukur tinggi isi, bukan tinggi
   awal frame yang lebih besar dari demonya. */
[data-section="components"] .catalog-demo__block-frame {
  height: var(--catalog-preview-min);
}

.catalog-demo__code {
  max-height: var(--catalog-code-max);
  overflow: auto;
  padding: var(--space-4) var(--space-5);
  border-radius: inherit;
  background: var(--catalog-sunken);
  transition: opacity var(--catalog-dur) var(--catalog-ease);
}

@starting-style {
  .catalog-demo__code {
    opacity: var(--opacity-0);
  }
}

.catalog-demo__code pre {
  margin: 0;
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
  line-height: var(--catalog-lh-code);
  font-variant-ligatures: none;
  white-space: pre;
}

.catalog-demo__code code {
  counter-reset: catalog-code-line;
}

.catalog-demo__note {
  margin: var(--space-3) 0 0;
  max-width: 72ch;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-md);
  line-height: var(--catalog-lh-sm);
}

/* --- Blok kode (bersama: demo, Docs, Typeset) --- */

.catalog-code-line {
  display: flex;
  gap: var(--space-4);
  counter-increment: catalog-code-line;
}

/* `text-align: end`, bukan `right` — nilai logis, jadi ikut arah teks.
   `test:rtl` menolak `right` fisik. */
.catalog-code-line__num {
  flex: none;
  min-width: 2ch;
  text-align: end;
  color: var(--catalog-code-linenum);
  user-select: none;
}

.catalog-code-line__num::before { content: counter(catalog-code-line); }
.catalog-code-line__content { white-space: pre; }

.catalog-code-token--keyword { color: var(--catalog-code-keyword); font-weight: var(--typography-weight-semibold); }
.catalog-code-token--tag { color: var(--catalog-code-tag); }
.catalog-code-token--attr { color: var(--catalog-code-attr); }
.catalog-code-token--string { color: var(--catalog-code-string); }
.catalog-code-token--comment { color: var(--catalog-code-comment); font-style: italic; }
.catalog-code-token--punct { color: var(--catalog-code-punct); }

/* --- Kaki dokumen: Dependencies + pager --- */

.catalog-doc-footer {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  margin-block-start: var(--space-16);
}

.catalog-doc-section {
  scroll-margin-block-start: calc(var(--catalog-topbar-height) + var(--space-6));
  padding-block-start: var(--space-8);
  border-block-start: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-doc-section__title {
  margin: 0;
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-xl);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-lg);
  letter-spacing: var(--catalog-track-heading);
}

.catalog-doc-section__desc,
.catalog-doc-footer__empty {
  margin: var(--space-1-5) 0 0;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-md);
  line-height: var(--catalog-lh-sm);
}

.catalog-doc-section code,
.catalog-doc-footer__empty code {
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-code-inline);
}

.catalog-dep-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}

.catalog-dep {
  display: inline-flex;
  align-items: center;
  height: var(--catalog-icon-btn);
  padding-inline: var(--space-3);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-lg);
  color: var(--catalog-ink);
  font-size: var(--catalog-text-md);
  font-weight: var(--typography-weight-medium);
  text-decoration: none;
  transition: border-color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease);
}

a.catalog-dep:hover {
  border-color: var(--catalog-border-strong);
  background: var(--catalog-hover);
}

a.catalog-dep:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

.catalog-dep--lib {
  background: var(--catalog-sunken);
  color: var(--catalog-muted);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
  font-weight: var(--typography-weight-normal);
}

.catalog-pager {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

.catalog-pager__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-0-5);
  padding: var(--space-3-5) var(--space-4);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-pager__link--next {
  text-align: end;
  grid-column: 2;
}

.catalog-pager__link:hover {
  border-color: var(--catalog-border-strong);
  background: var(--catalog-hover);
}

.catalog-pager__link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

.catalog-pager__dir {
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xs);
  font-weight: var(--typography-weight-medium);
  letter-spacing: var(--catalog-track-label);
}

.catalog-pager__name {
  color: var(--catalog-ink);
  font-size: var(--catalog-text-base);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-base);
}

/* --- Rel "On this page" (Components) — dipakai bersama Typeset --- */

.catalog-toc {
  display: none;
  width: var(--catalog-toc-width);
  flex-shrink: 0;
  padding-block: var(--space-8) var(--space-10);
  padding-inline: var(--space-6);
  overflow-y: auto;
  height: calc(100vh - var(--catalog-topbar-height));
  position: sticky;
  inset-block-start: var(--catalog-topbar-height);
  background: var(--color-background);
}

[data-section="typeset"] {
  --catalog-toc-width: 320px;
}

/* Rel kanan Typeset = kartu Docs | Prompt mengambang (persis shadcn),
   bukan kolom bergaris. Kartunya sendiri yang menggulung isi. */
[data-section="typeset"] .catalog-toc {
  padding-block: var(--space-3);
  padding-inline: 0 var(--space-3);
}

@media (min-width: 1200px) {
  [data-section="components"] .catalog-toc,
  [data-section="typeset"] .catalog-toc {
    display: block;
  }
}

.catalog-toc__title {
  margin: 0 0 var(--space-3);
  color: var(--catalog-ink);
  font-size: var(--catalog-text-xs);
  font-weight: var(--typography-weight-semibold);
  letter-spacing: var(--catalog-track-label);
}

/* Garis panduan di tepi awal daftar; link aktif menimpanya dengan garis
   tinta di posisi yang sama. */
.catalog-toc__list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
  border-inline-start: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-toc__link {
  display: block;
  width: 100%;
  margin-inline-start: calc(var(--border-1) * -1);
  padding-block: var(--space-1);
  padding-inline: var(--space-3) 0;
  border: 0;
  border-inline-start: var(--border-1) solid transparent;
  background: none;
  color: var(--catalog-muted);
  font: inherit;
  font-size: var(--catalog-text-sm);
  line-height: var(--catalog-lh-sm);
  text-align: start;
  cursor: pointer;
  transition: color var(--catalog-dur-fast) var(--catalog-ease),
              border-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-toc__link:hover {
  color: var(--catalog-ink);
}

.catalog-toc__link.is-active {
  border-inline-start-color: var(--catalog-ink);
  color: var(--catalog-ink);
  font-weight: var(--typography-weight-medium);
}

.catalog-toc__link:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--border-2) var(--color-ring);
}

/* --- Halaman statis (Docs, Foundations, Playground) ---
   Isi `#page`, saudara `#canvas` di dalam `.catalog-content`. */

.catalog-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-10);
  padding-block-end: var(--space-16);
  width: 100%;
}

/* Typeset: kotak pratinjau sudah setinggi layar dan menggulung sendiri,
   jadi ruang bawah halaman cuma menambah gulir kosong. */
[data-section="typeset"] .catalog-page {
  padding-block-end: 0;
}

[data-section="about"] .catalog-page {
  max-width: var(--catalog-page-max);
  margin-inline: auto;
}

.catalog-page__title {
  margin: 0 0 var(--space-3);
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-display);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-display);
  letter-spacing: var(--catalog-track-display);
}

.catalog-page .catalog-page__lede {
  margin: 0;
  max-width: 62ch;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-lg);
  line-height: var(--catalog-lh-lg);
}

/* Prosa — dibatasi ke Docs. Halaman lain (Foundations, Playground) punya
   class sendiri; selector elemen polos seperti `.catalog-page p` di sana
   menimpa ukuran lede dan font pratinjau Typeset. */
[data-section="about"] .catalog-page section {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

[data-section="about"] .catalog-page h2 {
  margin: 0;
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-xl);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-lg);
  letter-spacing: var(--catalog-track-heading);
}

[data-section="about"] .catalog-page h3 {
  margin: 0;
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-lg);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-base);
  letter-spacing: var(--catalog-track-tight);
}

[data-section="about"] .catalog-page p {
  margin: 0;
  max-width: 68ch;
  color: var(--catalog-body-foreground);
  font-size: var(--catalog-text-base);
  line-height: var(--catalog-lh-prose);
}

[data-section="about"] .catalog-page ul {
  margin: 0;
  max-width: 68ch;
  padding-inline-start: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
  color: var(--catalog-body-foreground);
  font-size: var(--catalog-text-base);
  line-height: var(--catalog-lh-prose);
}

[data-section="about"] .catalog-page li::marker {
  color: var(--catalog-muted);
}

[data-section="about"] .catalog-page :not(pre) > code {
  padding: var(--space-0-5) var(--space-1-5);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-md);
  background: var(--catalog-sunken);
  color: var(--catalog-ink);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-code-inline);
}

.catalog-page__code-block {
  margin: 0;
  padding: var(--space-4) var(--space-5);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  background: var(--catalog-sunken);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
  line-height: var(--catalog-lh-code);
  font-variant-ligatures: none;
  overflow-x: auto;
  counter-reset: catalog-code-line;
}

/* Changelog: garis waktu dua kolom — tanggal mono di kiri, isi di kanan. */
.catalog-changelog {
  display: flex;
  flex-direction: column;
  margin: 0;
  border-block-start: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-changelog__entry {
  display: grid;
  grid-template-columns: var(--catalog-changelog-date) minmax(0, 1fr);
  gap: var(--space-4);
  padding-block: var(--space-4);
  border-block-end: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-page .catalog-changelog__version {
  margin: 0;
  color: var(--catalog-muted);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
  line-height: var(--catalog-lh-prose);
  font-variant-numeric: tabular-nums;
}

.catalog-page .catalog-changelog__desc {
  margin: 0;
  color: var(--catalog-body-foreground);
}

/* --- Playground: panel kontrol (Typeset + Create) ---

   Tiruan panel kiri ui.shadcn.com/typeset dan /create: kartu mengambang,
   satu baris per kontrol (tanpa tombol Menu shadcn — pindah alat lewat tab
   Playground di header). Tiap baris = SATU
   tombol besar (label kecil di atas, nilai di bawah, ikon di kanan) yang
   membuka Dropdown Menu. Tombol lock menumpuk di sisi kanan baris, muncul
   saat baris di-hover, difokus (`:focus-within` — pengguna keyboard
   melihatnya saat Tab sampai ke sana), atau sedang terkunci. */

.catalog-pg {
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
  padding: var(--space-2);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  background: var(--catalog-sunken);
}

.catalog-pg__sep {
  height: var(--border-1);
  margin-block: var(--space-1);
  margin-inline: calc(var(--space-2) * -1);
  background: var(--catalog-border-hairline);
}

.catalog-pg-row {
  position: relative;
}

.catalog-pg-row__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  min-height: var(--space-11);
  padding-block: var(--space-1-5);
  padding-inline: var(--space-2-5);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-lg);
  background: var(--color-background);
  color: var(--catalog-ink);
  font-family: inherit;
  text-align: start;
  cursor: pointer;
  transition: background-color var(--catalog-dur-fast) var(--catalog-ease),
              border-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-pg-row__trigger:hover,
.catalog-pg-row__trigger[aria-expanded="true"] {
  background: var(--catalog-hover);
  border-color: var(--catalog-border-strong);
}

.catalog-pg-row__trigger:focus-visible {
  outline: none;
  border-color: var(--color-ring);
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

.catalog-pg-row__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.catalog-pg-row__label {
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xxs);
  line-height: var(--catalog-lh-xxs);
}

.catalog-pg-row__value {
  overflow: hidden;
  color: var(--catalog-ink);
  font-size: var(--catalog-text-sm);
  font-weight: var(--typography-weight-medium);
  line-height: var(--catalog-lh-xs);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.catalog-pg-row__icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: var(--space-4);
  height: var(--space-4);
  color: var(--catalog-muted);
}

.catalog-pg-row__icon svg {
  width: var(--space-4);
  height: var(--space-4);
}

.catalog-pg-row__glyph {
  font-size: var(--catalog-text-sm);
  font-weight: var(--typography-weight-medium);
  line-height: 1;
}

.catalog-pg-swatch {
  width: var(--space-3-5);
  height: var(--space-3-5);
  border-radius: var(--radius-full);
  background: var(--pg-swatch);
  box-shadow: inset 0 0 0 var(--border-1) color-mix(in oklch, var(--color-foreground) 12%, transparent);
}

/* Lock: 24px — batas minimum target sentuh WCAG 2.5.8. Menumpang di atas
   tombol baris, di kiri ikon, jadi tidak menambah tinggi panel. */
.catalog-pg-lock {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: calc(var(--space-2-5) + var(--space-4) + var(--space-1));
  display: grid;
  place-items: center;
  width: var(--space-6);
  height: var(--space-6);
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--color-background);
  color: var(--catalog-muted);
  cursor: pointer;
  opacity: var(--opacity-0);
  translate: 0 -50%;
  transition: opacity var(--catalog-dur-fast) var(--catalog-ease),
              color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-pg-lock svg {
  width: var(--space-3-5);
  height: var(--space-3-5);
}

.catalog-pg-row:hover .catalog-pg-lock,
.catalog-pg-row:focus-within .catalog-pg-lock,
.catalog-pg-row.is-locked .catalog-pg-lock {
  opacity: var(--opacity-100);
}

.catalog-pg-row:hover .catalog-pg-lock {
  background: var(--catalog-hover);
}

.catalog-pg-lock:hover,
.catalog-pg-row.is-locked .catalog-pg-lock {
  color: var(--catalog-ink);
  background: var(--catalog-active);
}

.catalog-pg-lock:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--border-2) var(--color-ring);
}

/* Menu pilihan: panjang daftar font (23 item) melebihi tinggi layar kecil,
   jadi panel digulung sendiri. */
.catalog-pg-menu {
  max-height: min(60vh, var(--catalog-code-max));
  overflow-y: auto;
}

.catalog-pg-menu a.dropdown-menu__item {
  color: inherit;
  text-decoration: none;
}

.catalog-pg-menu a.dropdown-menu__item[aria-current="page"] {
  font-weight: var(--typography-weight-semibold);
}

/* Aksi menempel di dasar sidebar (sidebar = wadah gulungnya), jadi Shuffle
   dan Get Code selalu terjangkau walau kontrolnya panjang. */
.catalog-pg__actions {
  position: sticky;
  inset-block-end: calc(var(--space-3) * -1);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: var(--space-2);
  margin-block-start: var(--space-1);
  padding-block-start: var(--space-2);
  border-block-start: var(--border-1) solid var(--catalog-border-hairline);
  background: var(--catalog-sunken);
}

/* Get Code Typeset: kodenya sudah tampil di rel kanan ≥1200px. */
@media (min-width: 1200px) {
  .catalog-pg__actions .catalog-pg__narrow-only {
    display: none;
  }
}

/* --- Playground: pratinjau + pager --- */

/* Satu bingkai membungkus bar pager (atas, diam) + kotak gulir pratinjau.
   Bar di luar kotak gulir, jadi tidak pernah menutupi teks dokumen atau
   link yang sedang difokus (WCAG 2.4.11). `overflow: clip` menjaga sudut
   bar dan pratinjau ikut radius bingkai. */
.catalog-pg-stage {
  /* Tinggi bar + garis bawahnya + garis atas/bawah bingkai: dikurangkan
     dari tinggi pratinjau supaya bingkai pas satu layar. */
  --catalog-pg-chrome-height: calc(var(--space-8) + var(--space-2) * 2 + var(--border-1) * 3);
  display: grid;
  overflow: clip;
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  background: var(--color-background);
}

/* Tinggi tetap + gulung internal: bar pager tetap terlihat walau dokumen
   panjang. Fokus terlihat wajib — region ini bisa difokus supaya pengguna
   keyboard bisa menggulungnya. Ring fokus dipasang di dalam (inset) karena
   bingkai memotong apa pun di luar batasnya. */
/* `position: relative` WAJIB: KaTeX menaruh salinan MathML untuk screen
   reader sebagai `position: absolute`. Tanpa ancestor ber-posisi di dalam
   kotak gulir ini, elemen itu lolos dari overflow dan memanjangkan seluruh
   halaman (area kosong ribuan px di bawah Typeset). */
.catalog-pg-preview {
  position: relative;
  height: calc(100vh - var(--catalog-topbar-height) - var(--space-8) - var(--catalog-panel-padding) - var(--catalog-pg-chrome-height));
  min-height: var(--catalog-code-max);
  overflow-y: auto;
  padding-block: var(--space-12);
  padding-inline: var(--space-8);
  scrollbar-width: thin;
  scrollbar-color: var(--catalog-border-strong) transparent;
}

.catalog-pg-preview:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--ring-width) var(--color-ring-focus);
}

.catalog-typeset-stage .catalog-typeset-preview {
  margin-inline: auto;
}

.catalog-pg-pager {
  display: flex;
  align-items: center;
  padding: var(--space-2);
  border-block-end: var(--border-1) solid var(--catalog-border-hairline);
  background: var(--catalog-sunken);
}

/* Layar sempit: tombol tetap satu baris dan bisa digeser, bukan patah
   ke baris kedua yang mendorong pratinjau turun. */
.catalog-pg-pager__group {
  display: flex;
  gap: var(--space-1);
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}

/* Segmented control: yang aktif "terangkat" ke permukaan pratinjau
   (latar + garis), yang lain teks muted. Tinggi 32px — di atas minimum
   target 24px (WCAG 2.5.8).

   SENGAJA bukan `toggle` DS (dicoba 19 Sep 2026, dibatalkan atas keputusan
   Tony): warna aktif toggle adalah `--color-accent`, yang hampir sama dengan
   latar bar ini (`--catalog-sunken`), sehingga tab aktif tidak terlihat. */
.catalog-pg-pager__btn {
  flex: none;
  height: var(--space-8);
  padding-inline: var(--space-3);
  border: var(--border-1) solid transparent;
  border-radius: var(--radius-md);
  background: none;
  color: var(--catalog-muted);
  font-family: inherit;
  font-size: var(--catalog-text-sm);
  font-weight: var(--typography-weight-medium);
  cursor: pointer;
  transition: color var(--catalog-dur-fast) var(--catalog-ease),
              background-color var(--catalog-dur-fast) var(--catalog-ease),
              border-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-pg-pager__btn:hover {
  color: var(--catalog-ink);
  background: var(--catalog-active);
}

.catalog-pg-pager__btn[aria-pressed="true"] {
  border-color: var(--catalog-border-hairline);
  background: var(--color-background);
  color: var(--catalog-ink);
}

.catalog-pg-pager__btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

/* --- Typeset --- */

.catalog-typeset-codepanel {
  height: 100%;
}

/* Kartu Docs | Prompt: kepala (tab kiri, framework kanan) diam, badan
   menggulung. Tabs dan Select komponen asli — cuma tata letaknya di sini. */
.catalog-typeset-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  background: var(--catalog-sunken);
  overflow: hidden;
}

.catalog-typeset-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  flex-shrink: 0;
  padding: var(--space-2);
  border-block-end: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-typeset-panel__framework .select__trigger {
  width: auto;
  min-width: calc(var(--space-24) + var(--space-4));
}

.catalog-typeset-panel__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-4);
  scrollbar-width: thin;
  scrollbar-color: var(--catalog-border-strong) transparent;
}

.catalog-typeset-panel__body[hidden] {
  display: none;
}

.catalog-typeset-panel__body:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--border-2) var(--color-ring);
}

.catalog-typeset-step__action {
  align-self: flex-start;
}

.catalog-typeset-prompt {
  margin: var(--space-3) 0;
  max-height: var(--catalog-code-max);
  overflow: auto;
  padding: var(--space-3);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-lg);
  background: var(--color-background);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-xs);
  line-height: var(--catalog-lh-sm);
  white-space: pre-wrap;
  word-break: break-word;
}

.catalog-typeset-codepanel__steps {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.catalog-typeset-step {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.catalog-typeset-step__title {
  margin: 0;
  color: var(--catalog-ink);
  font-size: var(--catalog-text-md);
  font-weight: var(--typography-weight-semibold);
}

.catalog-typeset-step__desc {
  margin: 0;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-xs);
  line-height: var(--catalog-lh-xs);
}

.catalog-typeset-step__code {
  position: relative;
  padding: var(--space-3);
  padding-inline-end: calc(var(--space-3) + var(--catalog-icon-btn));
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-lg);
  background: var(--catalog-sunken);
  overflow-x: auto;
}

.catalog-typeset-step__code .catalog-demo__copy {
  position: absolute;
  inset-block-start: var(--space-1);
  inset-inline-end: var(--space-1);
  background: var(--catalog-sunken);
}

.catalog-typeset-step__code pre {
  margin: 0;
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-xs);
  line-height: var(--catalog-lh-sm);
  font-variant-ligatures: none;
  white-space: pre;
}

.catalog-typeset-preview {
  max-width: var(--typeset-measure, 65ch);
  font-family: var(--typeset-font-body, var(--typography-family-sans));
  font-size: var(--typeset-size, var(--typography-size-base));
  line-height: var(--typeset-leading, var(--typography-leading-normal));
  color: var(--catalog-body-foreground);
  overflow-wrap: break-word;
}

/* Alur vertikal ala prose shadcn: dokumen = anak langsung yang berurutan,
   tanpa wadah flex. Jarak antar blok = Flow (em, ikut Size). Heading dapat
   jarak atas lebih besar, dan blok tepat setelah heading lebih rapat.
   Angka diukur dari ui.shadcn.com/preview/typeset di 15px: p 18.75px,
   h2 32.8px, h3 21.1px, hr 45px, setelah heading 1em. Ingat em di sini
   dihitung di ukuran font elemen itu sendiri (h2 = 1.25em), jadi pengali
   h2 1.4 × flow × 1.25em = 1.75× flow teks badan. Sama persis dengan
   TYPESET_PORTABLE_CSS di catalog.js. */
.catalog-typeset-preview > * {
  margin-block: 0;
}

.catalog-typeset-preview > * + * {
  margin-block-start: var(--typeset-flow, 1.25em);
}

.catalog-typeset-preview > * + h2 {
  margin-block-start: calc(var(--typeset-flow, 1.25em) * 1.4);
}

.catalog-typeset-preview > * + h3 {
  margin-block-start: var(--typeset-flow, 1.25em);
}

.catalog-typeset-preview > * + hr {
  margin-block-start: calc(var(--typeset-flow, 1.25em) * 2.4);
}

.catalog-typeset-preview > hr + * {
  margin-block-start: var(--typeset-flow, 1.25em);
}

.catalog-typeset-preview > :is(h1, h2, h3) + * {
  margin-block-start: 1em;
}

.catalog-typeset-preview h1,
.catalog-typeset-preview h2,
.catalog-typeset-preview h3 {
  font-family: var(--typeset-font-heading, var(--typography-family-sans));
  font-weight: var(--typography-weight-semibold);
  color: var(--catalog-heading-foreground);
  text-wrap: balance;
}

.catalog-typeset-preview h1 {
  font-size: 1.75em;
  line-height: var(--typography-leading-snug);
}

.catalog-typeset-preview h2 {
  font-size: 1.25em;
  line-height: var(--typography-leading-snug);
}

.catalog-typeset-preview h3 {
  font-size: 1.125em;
  line-height: var(--typography-leading-snug);
}

.catalog-typeset-preview p {
  line-height: inherit;
  text-wrap: pretty;
}

.catalog-typeset-preview strong {
  font-weight: var(--typography-weight-semibold);
  color: var(--catalog-heading-foreground);
}

.catalog-typeset-preview a {
  color: var(--catalog-heading-foreground);
  font-weight: var(--typography-weight-medium);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklch, currentColor 30%, transparent);
  text-underline-offset: 0.2em;
}

.catalog-typeset-preview a:hover {
  text-decoration-color: currentColor;
}

.catalog-typeset-preview :not(pre) > code {
  font-family: var(--typeset-font-mono, var(--typography-family-mono));
  font-size: 0.875em;
  padding-inline: var(--space-1);
  background: var(--catalog-sunken);
  border-radius: var(--radius-md);
}

/* Blok kode catalog membawa font + ukuran tetap sendiri — di pratinjau
   dikembalikan ke kontrol Mono dan Size. */
.catalog-typeset-preview .catalog-page__code-block {
  font-family: var(--typeset-font-mono, var(--typography-family-mono));
  font-size: 0.875em;
}

.catalog-typeset-preview ul,
.catalog-typeset-preview ol {
  padding-inline-start: 1.5em;
}

.catalog-typeset-preview li + li,
.catalog-typeset-preview li > :is(ul, ol) {
  margin-block-start: 0.5em;
}

.catalog-typeset-preview li::marker {
  color: var(--catalog-muted);
}

.catalog-typeset-preview blockquote {
  padding-inline-start: 1em;
  border-inline-start: var(--border-2) solid var(--catalog-border-hairline);
  color: var(--catalog-heading-foreground);
}

.catalog-typeset-preview blockquote > p + p {
  margin-block-start: var(--typeset-flow, 1.25em);
}

.catalog-typeset-preview hr {
  height: 0;
  border: 0;
  border-block-start: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-typeset-preview figure {
  margin-inline: 0;
}

.catalog-typeset-preview figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-lg);
  background: var(--catalog-sunken);
}

.catalog-typeset-preview figcaption {
  margin-block-start: 0.75em;
  font-size: 0.875em;
  color: var(--catalog-muted);
  text-align: center;
}

/* Tabel prosa: sel boleh membungkus (Table DS default nowrap, cocok untuk
   data, tapi di prosa kolom keterangan jadi terpotong). */
.catalog-typeset-preview .table__cell {
  white-space: normal;
}

/* Daftar tugas (Notes): tanpa bullet, checkbox DS menggantikan penanda. */
.catalog-typeset-tasks {
  list-style: none;
}

.catalog-typeset-preview .catalog-typeset-tasks {
  padding-inline-start: 0;
}

.catalog-typeset-tasks label {
  display: flex;
  align-items: baseline;
  gap: 0.625em;
}

.catalog-typeset-tasks .checkbox {
  flex: none;
  translate: 0 0.15em;
}

/* Pesan pengguna di dokumen Chat: gelembung rata kanan, sisanya prosa
   asisten tanpa kartu — sama seperti shadcn. */
.catalog-typeset-bubble {
  width: fit-content;
  max-width: 80%;
  margin-inline-start: auto;
  padding-block: 0.625em;
  padding-inline: 1em;
  border-radius: var(--radius-3xl);
  background: var(--catalog-sunken);
  color: var(--catalog-heading-foreground);
}

.catalog-typeset-preview > .catalog-typeset-bubble + * {
  margin-block-start: calc(var(--typeset-flow, 1.25em) * 1.75);
}

.catalog-typeset-diff {
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-lg);
  overflow: hidden;
  font-family: var(--typeset-font-mono, var(--typography-family-mono));
  font-size: 0.875em;
}

.catalog-typeset-diff__line {
  display: block;
  padding-block: var(--space-1);
  padding-inline: var(--space-3);
  white-space: pre;
}

.catalog-typeset-diff__line--add {
  background: color-mix(in oklch, var(--color-success) 14%, transparent);
  color: var(--color-success);
}

.catalog-typeset-diff__line--remove {
  background: color-mix(in oklch, var(--color-destructive) 14%, transparent);
  color: var(--color-destructive);
}

.catalog-typeset-math .katex {
  color: inherit;
}

.catalog-typeset-math--display {
  display: flex;
  justify-content: center;
  padding-block: var(--space-1);
}

.catalog-typeset-math-overflow {
  overflow-x: auto;
  padding-block: var(--space-1);
}

/* --- Create --- */

/* Pratinjau Create = kolom masonry kartu, persis susunan pratinjau shadcn.
   `columns` + `break-inside: avoid`: kartu setinggi isinya, tidak dipaksa
   rata per baris. */
/* Tanpa wadah: tidak ada kotak, border, atau gulung internal — kartu
   langsung di kanvas halaman. Elemen `#create-preview` tetap ada hanya
   sebagai batas cakupan override (warna, radius, font, menu). */
.catalog-create-preview {
  padding-block-end: var(--space-8);
}

.catalog-create-masonry {
  columns: 3 var(--catalog-token-card-min);
  column-gap: var(--space-4);
}

.catalog-create-masonry > .card {
  display: flex;
  break-inside: avoid;
  margin-block-end: var(--space-4);
}

.catalog-create-card__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Kontrol Heading: judul di pratinjau memakai font heading sendiri. */
.catalog-create-preview :is(h2, h3, .card__title, .dialog__title, .alert__title) {
  font-family: var(--create-font-heading, inherit);
}

.catalog-create-eyebrow {
  margin: 0;
  color: var(--color-muted-foreground);
  font-size: var(--typography-size-xs);
  font-weight: var(--typography-weight-medium);
  letter-spacing: var(--catalog-track-label);
  text-transform: uppercase;
}

.catalog-create-display {
  margin: 0;
  color: var(--color-foreground);
  font-size: var(--typography-size-2xl);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--typography-leading-tight);
}

.catalog-create-muted {
  margin: 0;
  color: var(--color-muted-foreground);
  font-size: var(--typography-size-sm);
}

.catalog-create-block {
  display: block;
  font-weight: var(--typography-weight-normal);
}

.catalog-create-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.catalog-create-between {
  justify-content: space-between;
  gap: var(--space-4);
}

.catalog-create-full {
  width: 100%;
}

.catalog-create-command {
  border: var(--border-1) solid var(--color-border);
}

.catalog-create-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-4);
  text-align: center;
}

.catalog-create-empty__icon {
  display: grid;
  place-items: center;
  width: var(--space-10);
  height: var(--space-10);
  border-radius: var(--radius-full);
  background: var(--color-muted);
  color: var(--color-muted-foreground);
}

.catalog-create-empty__icon svg {
  width: var(--space-5);
  height: var(--space-5);
}

.catalog-create-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.catalog-create-stats > div {
  padding: var(--space-3);
  border: var(--border-1) solid var(--color-border);
  border-radius: var(--radius-lg);
}

.catalog-create-figure {
  margin: 0;
  color: var(--color-foreground);
  font-size: var(--typography-size-4xl);
  font-weight: var(--typography-weight-semibold);
  font-variant-numeric: tabular-nums;
  line-height: var(--typography-leading-tight);
}

.catalog-create-dl {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3);
  border-radius: var(--radius-lg);
  background: var(--color-muted);
  font-size: var(--typography-size-sm);
}

.catalog-create-dl > div {
  display: flex;
  justify-content: space-between;
}

.catalog-create-dl dt { color: var(--color-muted-foreground); }
.catalog-create-dl dd { margin: 0; font-variant-numeric: tabular-nums; }

.catalog-create-num {
  text-align: end;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- Kartu tambahan (ritme kartu shadcn /create) --- */

.catalog-create-footer {
  gap: var(--space-2);
  justify-content: flex-end;
}

.catalog-create-title {
  margin: 0 0 var(--space-1);
  color: var(--color-foreground);
  font-size: var(--typography-size-lg);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--typography-leading-tight);
}

.catalog-create-heading {
  margin: 0;
  color: var(--color-foreground);
  font-size: var(--typography-size-xl);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--typography-leading-tight);
}

.catalog-create-swatches {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--space-2);
}

.catalog-create-swatch {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.catalog-create-swatch__tile {
  aspect-ratio: 1;
  border: var(--border-1) solid var(--color-border);
  border-radius: var(--radius-md);
}

.catalog-create-swatch__label {
  overflow: hidden;
  color: var(--color-muted-foreground);
  font-family: var(--typography-family-mono);
  font-size: var(--typography-size-xs);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.catalog-create-link {
  color: var(--color-muted-foreground);
  font-size: var(--typography-size-sm);
  text-decoration: underline;
  text-underline-offset: var(--space-1);
}

.catalog-create-tabs .tabs__list {
  width: 100%;
}

.catalog-create-tabs .tabs__trigger {
  flex: 1;
}

.catalog-create-tabs .tabs__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-block-start: var(--space-4);
}

.catalog-create-kv {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
}

.catalog-create-kv > div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) var(--space-3);
  border: var(--border-1) solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: var(--typography-family-mono);
  font-size: var(--typography-size-xs);
}

.catalog-create-kv dt {
  color: var(--color-foreground);
  font-weight: var(--typography-weight-medium);
}

.catalog-create-kv dd {
  overflow: hidden;
  margin: 0;
  color: var(--color-muted-foreground);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.catalog-create-grid2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

/* Select di form kartu selebar kolomnya, seperti Input (shadcn `w-full`).
   Dua class supaya menang atas select.css yang dimuat lazy sesudahnya. */
.catalog-create-card__content .select {
  display: flex;
}

.catalog-create-card__content .select .select__trigger {
  width: 100%;
}

.catalog-create-checks {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.toggle-group.catalog-create-slots {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2);
  width: 100%;
}

.catalog-create-slots .toggle-group__item {
  width: 100%;
  font-variant-numeric: tabular-nums;
}

.catalog-create-row > .catalog-create-svg {
  width: var(--space-4);
  height: var(--space-4);
}

.catalog-create-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-8) var(--space-4);
  border: var(--border-1) dashed var(--color-border);
  border-radius: var(--radius-lg);
  text-align: center;
}

/* Celah antar potongan pai = warna kartu, bukan latar halaman. */
.catalog-create-preview .chart {
  --chart-surface: var(--color-card);
}

.catalog-create-spark {
  --chart-height: var(--space-24);
}

.catalog-create-calendar {
  align-self: center;
}

.catalog-create-bills {
  display: flex;
  flex-direction: column;
}

.catalog-create-bill {
  padding-block: var(--space-2);
  font-size: var(--typography-size-sm);
}

.catalog-create-bill + .catalog-create-bill {
  border-top: var(--border-1) solid var(--color-border);
}

/* --- Kontrol Style: perlakuan yang bukan angka ---

   Skala spasi dan radius tiap Style dipasang JS lewat token. Yang di sini
   cuma yang tidak bisa diungkapkan sebagai token: Sera (sumber: "square
   corners, underline-only inputs, strong typographic character") dan Rhea
   ("borderless-at-rest fields"). */
.catalog-create-preview[data-create-style="sera"] :is(.input, .textarea) {
  border-width: 0 0 var(--border-1);
  border-radius: 0;
  background-color: transparent;
}

.catalog-create-preview[data-create-style="sera"] .card__title {
  font-size: var(--typography-size-lg);
  font-weight: var(--typography-weight-semibold);
  letter-spacing: var(--typography-tracking-tight);
}

.catalog-create-preview[data-create-style="sera"] .catalog-create-display {
  font-size: var(--typography-size-3xl);
}

.catalog-create-preview[data-create-style="rhea"] :is(.input, .textarea) {
  border-color: transparent;
  background-color: var(--color-muted);
}

.catalog-create-preview[data-create-style="rhea"] :is(.input, .textarea):focus-visible {
  border-color: var(--color-ring);
  background-color: var(--color-background);
}

/* --- Kontrol Menu + Menu Accent ---

   `--pv-bg`/`--pv-fg` ditaruh di WADAH pratinjau (warna popover asli
   diwariskan dari :root di sana), lalu dipakai panel menu di dalamnya.
   Kalau panel menu menulis `--color-popover: mix(var(--color-popover))`
   langsung, itu referensi diri — siklus, nilainya invalid. Panel popover
   tetap mewarisi variabel dari pohon DOM walau naik ke top layer. */
.catalog-create-preview {
  --pv-bg: var(--color-popover);
  --pv-fg: var(--color-popover-foreground);
}

.catalog-create-preview[data-create-menu~="inverted"] {
  --pv-bg: var(--color-foreground);
  --pv-fg: var(--color-background);
}

.catalog-create-preview :is(.dropdown-menu__content, .select__content, .command) {
  --color-popover: var(--pv-bg);
  --color-popover-foreground: var(--pv-fg);
}

.catalog-create-preview[data-create-menu~="inverted"] :is(.dropdown-menu__content, .select__content, .command) {
  --color-accent: color-mix(in oklch, var(--pv-fg) 16%, var(--pv-bg));
  --color-accent-foreground: var(--pv-fg);
  --color-muted-foreground: color-mix(in oklch, var(--pv-fg) 65%, var(--pv-bg));
  --color-border: color-mix(in oklch, var(--pv-fg) 18%, var(--pv-bg));
  --color-foreground: var(--pv-fg);
}

.catalog-create-preview[data-create-menu~="translucent"] :is(.dropdown-menu__content, .select__content, .command) {
  --color-popover: color-mix(in oklch, var(--pv-bg) 72%, transparent);
  backdrop-filter: blur(var(--blur-md));
}

.catalog-create-preview[data-create-menu~="bold"] :is(.dropdown-menu__content, .select__content, .command) {
  --color-accent: var(--color-primary);
  --color-accent-foreground: var(--color-primary-foreground);
}

/* --- Panel Create: tombol dasar ditumpuk + dialog --- */

.catalog-pg__actions--stack {
  grid-auto-flow: row;
}

.catalog-pg__preset {
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-xs);
}

.catalog-create-preset-field {
  padding-block: var(--space-2);
}

.catalog-create-preset-error {
  margin: 0;
  min-height: var(--catalog-lh-xs);
  color: var(--color-destructive);
  font-size: var(--catalog-text-xs);
  line-height: var(--catalog-lh-xs);
}

.catalog-create-dialog-code {
  margin: 0;
  max-height: 40vh;
  overflow: auto;
  padding: var(--space-4);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-lg);
  background: var(--catalog-sunken);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
  line-height: var(--catalog-lh-code);
  white-space: pre-wrap;
  word-break: break-word;
}

/* --- Foundations: halaman token --- */

.catalog-token-category {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  max-width: var(--catalog-token-category-max);
}

.catalog-token-category > .catalog-page__title {
  margin-block-end: 0;
}

.catalog-token-color-header {
  display: flex;
  align-items: center;
}

.catalog-token-color-header .catalog-page__title {
  margin: 0;
}

.catalog-token-color-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  margin-block-start: var(--space-4);
}

.catalog-token-color-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  padding-block-start: var(--space-8);
  border-block-start: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-token-color-section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

/* Isi Palette dirender ulang tiap ganti format. Jarak antargrup sama dengan
   jarak antaranak section. */
.catalog-token-color-section__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.catalog-token-color-section__title {
  margin: 0;
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-xl);
  font-weight: var(--typography-weight-semibold);
  line-height: var(--catalog-lh-lg);
  letter-spacing: var(--catalog-track-heading);
}

.catalog-token-color-section__desc {
  margin: calc(var(--space-4) * -1) 0 0;
  max-width: 62ch;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-md);
  line-height: var(--catalog-lh-sm);
}

.catalog-token-color-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.catalog-token-color-group__name {
  margin: 0;
  color: var(--catalog-ink);
  font-size: var(--catalog-text-sm);
  font-weight: var(--typography-weight-semibold);
  letter-spacing: var(--catalog-track-label);
}

/* Tabel token semantic: satu bingkai, baris dipisah garis rambut. */
.catalog-token-rows {
  display: flex;
  flex-direction: column;
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  overflow: hidden;
}

.catalog-token-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--space-11);
  padding-inline: var(--space-3-5);
  background: var(--color-background);
  transition: background-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-token-row + .catalog-token-row {
  border-block-start: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-token-row:hover {
  background: var(--catalog-hover);
}

.catalog-token-row__swatch {
  width: var(--catalog-swatch-size);
  height: var(--catalog-swatch-size);
  border-radius: var(--radius-md);
  box-shadow: inset 0 0 0 var(--border-1) var(--catalog-border-hairline);
  flex-shrink: 0;
}

.catalog-token-row__name {
  flex: 1;
  min-width: 0;
  color: var(--catalog-ink);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.catalog-token-row__value {
  flex-shrink: 1;
  min-width: 0;
  max-width: 55%;
  color: var(--catalog-muted);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-xs);
  font-variant-numeric: tabular-nums;
  text-align: end;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Ramp palet: 11 step berjajar, gelap-terang berurutan. */
.catalog-ramp {
  display: grid;
  grid-template-columns: repeat(11, minmax(0, 1fr));
  gap: var(--space-1-5);
}

.catalog-ramp__cell {
  display: flex;
  flex-direction: column;
  gap: var(--space-1-5);
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: copy;
}

.catalog-ramp__chip {
  height: var(--catalog-ramp-chip);
  border-radius: var(--radius-lg);
  box-shadow: inset 0 0 0 var(--border-1) var(--catalog-border-hairline);
  transition: translate var(--catalog-dur-fast) var(--catalog-ease),
              box-shadow var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-ramp__cell:hover .catalog-ramp__chip {
  translate: 0 calc(var(--space-0-5) * -1);
  box-shadow: inset 0 0 0 var(--border-1) var(--catalog-border-strong), var(--shadow-2);
}

.catalog-ramp__cell.is-copied .catalog-ramp__chip {
  box-shadow: inset 0 0 0 var(--border-2) var(--catalog-ink);
}

.catalog-ramp__cell:focus-visible {
  outline: none;
}

.catalog-ramp__cell:focus-visible .catalog-ramp__chip {
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

.catalog-ramp__step {
  color: var(--catalog-ink);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-xs);
  font-weight: var(--typography-weight-medium);
  line-height: var(--catalog-lh-xs);
}

.catalog-ramp__value {
  color: var(--catalog-muted);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-xxs);
  line-height: var(--catalog-lh-xxs);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Kartu token (spacing, radius, shadow, motion, z-index) — bisa diedit. */
.catalog-token-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--catalog-token-card-min), 1fr));
  gap: var(--space-3);
}

.catalog-token-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  background: var(--color-background);
  transition: border-color var(--catalog-dur-fast) var(--catalog-ease);
}

.catalog-token-card:hover,
.catalog-token-card:focus-within {
  border-color: var(--catalog-border-strong);
}

.catalog-token-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.catalog-token-name {
  flex: 1;
  min-width: 0;
  color: var(--catalog-muted);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.catalog-token-swatch {
  width: var(--catalog-swatch-size);
  height: var(--catalog-swatch-size);
  border-radius: var(--radius-md);
  box-shadow: inset 0 0 0 var(--border-1) var(--catalog-border-hairline);
  flex-shrink: 0;
}

.catalog-token-value {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

.catalog-token-card input[type="text"],
.catalog-token-card textarea {
  flex: 1;
  min-width: 0;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--catalog-ink);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-base);
  line-height: var(--catalog-lh-base);
}

.catalog-token-card textarea {
  resize: vertical;
  overflow-wrap: anywhere;
}

.catalog-token-card input[type="text"]:focus-visible,
.catalog-token-card textarea:focus-visible {
  outline: none;
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 var(--ring-width) var(--color-ring-focus);
}

.catalog-token-unit {
  flex-shrink: 0;
  color: var(--catalog-muted);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-base);
  line-height: var(--catalog-lh-base);
}

.catalog-token-table {
  display: flex;
  flex-direction: column;
  gap: 0;
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-xl);
  overflow: hidden;
}

/* Tabel token (Spacing, Radius, Z-index — lihat TOKEN_TABLES di
   catalog.js). Satu baris = satu grid dengan kolom tetap yang SAMA di semua
   tabel dan semua halaman: nama | nilai | konversi | preview | alias. Alias di ujung
   supaya preview mulai di titik yang sama di kedua tabel — di Scale sel alias
   kosong dan tidak menyisakan celah di tengah baris. Kolom tetap, bukan
   max-content, supaya nama panjang (`spacing-inset-lg`) tidak menggeser
   kolom lain dan kedua tabel sejajar satu sama lain. */
.catalog-token-table .catalog-token-card {
  display: grid;
  grid-template-columns:
    var(--catalog-token-name-col)
    var(--catalog-token-value-col)
    var(--catalog-token-px-col)
    minmax(0, 1fr)
    var(--catalog-token-alias-col);
  align-items: center;
  column-gap: var(--space-4);
  padding: var(--space-2-5) var(--space-4);
  border: 0;
  border-radius: 0;
}

.catalog-token-table .catalog-token-card + .catalog-token-card {
  border-block-start: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-token-table .catalog-token-card__head {
  min-width: 0;
}

.catalog-token-table .catalog-token-value {
  justify-content: flex-end;
  align-items: baseline;
  gap: var(--space-1);
}

.catalog-token-table .catalog-token-card input[type="text"] {
  flex: none;
  width: 6ch;
  field-sizing: content;
  min-width: 1ch;
  text-align: end;
  font-variant-numeric: tabular-nums;
}

.catalog-token-px,
.catalog-token-alias {
  min-width: 0;
  color: var(--catalog-muted);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-sm);
  font-variant-numeric: tabular-nums;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.catalog-token-px,
.catalog-token-alias {
  text-align: end;
}

/* Preview radius: SATU sudut (kiri atas) di kotak 64×40, bukan kotak utuh
   kecil. Kotak utuh 48×32 memotong radius di setengah tingginya (16px),
   jadi 2xl, 3xl, dan full tampil identik. Satu sudut setinggi 40px
   membedakan semua step sampai 3xl (24px); full jadi seperempat lingkaran
   penuh. `border-start-start-radius` ikut membalik di RTL. */
.catalog-token-table__radius {
  width: var(--space-16);
  height: var(--space-10);
  border-block-start: var(--border-2) solid var(--catalog-ink);
  border-inline-start: var(--border-2) solid var(--catalog-ink);
  background: color-mix(in oklch, var(--catalog-ink) 14%, transparent);
}

.catalog-token-ruler {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex: 1;
  min-width: 0;
}

.catalog-token-ruler__bar {
  height: var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--catalog-ink);
}

.catalog-token-table .catalog-token-ruler__bar {
  height: var(--space-3);
  min-width: var(--border-2);
  border-inline-end: var(--border-2) solid var(--catalog-ink);
  border-radius: 0;
  background: color-mix(in oklch, var(--catalog-ink) 14%, transparent);
}

/* Tukar (Shadow, Typography Family): baris = nama | preview | nilai |
   alias. Preview menempati kolom nilai + konversi (kolom 2–3), nilai yang
   panjang pindah ke kolom 1fr supaya bisa membungkus baris. Kolom nama dan
   alias tetap sejajar dengan tabel lain. */
.catalog-token-table--swap .catalog-token-card > * {
  grid-row: 1;
}

.catalog-token-table--swap .catalog-token-card > :nth-child(4) {
  grid-column: 2 / span 2;
}

.catalog-token-table--swap .catalog-token-value {
  grid-column: 4;
  justify-content: flex-start;
}

.catalog-token-table--swap .catalog-token-px,
.catalog-token-table--text .catalog-token-px {
  display: none;
}

.catalog-token-table--swap .catalog-token-card textarea,
.catalog-token-table--text .catalog-token-card textarea {
  resize: none;
  font-size: var(--catalog-text-sm);
}

/* Typography: nama token panjang (`typography-tracking-tighter`), jadi
   kolom nama halaman ini lebih lebar dari tabel lain. Kolom alias selalu
   kosong di sini (grup core tanpa alias; susunan Text punya baris sendiri),
   jadi lebarnya dipakai preview. */
.catalog-token-table--typography {
  --catalog-token-name-col: 14.5rem;
  --catalog-token-alias-col: 0px;
}

.catalog-token-type-sample {
  min-width: 0;
  margin: 0;
  color: var(--catalog-sample-foreground);
  font-family: var(--typography-family-sans);
  font-size: var(--catalog-text-lg);
  line-height: var(--typography-leading-snug);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Leading: dua baris teks kecil supaya jarak antarbarisnya terbaca. */
.catalog-token-type-sample--leading {
  max-inline-size: var(--catalog-type-leading-max);
  font-size: var(--catalog-text-sm);
  white-space: normal;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

/* Text (gaya jadi): tiga baris dalam satu entri — sampel dengan gaya itu,
   nilai shorthand yang bisa diedit, lalu susunan token-nya. */
.catalog-token-table--text .catalog-token-card {
  align-items: start;
  row-gap: var(--space-1);
  padding-block: var(--space-4);
}

.catalog-token-table--text .catalog-token-card__head {
  grid-row: 1 / span 3;
  padding-block-start: var(--space-1);
}

.catalog-token-table--text .catalog-token-type-sample {
  grid-column: 2 / -1;
  grid-row: 1;
  font-size: initial;
  line-height: initial;
}

.catalog-token-table--text .catalog-token-value {
  grid-column: 2 / -1;
  grid-row: 2;
  justify-content: flex-start;
}

.catalog-token-table--text .catalog-token-alias {
  grid-column: 2 / -1;
  grid-row: 3;
  text-align: start;
}

.catalog-token-table-part--flat {
  gap: var(--space-2);
}

/* Panggung dengan warna core (bukan token tema). Bayangan token hitam
   5–10% hilang di permukaan gelap asli (L≈0.13), jadi panggung tidak
   ikut --color-background. Light: slate-100/50. Dark: abu menengah
   slate-700/600 — cukup terang untuk menampakkan bayangan, tanpa blok
   putih yang silau di halaman gelap. */
.catalog-token-shadow-stage {
  display: grid;
  place-items: center;
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--color-slate-100);
}

.catalog-token-shadow-stage__tile {
  width: var(--space-16);
  height: var(--space-10);
  border-radius: var(--radius-md);
  background: var(--color-slate-50);
}

/* Pasangan gelap — ditulis dua kali (`.dark` + blok media) seperti
   token shell di atas, supaya pilihan `.light` tetap menang. */
.dark .catalog-token-shadow-stage {
  background: var(--color-slate-700);
}

.dark .catalog-token-shadow-stage__tile {
  background: var(--color-slate-600);
}

@media (prefers-color-scheme: dark) {
  :root:not(.light) .catalog-token-shadow-stage {
    background: var(--color-slate-700);
  }

  :root:not(.light) .catalog-token-shadow-stage__tile {
    background: var(--color-slate-600);
  }
}

/* Halaman dengan beberapa skala (Motion: Duration + Easing). Judul part
   h2, lalu Scale/Semantic sebagai subjudul kecil. */
.catalog-token-table-part {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.catalog-token-table-part__sub {
  margin: 0;
  color: var(--catalog-muted);
  font-size: var(--catalog-text-sm);
  font-weight: var(--typography-weight-medium);
}

/* Duration: hover/fokus baris mengisi bar dari nol, selama durasi token
   itu sendiri (`--catalog-token-play-dur`, diisi catalog.js), linear. */
@keyframes catalog-token-duration-fill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

.catalog-token-table--duration .catalog-token-ruler__bar {
  transform-origin: left center;
}

[dir="rtl"] .catalog-token-table--duration .catalog-token-ruler__bar {
  transform-origin: right center;
}

.catalog-token-table--duration .catalog-token-card:is(:hover, :focus-within) .catalog-token-ruler__bar {
  animation: catalog-token-duration-fill var(--catalog-token-play-dur) linear both;
}

/* Easing: nilai `0.4, 0, 0.2, 1` lebih lebar dari kolom nilai, jadi
   memakai kolom konversi juga (kolom itu memang kosong untuk easing). */
.catalog-token-table--easing .catalog-token-value {
  grid-column: 2 / span 2;
}

.catalog-token-table--easing .catalog-token-px {
  display: none;
}

/* Lebar tetap untuk `0.4, 0, 0.2, 1` (14 karakter) — `field-sizing` belum
   didukung semua browser, jadi 6ch bawaan tabel memotongnya. */
.catalog-token-table--easing .catalog-token-card input[type="text"] {
  width: 15ch;
}

.catalog-token-easing {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
}

.catalog-token-easing__curve {
  flex-shrink: 0;
  width: var(--space-12);
  height: var(--space-8);
  overflow: visible;
  fill: none;
  stroke: var(--catalog-ink);
  stroke-width: var(--border-2);
  stroke-linecap: round;
}

.catalog-token-easing__diagonal {
  stroke: var(--catalog-border-strong);
  stroke-width: var(--border-1);
  stroke-dasharray: 2 3;
}

.catalog-token-easing__track {
  position: relative;
  flex: 1;
  max-inline-size: var(--space-24);
  height: var(--space-2);
  border-block-end: var(--border-1) solid var(--catalog-border-hairline);
}

.catalog-token-easing__dot {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  width: var(--space-2);
  height: var(--space-2);
  border-radius: var(--radius-full);
  background: var(--catalog-ink);
}

@keyframes catalog-token-easing-slide {
  from { inset-inline-start: 0; }
  to { inset-inline-start: calc(100% - var(--space-2)); }
}

/* Durasi tetap 1 detik untuk semua baris supaya yang beda cuma kurvanya. */
.catalog-token-table--easing .catalog-token-card:is(:hover, :focus-within) .catalog-token-easing__dot {
  animation-name: catalog-token-easing-slide;
  animation-duration: var(--duration-1000);
  animation-fill-mode: both;
}

@media (prefers-reduced-motion: reduce) {
  .catalog-token-table--duration .catalog-token-card:is(:hover, :focus-within) .catalog-token-ruler__bar,
  .catalog-token-table--easing .catalog-token-card:is(:hover, :focus-within) .catalog-token-easing__dot {
    animation: none;
  }
}

/* Judul grup di halaman token (Typography, Motion, Scale/Semantic). */
.catalog-type-token-group__name {
  margin: 0;
  color: var(--catalog-heading-foreground);
  font-size: var(--catalog-text-lg);
  font-weight: var(--typography-weight-semibold);
  letter-spacing: var(--catalog-track-tight);
}

/* Tooltip instan untuk nilai token yang terpotong. */
.catalog-tooltip {
  position: fixed;
  z-index: calc(var(--z-toast) + 1);
  max-width: var(--catalog-tooltip-max);
  padding: var(--space-1) var(--space-2);
  border: var(--border-1) solid var(--catalog-border-hairline);
  border-radius: var(--radius-md);
  background: var(--color-popover);
  color: var(--color-popover-foreground);
  box-shadow: var(--shadow-3);
  font-family: var(--typography-family-mono);
  font-size: var(--catalog-text-xs);
  pointer-events: none;
  white-space: pre-wrap;
  word-break: break-all;
}

/* --- Responsif ---

   Breakpoint dari tokens/core/breakpoint.json — @media tidak bisa
   mengonsumsi var(), jadi nilainya ditulis literal. */

@media (min-width: 1280px) {
  :root {
    --catalog-panel-padding: var(--space-10);
  }

  .catalog-demo__preview {
    padding-inline: var(--space-8);
  }
}

@media (max-width: 1023px) {
  .catalog-topbar {
    gap: var(--space-4);
  }

  .catalog-brand {
    width: auto;
  }

  /* Search jadi tombol ikon; teks tetap di `aria-label` tombolnya. */
  /* Lebar = tinggi tombol DS, jadi kotaknya bujur sangkar seperti btn--icon. */
  .catalog-search__input {
    width: auto;
    aspect-ratio: 1;
    padding: 0;
    justify-content: center;
  }

  .catalog-search__placeholder,
  .catalog-search .catalog-kbd {
    display: none;
  }

  .catalog-tabbar {
    mask-image: linear-gradient(to right, var(--color-foreground) calc(100% - var(--space-6)), transparent);
  }
}

@media (max-width: 767px) {
  :root {
    --catalog-panel-padding: var(--space-4);
  }

  /* Spacing: px & alias disembunyikan, ruler turun ke baris kedua. */
  .catalog-token-table .catalog-token-card {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: var(--space-2);
  }

  .catalog-token-table .catalog-token-px,
  .catalog-token-table .catalog-token-alias {
    display: none;
  }

  .catalog-token-table .catalog-token-ruler,
  .catalog-token-table .catalog-token-easing {
    grid-column: 1 / -1;
  }

  .catalog-token-table--easing .catalog-token-value {
    grid-column: auto;
  }

  .catalog-token-table--swap .catalog-token-card > *,
  .catalog-token-table--text .catalog-token-card > * {
    grid-row: auto;
  }

  .catalog-token-table--swap .catalog-token-card > :nth-child(4),
  .catalog-token-table--swap .catalog-token-value,
  .catalog-token-table--text .catalog-token-card > *,
  .catalog-token-table .catalog-token-type-sample {
    grid-column: 1 / -1;
  }

  /* Urutan sama dengan desktop: preview dulu, baru nilai. */
  .catalog-token-table--swap .catalog-token-value {
    order: 1;
  }

  /* Text: susunan token tetap tampil (satu-satunya alias yang bukan
     sekadar "sama dengan"). */
  .catalog-token-table.catalog-token-table--text .catalog-token-alias {
    display: block;
    order: 2;
    white-space: normal;
  }

  .catalog-token-table--text .catalog-token-value {
    order: 1;
  }

  .catalog-topbar {
    gap: var(--space-2);
    padding-inline: var(--space-2) var(--space-3);
  }

  .catalog-nav-toggle {
    display: inline-flex;
  }

  .catalog-tabbar {
    display: none;
  }

  .catalog-brand__suffix {
    display: none;
  }

  /* Sidebar jadi laci. `position: fixed` + `translate` di SIDEBAR — saudara
     `#panel`, bukan leluhurnya — jadi tidak ada titik acuan komponen yang
     berpindah. `visibility` ikut ditutup supaya link yang tidak terlihat
     keluar dari urutan Tab; transisinya ditunda sampai laci selesai
     bergeser. */
  .catalog-sidebar {
    position: fixed;
    inset-block: var(--catalog-topbar-height) 0;
    inset-inline-start: 0;
    z-index: calc(var(--z-sticky) + 2);
    width: min(var(--catalog-drawer-width), 86vw);
    height: auto;
    box-shadow: var(--shadow-5);
    translate: -100% 0;
    visibility: hidden;
    transition: translate var(--catalog-dur) var(--catalog-ease),
                visibility 0s linear var(--catalog-dur);
  }

  [dir="rtl"] .catalog-sidebar {
    translate: 100% 0;
  }

  .is-nav-open .catalog-sidebar {
    translate: 0 0;
    visibility: visible;
    transition: translate var(--catalog-dur) var(--catalog-ease),
                visibility 0s linear 0s;
  }

  [data-section="about"] .catalog-sidebar {
    display: flex;
  }

  .catalog-scrim {
    position: fixed;
    inset: var(--catalog-topbar-height) 0 0;
    z-index: calc(var(--z-sticky) + 1);
    background: var(--catalog-scrim);
    animation: catalog-enter var(--catalog-dur) var(--catalog-ease);
  }

  .catalog-mobile-sections {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-0-5);
    padding-block-end: var(--space-4);
    margin-block-end: var(--space-3);
    border-block-end: var(--border-1) solid var(--catalog-border-hairline);
  }

  .catalog-mobile-sections__link {
    display: flex;
    align-items: center;
    min-height: var(--catalog-icon-btn);
    padding-inline: var(--space-2);
    border-radius: var(--radius-md);
    color: var(--catalog-muted);
    font-size: var(--catalog-text-md);
    font-weight: var(--typography-weight-medium);
    text-decoration: none;
  }

  .catalog-mobile-sections__link:hover {
    color: var(--catalog-ink);
    background: var(--catalog-hover);
  }

  .catalog-mobile-sections__link.is-active {
    color: var(--catalog-ink);
    background: var(--catalog-active);
  }

  .catalog-mobile-sections__link:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 var(--border-2) var(--color-ring);
  }

  .catalog-panel {
    padding-block-start: var(--space-6);
  }

  /* Judul di atas, kontrol di bawah — tinggi tetap BILANGAN BULAT. */
  .catalog-canvas-bar {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    gap: var(--space-3);
    height: var(--catalog-canvas-bar-height-mobile);
  }

  .catalog-canvas-heading {
    max-width: 100%;
    gap: var(--space-1);
  }

  .catalog-canvas-title,
  .catalog-page__title {
    font-size: var(--catalog-text-display-mobile);
    line-height: var(--catalog-lh-display-mobile);
  }

  .catalog-doc-meta__link span:not(.catalog-sr) {
    display: none;
  }

  .catalog-install {
    flex: 1;
  }

  .catalog-demo__preview {
    padding-block: var(--space-6);
  }

  .catalog-index__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-1) var(--space-3);
  }

  .catalog-ramp {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    row-gap: var(--space-3);
  }

  .catalog-changelog__entry {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-1);
  }

  .catalog-pager {
    grid-template-columns: minmax(0, 1fr);
  }

  .catalog-pager__link--next {
    grid-column: auto;
  }
}

