/* Sistem token hasil ukur coterie.com.
   Dipindahkan dari clvn-desk (Payload + Next) ke situs statis ini.

   Tiga perubahan dari sumbernya, semuanya tercatat di tempatnya
   masing masing: fallback font ditaruh DI DALAM var(), --n di .u-span
   diberi fallback, dan contoh JSX di bagian 8 jadi HTML.

   Angka angkanya TIDAK berubah. Root font-size wajib tetap
   10.0013px di 375, 7.10656px di 1024, dan 8.8832px di 1280.
   Ketiganya dikunci tests/e2e/tokens.e2e.spec.ts.

   Muat berkas ini TERAKHIR. Rule html { font-size } di dalamnya harus
   menang atas reset apa pun. */

/* ============================================================
   Design tokens, hasil ukur coterie.com 23 Agustus 2026.
   Sumber angka: Portfolio Website/15_coterie-teardown.md
   Prefix `t-` dan `u-` dipakai supaya tidak bentrok dengan
   utility Tailwind (h-28 di Tailwind itu height, bukan heading).
   ============================================================ */

/* --- 1. Root font engine -------------------------------------
   Ini inti sistemnya. Semua ukuran lain memakai rem, jadi
   seluruh layout menskala dari tiga rule ini.
   Terverifikasi: 375px -> 10.00px, 1280px -> 8.88px, 1680px -> 10.69px.
   Cap 10.69px tercapai sekitar lebar 1540px.
   --sbw adalah lebar scrollbar. ponytail: dibiarkan 0px.
   Diukur, selisihnya cuma sekitar 1 persen di root font-size dan
   tidak memicu scroll horizontal, jadi tidak perlu JS setter.
   Kalau nanti terbukti mengganggu, set dari layout dengan
   document.documentElement.style.setProperty('--sbw', ...). */
html {
  font-size: min(2.667vw - var(--sbw) * 0.027, 11.07px);
}
@media (min-width: 768px) {
  html {
    font-size: calc(1.302vw - var(--sbw) * 0.013);
  }
}
@media (min-width: 1024px) {
  html {
    font-size: min(0.694vw - var(--sbw) * 0.007, 10.69px);
  }
}

:root {
  --sbw: 0px;

  /* --- 2. Grid. 12 kolom di mobile, 24 di desktop. Semua vw. --- */
  --max-width: 1680px;
  --margin: 4.267vw;
  --gutter: calc(2.592vw - var(--sbw) * 0.0259);
  --col: calc(5.247vw - var(--sbw) * 0.0525);
  --grid-width: calc(91.467vw - var(--sbw));

  --header-height-fixed: calc(6rem - 1px);
  --banner-height: 3.2rem;
  --header-height: calc(6rem + 3.2rem - 1px);

  /* --- 3. Warna. Obsidian chrome ------------------------------
     Rebranding 1 September 2026. Palet sumber: Onyx #0A0A0A,
     Blue Slate #536878, Alabaster Grey #E5E4E2.

     Angka kontras di bawah DIHITUNG terhadap WCAG 2.1, bukan dikira
     kira. Yang paling terasa berubah: tombol primary turun dari
     11,4:1 jadi 6,3:1. Masih lolos AA, tapi memang tidak lagi
     berteriak seperti biru elektrik Coterie. Itu arah paletnya,
     bukan kelalaian.

     NAMA LAMA DIPERTAHANKAN SEBAGAI ALIAS. Dua puluh lima berkas CSS
     memakai --blue dan kawan kawannya. Menyisir semuanya cuma untuk
     berganti nama tidak menghasilkan satu piksel pun perubahan, jadi
     ramp barunya diberi nama jujur lalu nama lama menunjuk ke sana. */

  --onyx: #0a0a0a;
  --slate: #536878;       /* 6,3:1 dengan teks putih di atasnya */
  --slate-deep: #3d4c58;  /* 8,9:1 di latar putih, dipakai untuk teks */
  --slate-dark: #2c3742;  /* 12,1:1, state active */
  --slate-tint: #dde3e8;  /* 4,9:1 dengan --slate di atasnya */
  --slate-wash: #edf0f3;
  --alabaster: #e5e4e2;

  --black: var(--onyx);
  --black7: #4f565c;      /* 7,5:1 di latar putih */
  --black-muted: #b4bac0;
  --white: #ffffff;

  --blue: var(--slate);
  --blue600: var(--slate-deep);
  --blue800: var(--slate-dark);
  --blue-cgi: var(--slate-tint);
  --blue-light: var(--slate-wash);

  --stone: var(--alabaster);
  --grey-border: #dfe2e5;
  --grey-disabled: #e6e9eb;
  --grey-oos: #f3f5f6;
  --error: #e43030;       /* TIDAK diubah. Merah error itu fungsi, bukan brand */

  --hairline: rgba(10, 10, 10, 0.1);
  --overlay: rgba(10, 10, 10, 0.2);

  /* --- 3a. Permukaan kaca -------------------------------------
     Gradien lembut plus butiran, untuk hero dan section gelap.

     Nol dependency dipertahankan: gradiennya CSS biasa, butirannya
     feTurbulence SVG yang ditanam sebagai data URI. Tidak ada berkas
     aset baru dan tidak ada permintaan jaringan tambahan.

     Titik terangnya SENGAJA di sudut. Teks putih di atas permukaan
     ini harus mendarat di wilayah gelapnya, bukan di titik terang. */
  --glass-pale: #c9d2d6;
  --glass-mid: #5a6b72;
  --glass-deep: var(--onyx);
  --glass-angle: 145deg;
  --grain-opacity: 0.06;
  --grain-tile: 180px;

  /* DUA bentuk permukaan, dan bedanya soal kontras, bukan selera.

     --glass-surface punya titik terang pucat di sudut. Bagus untuk
     bidang besar, TAPI teks putih yang mendarat di titik itu jatuh ke
     kontras yang tidak lolos. Pakai hanya kalau teksnya bisa ditaruh
     di wilayah gelapnya.

     --glass-surface-flat membuang titik terangnya. Itu yang aman untuk
     chrome, karena teksnya tersebar di seluruh bidang dan tidak bisa
     dihindarkan dari bagian terang. Titik paling terangnya #5a6b72,
     dan teks putih di atasnya 5,5:1, lolos AA. */
  --glass-surface:
    radial-gradient(120% 85% at 16% 6%, var(--glass-pale) 0%, transparent 58%),
    linear-gradient(var(--glass-angle), var(--glass-mid) 0%, var(--glass-deep) 62%);
  --glass-surface-flat:
    linear-gradient(var(--glass-angle), var(--glass-mid) 0%, var(--glass-deep) 100%);

  /* --- 4. Radius ---------------------------------------------- */
  --radius-pill: 6rem;
  --radius-card: 0.8rem;
  --radius-sheet: 1.6rem;
  --radius-chip: 0.2rem;

  /* --- 5. Easing, diukur dari cart drawer --------------------- */
  --ease-in-overshoot: cubic-bezier(0.16, 1.08, 0.38, 0.98);
  --ease-out-quart: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-media: cubic-bezier(0.26, 1.04, 0.54, 1);
  --ease-swap: cubic-bezier(0.48, 0.04, 0.52, 0.96);

  /* --- 6. Font. PLACEHOLDER.
     Ganti satu baris ini saat font final dipilih. Suisse milik
     Coterie berlisensi komersial dan tidak dipakai. */
  --font-display: var(--font-geist-sans, ui-sans-serif), system-ui, sans-serif;
  --font-mono-ui: var(--font-geist-mono, ui-monospace), monospace;
}

/* Tablet 768 sampai 1023. Terverifikasi di 768, 900, 1023.
   Grid tetap 12 kolom seperti mobile, TAPI kolomnya lebih lebar
   daripada desktop (49.47px di 900 versus 33.95px di 1280).
   Tidak ada satu pun switch layout di 768. Rentang tablet mewarisi
   layout mobile utuh, lalu diperbesar oleh root font-size yang naik
   linier tanpa plafon sampai 1023. */
@media (min-width: 768px) and (max-width: 1023px) {
  :root {
    --margin: 2.083vw;
    --gutter: calc(2.715vw - var(--sbw) * 0.0272);
    --col: calc(5.497vw - var(--sbw) * 0.055);
    --grid-width: calc(95.833vw - var(--sbw));
  }
}

@media (min-width: 1024px) {
  :root {
    --margin: 2.778vw;
    --gutter: calc(1.338vw - var(--sbw) * 0.0134);
    --col: calc(2.653vw - var(--sbw) * 0.0265);
    --grid-width: calc(94.444vw - var(--sbw));
    --header-height-fixed: calc(6.7rem - 1px);
    --header-height: calc(6.7rem + 3.2rem - 1px);
  }
}

/* --- 7. Skala tipografi --------------------------------------
   Polanya: mobile pakai max() sebagai LANTAI supaya teks tidak
   pernah mengecil melewati batas baca. Desktop pakai min()
   sebagai PLAFON supaya tidak membesar tanpa batas.
   Efek sampingnya nyata: beberapa teks justru lebih kecil di
   desktop daripada di mobile. Itu memang begitu, bukan salah ukur. */
.t-h1 { font-size: max(6.8rem, 61.2px); line-height: 1; letter-spacing: -0.02em; }
.t-44 { font-size: max(4.4rem, 39.6px); line-height: 1.1; letter-spacing: -0.02em; }
.t-42 { font-size: max(4.2rem, 37.8px); line-height: 1.05; letter-spacing: -0.02em; }
.t-38 { font-size: max(3.8rem, 34.2px); line-height: 1.1; letter-spacing: -0.02em; }
.t-28 { font-size: max(2.8rem, 25.2px); line-height: 1.1; letter-spacing: -0.02em; }
.t-22 { font-size: max(2.2rem, 19.8px); line-height: 1.1; letter-spacing: -0.01em; }
.t-18 { font-size: max(1.8rem, 16.2px); line-height: 1.4; }
.t-16 { font-size: max(1.6rem, 14.4px); line-height: 1.4; }
.t-14 { font-size: max(1.4rem, 12.6px); line-height: 1.4; }
.t-12 { font-size: max(1.2rem, 11px); line-height: 1.4; }
.t-10 { font-size: max(1rem, 11px); line-height: 1.4; }
/* clamp di bawah cacat: lantai 11px lebih besar dari plafon 10px, jadi
   suku 1rem mati total dan hasilnya SELALU 11px. Sengaja TIDAK diperbaiki.
   11px itu justru angka yang terukur di sumber, jadi membetulkan rumusnya
   jadi clamp(10px, 1rem, 11px) malah menggeser hasilnya ke 10px dan
   merusak kesetiaan. Biarkan, dan jangan "rapikan" tanpa mengukur ulang. */
.t-mono { font-family: var(--font-mono-ui); font-size: clamp(11px, 1rem, 10px); letter-spacing: -0.06em; }

/* Varian desktop. Dipakai berpasangan seperti Coterie:
   class="t-28 lg-t-42" berarti 28 di mobile, 42 di desktop.
   Tanda hubung, bukan titik dua, supaya tidak perlu escaping
   dan tidak bertabrakan dengan variant Tailwind. */
@media (min-width: 1024px) {
  .lg-t-112 { font-size: min(11.2rem, 112px); line-height: 1; letter-spacing: -0.02em; }
  .lg-t-80  { font-size: min(8rem, 80px);     line-height: 1; letter-spacing: -0.02em; }
  .lg-t-56  { font-size: min(5.6rem, 56px);   line-height: 1.1; letter-spacing: -0.02em; }
  /* 3.6rem terukur di judul kartu bundle (31.98px @1280). */
  .lg-t-36  { font-size: min(3.6rem, 36px);   line-height: 1.1; letter-spacing: -0.01em; }
  .lg-t-42  { font-size: min(4.2rem, 42px);   line-height: 1.1; letter-spacing: -0.02em; }
  /* p-17 letter-spacing normal, beda dari p-14 dan p-12 yang 0.02em. Terukur. */
  /* 21.6px terukur di eyebrow autoRenewBenefits dan judul submenu.
     Pakai clamp dengan lantai, bukan min, karena 2.4rem @1280 = 21.32
     yang di bawah lantainya. */
  .lg-t-24  { font-size: clamp(21.6px, 2.4rem, 24px); line-height: 1.1; letter-spacing: -0.01em; }
  .lg-t-17  { font-size: clamp(15.3px, 1.7rem, 17px); line-height: 1.4; letter-spacing: normal; }
  .lg-t-14  { font-size: clamp(12.6px, 1.4rem, 14px); line-height: 1.4; letter-spacing: 0.02em; }
  .lg-t-12  { font-size: clamp(11px, 1.2rem, 12px);   line-height: 1.4; letter-spacing: 0.02em; }
}

/* Heading memakai pre-wrap supaya line break diatur dari CMS,
   bukan dari CSS. Coterie melakukan hal yang sama. */
.t-h1, .t-44, .t-42, .t-38, .t-28, .t-22 { white-space: pre-wrap; font-weight: 400; }

/* --- 8. Grid helper ------------------------------------------
   Lebar ditulis sebagai kelipatan kolom, persis seperti Coterie:
   <div class="u-span" style="--n:8"></div> menghasilkan
   calc(8*col + 7*gutter).

   --n diberi fallback 1. Tanpa itu, lupa menyetel --n bikin width
   invalid dan elemennya ambruk ke auto tanpa pesan error apa pun. */
.u-container { width: var(--grid-width); margin-inline: auto; max-width: var(--max-width); }
.u-span { width: calc(var(--n, 1) * var(--col) + (var(--n, 1) - 1) * var(--gutter)); }

/* --- 8a. Placeholder media ------------------------------------
   Blok abu polos pengganti seluruh aset. Tanpa teks di dalamnya.
   Sengaja terlihat sebagai placeholder, bukan sebagai pilihan desain.

   Diangkat ke tokens.css karena dipakai bersama oleh mega nav, section
   homepage, dan PDP. Di sumbernya dia tinggal di sections.css dan
   bernama .ph, nama satu suku kata yang tidak lolos konvensi u-* situs
   ini. */
.u-placeholder {
  width: 100%;
  height: 100%;
  min-height: 8rem;
  background: #d9d9d9;
}

/* Aset asli yang menggantikan .u-placeholder. Mengisi kotak yang sama
   persis, dan object-fit cover menjaga gambar tidak gepeng saat rasio
   slot berbeda dari rasio berkasnya. Tiap img membawa width dan height
   asli di markup, jadi browser sudah tahu rasionya sebelum berkasnya
   turun dan tidak ada layout shift saat gambar mendarat. */
.u-media {
  display: block;
  width: 100%;
  height: 100%;
  /* min-height ikut dibawa dari .u-placeholder dan BUKAN hiasan. Banyak
     slot induknya bertinggi auto, sehingga height 100 persen tidak punya
     acuan dan kotaknya runtuh ke nol: gambarnya termuat tapi tidak
     terlihat sama sekali. */
  min-height: 8rem;
  object-fit: cover;
}

/* Untuk slot yang tingginya SUDAH pasti, misalnya thumbnail 4rem. Lantai
   8rem di atas itu untuk slot yang induknya bertinggi auto; di kotak
   4rem ia justru membuat gambar dua kali lipat lalu dipotong overflow,
   sehingga yang terlihat potongan acak separuh foto, bukan thumbnail. */
.u-media--fixed {
  min-height: 0;
}

/* --- 8c. Permukaan kaca --------------------------------------
   Dipakai bersama oleh hero, section gelap, dan latar editorial,
   jadi dia tinggal di sini mengikuti alasan yang sama seperti
   .u-placeholder di 8a: milik banyak section, bukan milik satu.

   BUKAN pengganti .u-placeholder. Placeholder sengaja terlihat
   sebagai placeholder dan itu tetap berlaku. Permukaan ini pilihan
   desain yang disengaja, jadi dipasang hanya di tempat yang memang
   dirancang gelap.

   isolation: isolate menahan mix-blend-mode butirannya supaya
   membaur hanya di dalam kotak ini. Tanpa itu, butirannya ikut
   menimpa section tetangga begitu keduanya kebetulan berbagi
   stacking context yang sama. */
.u-glass {
  position: relative;
  isolation: isolate;
  color: var(--white);
  background: var(--glass-surface);
}

/* Butiran menimpa SELURUH kotak, termasuk teks di dalamnya, dan itu
   memang tampilan yang dituju: di referensinya grain-nya satu lapis
   di atas segalanya, bukan cuma di latar.

   pointer-events none supaya lapisan ini tidak pernah mencegat klik
   milik tombol atau tautan di bawahnya. */
.u-glass::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27180%27 height=%27180%27%3E%3Cfilter id=%27g%27%3E%3CfeTurbulence type=%27fractalNoise%27 baseFrequency=%270.8%27 numOctaves=%273%27 stitchTiles=%27stitch%27/%3E%3C/filter%3E%3Crect width=%27180%27 height=%27180%27 filter=%27url(%23g)%27/%3E%3C/svg%3E");
  background-size: var(--grain-tile) var(--grain-tile);
}

/* --- 8b. Aksesibilitas ---------------------------------------
   Menyembunyikan dari mata tapi tetap terbaca pembaca layar. Dipakai
   drawer untuk prefiks yang cuma berguna kalau tidak melihat layar,
   dan oleh tombol tutup mega nav yang hanya ada untuk keyboard. */
.u-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- 9. Tombol ----------------------------------------------- */
.u-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-weight: 600;
  line-height: 0.9;
  padding: 1.4rem 3.2rem;
  font-size: clamp(11.7px, 1.3rem, 13px);
  cursor: pointer;
  transition:
    opacity 0.6s var(--ease-media),
    color 0.6s var(--ease-media),
    background-color 0.6s var(--ease-media),
    border-color 0.6s var(--ease-media);
}
/* Tombol ganti rumus di 1024px, bukan satu nilai tetap.
   Terukur di PDP: 13px di mobile 375, 10.8px di desktop 1280.
   Mobile pakai rumus medium, desktop pakai rumus large. Terdengar
   terbalik karena "large" justru menghasilkan font lebih kecil,
   tapi itu memang penamaan mereka. */
@media (min-width: 1024px) {
  .u-btn { font-size: clamp(10.8px, 1.2rem, 12px); }
}
.u-btn-lg { padding: 1.6rem 3.2rem; }

.u-btn-primary { background: var(--blue); color: var(--white); }
.u-btn-primary:active { background: var(--blue800); transition-duration: 0.2s; }

.u-btn-secondary { background: var(--white); color: var(--blue600); border-color: var(--grey-border); }
.u-btn-secondary:active { color: var(--blue800); border-color: var(--blue800); transition-duration: 0.2s; }

.u-btn-selected { background: var(--blue-cgi); color: var(--blue); border-color: var(--hairline); }

.u-btn:disabled,
.u-btn[aria-disabled='true'] {
  background: var(--grey-disabled);
  color: var(--black7);
  border-color: var(--grey-disabled);
  pointer-events: none;
}
.u-btn:focus-visible { outline: 1px solid var(--blue); outline-offset: 2px; }

/* --- 10. Warna teks dan latar -------------------------------- */
.u-black  { color: var(--black); }
.u-black7 { color: var(--black7); }
.u-blue   { color: var(--blue); }
.bg-stone { background-color: var(--stone); }
.bg-cgi   { background-color: var(--blue-cgi); }
