:root {
  /* Palet: Burnt Orange, Lust, Copper, Blue Lagoon, Black Pearl */
  --burnt-orange: #FE7E3C;
  --lust: #E4201B;
  --copper: #61413C;
  --blue-lagoon: #0E6873;
  --black-pearl: #1A2C30;
  /* Semua permukaan (kartu/panel/tombol) pakai warna SOLID, opacity 100%.
     Tidak ada glassmorphism / backdrop-filter / background transparan. */
  --surface: #1a2c30;
  --surface-2: #233c42;
  --surface-3: #2d4b53;
  --surface-border: #34575e;
}

html {
  background-color: #0f1b1e;
  scroll-behavior: smooth;
  overflow-x: hidden;
}

/* Fix: teks gradient (bg-clip-text) suka kepotong di bagian bawah huruf
   yang punya "ekor" -- j, g, y, p -- karena line-height Tailwind default-nya
   terlalu mepet buat clip masking. Dikasih line-height lebih longgar +
   sedikit padding-bottom biar ekornya kebaca full, tanpa ganggu posisi
   teks di layout (padding-nya dikompensasi margin negatif). */
.bg-clip-text {
  line-height: 1.25;
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
}

body {
  /* Background halaman: warna solid, tanpa gradient & tanpa animasi. */
  background-color: #0f1b1e;
  color: #e8f1f2;
  font-family: "Plus Jakarta Sans", sans-serif;
  overflow: hidden; /* was overflow-x: hidden saja -> overflow-y kebawa keitung "auto" otomatis sama browser, jadi body punya scrollbar vertikal sendiri terpisah dari html = scrollbar dobel + scroll kadang macet. html tetep yang megang scroll halaman seperti biasa. */
  width: 100%;
}

/* ------------------------------------------------------------------
   Lazy image fade-in (semua galeri: chroma grid, photo-editing,
   apparel, folder-modal thumb strip).
   Kenapa: browser baru mulai request gambar loading="lazy" pas dia
   deket viewport, jadi kalau langsung nongol 100% opaque begitu
   selesai decode, kartu/grid keliatan "kedip"/nyentak satu-satu pas
   discroll -- padahal request-nya udah bener (lazy + async decode +
   webp, gak ada yang diubah). Fade 300ms ini murni bikin transisi-nya
   halus (perceived speed), img.is-loaded ditoggle dari script.js pas
   event 'load' (atau langsung kalau ternyata udah tercache duluan).
   Kalau gambarnya gagal load (404/error), tetep di-mark is-loaded biar
   gak nyangkut invisible selama-lamanya -- listener error di JS yang
   nyembunyiin box-nya udah nanganin itu. */
img[loading="lazy"] {
  opacity: 0;
  transition: opacity 0.35s ease;
}
img[loading="lazy"].is-loaded {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  img[loading="lazy"] {
    transition: none;
  }
}

/* ===== Kontras teks =====
   Tailwind CDN generate class text-white/40, /50, /60 dst secara runtime
   dengan opacity persis sesuai angkanya -- opacity serendah itu bikin
   teks susah kebaca. Dinaikkan di sini (bukan diubah di index.html) supaya konsisten
   ke semua teks yang pakai class itu, baik yang statis di HTML maupun
   yang di-generate dinamis lewat script.js (kartu komentar, dll).
   Selector "body .text-white\/40" sengaja dipakai (bukan cuma ".text-white\/40")
   biar specificity-nya menang otomatis atas class Tailwind, gak peduli
   urutan <style> Tailwind CDN ke-inject sebelum atau sesudah style.css ini. */
body .text-white\/80 {
  color: rgba(255, 255, 255, 0.88);
}
body .text-white\/70 {
  color: rgba(255, 255, 255, 0.82);
}
body .text-white\/60 {
  color: rgba(255, 255, 255, 0.76);
}
body .text-white\/50 {
  color: rgba(255, 255, 255, 0.68);
}
body .text-white\/40 {
  color: rgba(255, 255, 255, 0.6);
}
body .placeholder-white\/30::placeholder {
  color: rgba(255, 255, 255, 0.42);
}
body .border-white\/5 {
  border-color: rgba(255, 255, 255, 0.12);
}
body .border-white\/10 {
  border-color: rgba(255, 255, 255, 0.18);
}

/* ===== Anti-halaman-melebar-ke-samping =====
   Beberapa elemen dekorasi "glow"/blur (lingkaran blur radial di
   section Hero) sengaja dibikin gede
   (sampai 850px) biar efeknya soft & lembut di layar gede — tapi di
   HP kecil, ukuran segitu jauh lebih lebar dari layar, jadi bikin
   SELURUH HALAMAN (bukan cuma navbar) bisa digeser ke samping.
   `overflow-x: hidden` di html+body doang ternyata gak selalu cukup
   nge-clip elemen absolute yang gede itu di semua browser HP, jadi
   section Hero-nya sendiri dikasih overflow:hidden biar elemen
   dekorasi di dalemnya gak pernah bisa melebarkan halaman. */
#home {
  overflow: hidden;
}

.material-symbols-outlined {
  font-variation-settings:
    "FILL" 0,
    "wght" 500,
    "GRAD" 0,
    "opsz" 24;
  vertical-align: middle;
}

/* ===== Kartu / panel dasar: warna solid, tanpa blur, tanpa transparansi ===== */
.glass {
  background: var(--surface);
  border: 1px solid var(--surface-border);
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.45);
}

.glass-hover {
  transition: all 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.glass-hover:hover {
  transform: translateY(-8px);
  border-color: #fe7e3c;
  box-shadow: 0 16px 36px -14px rgba(0, 0, 0, 0.6);
}

@keyframes float {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-18px);
  }
}
.animate-float {
  animation: float 6s ease-in-out infinite;
}

.glow-btn {
  transition: transform 0.3s ease;
}
.glow-btn:hover {
  transform: translateY(-2px);
}

/* ===== Star Rating (fitur komentar) =====
   Widget input di form "Leave a Comment" pakai trik radio + CSS murni:
   input dirender urut 5→1 di DOM tapi ditampilin row-reverse (jadi
   1→5 dari kiri ke kanan). Karena urutannya kebalik, selector "~"
   (general sibling) otomatis nyalain bintang itu + semua bintang di
   sebelah kirinya (angka lebih kecil) pas checked/hover. Ikon pakai
   Material Symbols; FILL 0 = outline (belum dipilih), FILL 1 = solid
   (dipilih/di-hover), warnanya secondary (amber) biar kontras sama
   tema ungu situs. */
.star-rating {
  display: inline-flex;
  flex-direction: row-reverse;
  justify-content: flex-end;
  gap: 2px;
}
.star-rating input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.star-rating label {
  cursor: pointer;
  color: rgba(255, 255, 255, 0.2);
  font-variation-settings:
    "FILL" 0,
    "wght" 500,
    "GRAD" 0,
    "opsz" 24;
  transition:
    color 0.15s ease,
    transform 0.15s ease;
}
.star-rating label:hover,
.star-rating label:hover ~ label,
.star-rating input:checked ~ label {
  color: #fe7e3c;
  font-variation-settings:
    "FILL" 1,
    "wght" 500,
    "GRAD" 0,
    "opsz" 24;
}
.star-rating label:hover {
  transform: scale(1.15);
}
.star-rating input:focus-visible + label {
  outline: 2px solid #fe7e3c;
  outline-offset: 3px;
  border-radius: 6px;
}

/* Tampilan bintang read-only di kartu komentar (hasil renderStars() di
   script.js) — bukan input, cuma nunjukin rating yang udah dikirim. */
.stars-display {
  display: inline-flex;
  gap: 1px;
  color: rgba(255, 255, 255, 0.15);
}
.stars-display .star-filled {
  color: #fe7e3c;
  font-variation-settings:
    "FILL" 1,
    "wght" 500,
    "GRAD" 0,
    "opsz" 24;
}

.nav-link {
  position: relative;
}
.nav-link::after {
  content: "";
  position: absolute;
  bottom: -4px;
  left: 50%;
  width: 0;
  height: 2px;
  background: linear-gradient(90deg, #fe7e3c, #e4201b);
  transition: all 0.3s ease;
  transform: translateX(-50%);
}
.nav-link:hover::after,
.nav-link.active::after {
  width: 70%;
}
.nav-link.active {
  color: #e8f1f2;
}

/* ==========================================================================
   Experience & Education — stepper ala komponen "Stepper" React Bits, tapi
   ditulis ulang jadi vanilla JS + GSAP (bukan React/motion) soalnya situs
   ini gak pakai React. Panel bulat gede di atas, baris indikator lingkaran
   bernomor + garis penghubung yang keisi pas step udah dilewatin, konten
   satu step di tengah, tombol Back/Next teks di bawah — persis pola
   reactbits.dev/components/stepper, cuma warnanya disesuaikan ke palet
   situs (primary orange, bukan ungu). Kartunya ditumpuk di cell grid yang
   sama (grid-area: 1/1) dan transisi geser+fade-nya dijalanin GSAP, sama
   kayak crossfade di modal galeri project.
   ========================================================================== */
.exp-stepper {
  max-width: 40rem;
  margin: 0 auto;
}
.exp-panel {
  background: var(--surface);
  border: none;
  border-radius: 2rem;
  /* Cuma shadow buat kesan ngangkat dari background, gak pakai garis
     pinggir/outline sama sekali. */
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.45);
  overflow: hidden;
}

/* ---------- Baris indikator: lingkaran bernomor + garis penghubung ---------- */
.exp-indicators {
  display: flex;
  align-items: center;
  padding: 1.75rem 1.5rem 0.5rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.exp-indicators::-webkit-scrollbar {
  display: none;
}
.exp-indicator {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 9999px;
  border: none;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(232, 241, 242, 0.5);
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition:
    background 0.3s ease,
    color 0.3s ease,
    transform 0.3s ease;
}
.exp-indicator .material-symbols-outlined {
  font-size: 1rem;
}
.exp-indicator.is-active {
  background: #fe7e3c;
  color: #0f1b1e;
  transform: scale(1.1);
}
.exp-indicator.is-complete {
  background: rgba(254, 126, 60, 0.22);
  color: #fe7e3c;
}
.exp-indicator:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
.exp-connector {
  flex: 1 1 auto;
  min-width: 1.25rem;
  height: 2px;
  margin: 0 0.4rem;
  background: rgba(255, 255, 255, 0.14);
  overflow: hidden;
}
.exp-connector span {
  display: block;
  height: 100%;
  width: 0%;
  background: #fe7e3c;
  transition: width 0.4s ease;
}
.exp-connector.is-complete span {
  width: 100%;
}

/* ---------- Konten step ---------- */
.exp-stage {
  display: grid;
  padding: 1.5rem 1.75rem 0.5rem;
  overflow: hidden;
}
.exp-card {
  grid-area: 1 / 1;
  visibility: hidden;
  pointer-events: none;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}
.exp-card.is-active {
  visibility: visible;
  pointer-events: auto;
  z-index: 1;
}
.exp-card-content {
  min-width: 0;
}

/* ---------- Foto tiap experience (isi src-nya sendiri di assets/experience/) ---------- */
.exp-card-media {
  position: relative;
  border-radius: 1.25rem;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  background: linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.07),
    rgba(255, 255, 255, 0.02)
  );
}
.exp-card-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Selama foto belum diisi / gagal dimuat, tampilin placeholder halus
   pakai warna aksen kartu, bukan ikon broken-image bawaan browser. */
.exp-card-media.is-empty img {
  display: none;
}
.exp-card-media.is-empty {
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--exp-accent, #fe7e3c) 14%, transparent),
    rgba(255, 255, 255, 0.02)
  );
}

@media (min-width: 768px) {
  .exp-card {
    flex-direction: row;
    align-items: center;
    gap: 2.5rem;
  }
  .exp-card-content {
    flex: 1 1 56%;
  }
  .exp-card-media {
    flex: 1 1 44%;
    aspect-ratio: 4 / 3;
  }
}
.exp-card[data-accent="primary"] {
  --exp-accent: #ffaa80;
}
.exp-card[data-accent="secondary"] {
  --exp-accent: #38b2c1;
}
.exp-card[data-accent="tertiary"] {
  --exp-accent: #dcb5a8;
}
.exp-card .exp-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  margin-bottom: 1.1rem;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--exp-accent, #fe7e3c);
}
.exp-card .exp-icon .material-symbols-outlined {
  font-size: 1.5rem;
}
.exp-card .exp-title {
  margin: 0;
  font-size: 1.45rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.3;
  color: #fff;
}
.exp-card .exp-meta {
  margin: 0.35rem 0 0;
  font-size: 0.94rem;
  font-weight: 600;
  color: var(--exp-accent, #fe7e3c);
}

/* Deskripsi sekarang list poin-poin, bukan satu kalimat panjang.
   Marker custom (bukan bullet bawaan browser) senada aksen tiap kartu. */
.exp-card .exp-desc {
  margin: 1.1rem 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.exp-card .exp-desc li {
  position: relative;
  padding-left: 1.15rem;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.6;
  color: rgba(232, 241, 242, 0.75);
}
.exp-card .exp-desc li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 9999px;
  background: var(--exp-accent, #fe7e3c);
}

/* ---------- Footer: tombol Back / Next ---------- */
.exp-footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 1.5rem 1.75rem 1.75rem;
}
.exp-footer.has-back {
  justify-content: space-between;
}
.exp-btn {
  border: none;
  cursor: pointer;
  font-weight: 700;
  transition:
    background 0.25s ease,
    color 0.25s ease,
    opacity 0.25s ease;
}
.exp-btn--back {
  display: none;
  padding: 0.5rem 0.25rem;
  background: transparent;
  color: rgba(232, 241, 242, 0.55);
  font-size: 0.9rem;
}
.exp-footer.has-back .exp-btn--back {
  display: inline-flex;
}
.exp-btn--back:hover {
  color: #fff;
}
.exp-btn--next {
  padding: 0.7rem 1.4rem;
  border-radius: 9999px;
  background: #fe7e3c;
  color: #0f1b1e;
  font-size: 0.9rem;
}
.exp-btn--next:hover {
  background: #ffaa80;
}
.exp-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

@media (min-width: 640px) {
  .exp-card .exp-title {
    font-size: 1.5rem;
  }
}

/* ---------- Skala desktop: panel lebih lebar, semuanya sedikit lebih besar ---------- */
@media (min-width: 1024px) {
  .exp-stepper {
    max-width: 64rem;
  }
  .exp-indicators {
    padding: 2.5rem 3rem 0.75rem;
  }
  .exp-indicator {
    width: 2.5rem;
    height: 2.5rem;
    font-size: 0.9rem;
  }
  .exp-connector {
    margin: 0 0.6rem;
  }
  .exp-stage {
    padding: 2.25rem 3rem 1rem;
  }
  .exp-card .exp-icon {
    width: 3.75rem;
    height: 3.75rem;
    margin-bottom: 1.4rem;
  }
  .exp-card .exp-icon .material-symbols-outlined {
    font-size: 1.7rem;
  }
  .exp-card .exp-title {
    font-size: 1.9rem;
  }
  .exp-card .exp-meta {
    font-size: 1.05rem;
  }
  .exp-card .exp-desc {
    max-width: 34rem;
    gap: 0.75rem;
  }
  .exp-card .exp-desc li {
    font-size: 1.08rem;
    padding-left: 1.3rem;
  }
  .exp-card .exp-desc li::before {
    width: 0.45rem;
    height: 0.45rem;
  }
  .exp-footer {
    padding: 2rem 3rem 2.25rem;
  }
  .exp-btn--next {
    padding: 0.85rem 1.75rem;
    font-size: 1rem;
  }
  .exp-btn--back {
    font-size: 1rem;
  }
}

/* ---------- Layout: stepper (kiri) + panel sertifikat (kanan) ---------- */
.exp-layout {
  display: grid;
  gap: 2rem;
}

@media (min-width: 1024px) {
  .exp-layout {
    grid-template-columns: 3fr 2fr;
    align-items: start;
    max-width: 78rem;
    margin: 0 auto;
  }
  .exp-layout .exp-stepper {
    max-width: none;
    margin: 0;
  }
}

/* ---------- Panel sertifikat ---------- */
.cert-panel {
  background: var(--surface);
  border-radius: 2rem;
  box-shadow: 0 8px 24px -8px rgba(0, 0, 0, 0.45);
  padding: 1.75rem 1.5rem;
}
.cert-panel-title {
  margin: 0 0 1.25rem;
  font-size: 1.15rem;
  font-weight: 800;
  color: #fff;
}
.cert-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.cert-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem;
  border-radius: 1.25rem;
  background: rgba(255, 255, 255, 0.03);
  text-decoration: none;
  transition:
    background 0.25s ease,
    transform 0.25s ease;
}
.cert-item:hover {
  background: rgba(255, 255, 255, 0.07);
  transform: translateY(-2px);
}
.cert-thumb {
  flex: 0 0 5.5rem;
  width: 5.5rem;
  aspect-ratio: 4 / 3;
  border-radius: 0.85rem;
  overflow: hidden;
  background: #fff;
  display: grid;
  place-items: center;
}
.cert-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.cert-thumb.is-empty {
  background: linear-gradient(
    135deg,
    rgba(254, 126, 60, 0.14),
    rgba(255, 255, 255, 0.04)
  );
}
.cert-thumb.is-empty img {
  display: none;
}
.cert-info {
  min-width: 0;
}
.cert-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.35;
  color: #fff;
}
.cert-issuer {
  margin: 0.3rem 0 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: rgba(232, 241, 242, 0.6);
}

@media (min-width: 1024px) {
  .cert-panel {
    padding: 2.25rem 2rem;
  }
  .cert-panel-title {
    font-size: 1.3rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .exp-indicator,
  .exp-connector span,
  .exp-btn {
    transition: none;
  }
}



/* ===== Scroll Reveal =====
   Murni CSS (transform + opacity saja, jalan di compositor) -- gak
   tergantung GSAP. Elemen cuma disembunyikan kalau <html> punya class
   .reveal-ready, yang dipasang inline di <head> HANYA kalau browser
   dukung IntersectionObserver & user gak minta "reduced motion". Jadi
   tanpa JS / dengan reduced-motion semua konten langsung kelihatan.
   Logika pemicunya ada di initScrollReveal() (script.js). */
:root {
  --rv-y: 30px;
  --rv-x: 40px;
  --rv-dur: 0.8s;
  --rv-ease: cubic-bezier(0.22, 1, 0.36, 1); /* easeOutQuint: cepat di awal, mendarat halus */
}

.reveal-ready [data-reveal]:not(.is-in),
.reveal-ready [data-reveal-item]:not(.is-in) {
  opacity: 0;
}

@keyframes rv-up {
  from { opacity: 0; transform: translate3d(0, var(--rv-y), 0); }
}
@keyframes rv-left {
  from { opacity: 0; transform: translate3d(calc(var(--rv-x) * -1), 0, 0); }
}
@keyframes rv-right {
  from { opacity: 0; transform: translate3d(var(--rv-x), 0, 0); }
}
@keyframes rv-scale {
  from { opacity: 0; transform: scale(0.92); }
}
@keyframes rv-pop {
  from { opacity: 0; transform: translate3d(0, 18px, 0) scale(0.92); }
}
@keyframes rv-line {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* "backwards" = selama delay stagger elemen tetap di posisi awal, dan
   setelah selesai animasinya lepas total (jadi gak bentrok sama hover). */
.is-in[data-reveal],
.is-in[data-reveal-item] {
  animation: rv-up var(--rv-dur) var(--rv-ease) var(--rv-delay, 0ms) backwards;
}
.is-in[data-reveal="left"]  { animation-name: rv-left; }
.is-in[data-reveal="right"] { animation-name: rv-right; }
.is-in[data-reveal="scale"] { animation-name: rv-scale; }
.is-in[data-reveal-item]    { animation-name: rv-pop; --rv-dur: 0.6s; }
.is-in[data-reveal="line"]  { animation-name: rv-line; animation-duration: 1.6s; }

/* Elemen yang sudah terlewat (mis. habis lompat lewat menu) langsung
   tampil tanpa animasi, biar gak ada section kosong pas discroll balik. */
.is-in.is-instant {
  animation: none !important;
}

/* Mobile / layar sentuh: gerak lebih pendek & lebih cepat, gak ada
   geser horizontal (kiri/kanan diganti naik) supaya ringan dan gak
   bikin halaman bisa digeser ke samping. */
@media (max-width: 767px), (hover: none) {
  :root {
    --rv-y: 22px;
    --rv-dur: 0.55s;
  }
  .is-in[data-reveal="left"],
  .is-in[data-reveal="right"] {
    animation-name: rv-up;
  }
  .is-in[data-reveal-item] {
    --rv-dur: 0.5s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .reveal-ready [data-reveal],
  .reveal-ready [data-reveal-item] {
    opacity: 1 !important;
    animation: none !important;
  }
}

::-webkit-scrollbar {
  width: 8px;
}
::-webkit-scrollbar-track {
  background: #0f1b1e;
}
::-webkit-scrollbar-thumb {
  background: #34575e;
  border-radius: 8px;
}

/* Kolom "Recent Activity": dulu daftar komentar/reply ikut manjang
   ke bawah tanpa batas mengikuti jumlah komentar, bikin section
   Contact jadi sangat tinggi kalau komentarnya udah banyak. Sekarang
   dikasih tinggi maksimum lalu discroll sendiri di dalam boxnya,
   supaya section-nya tetap ringkas berapa pun jumlah komentarnya. */
#commentsList {
  max-height: 620px;
  overflow-y: auto;
  padding-right: 6px;
  scrollbar-gutter: stable;
}
#commentsList::-webkit-scrollbar {
  width: 6px;
}
#commentsList::-webkit-scrollbar-track {
  background: transparent;
}
#commentsList::-webkit-scrollbar-thumb {
  background: #34575e;
  border-radius: 8px;
}

/* ===== Daftar komentar bergaya "chat thread" =====
   Dulu tiap komentar top-level punya kartu .glass sendiri-sendiri
   (terpisah dengan jarak/gap). Sekarang #commentsList sendiri yang
   jadi satu kartu .glass besar (lihat index.html), dan tiap komentar
   di dalemnya cuma dipisah garis tipis (.comment-row) — biar kelihatan
   kayak satu percakapan/thread, bukan tumpukan kartu terpisah. */
.comment-row {
  padding-block: 1.15rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.comment-row:first-child {
  padding-top: 0.15rem;
}
.comment-row:last-child {
  border-bottom: none;
  padding-bottom: 0.15rem;
}

/* ===== Baris aksi & reaksi per komentar =====
   Didesain ulang biar flat & tenang (ikon + teks kecil, kayak
   referensi Pagedone/commenting) — bukan lagi tombol bulat warna-warni
   dan popover ngambang dengan animasi loncat & shadow nyala. */
.msg-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.1rem;
  margin-top: 0.55rem;
}

/* Tombol aksi ikon+label (Reply, Tambah reaksi) — gaya sama biar
   konsisten satu sama lain, netral sampai di-hover/aktif baru ungu. */
.msg-icon-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  font-weight: 700;
  color: rgba(232, 241, 242, 0.45);
  cursor: pointer;
  transition: color 0.15s ease;
}
.msg-icon-btn:hover,
.msg-icon-btn.is-active {
  color: #fe7e3c;
}
.msg-icon-btn .material-symbols-outlined {
  font-size: 1rem;
}

.reactions-inline {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.7rem;
}

/* Chip teks datar buat emoji yang udah punya reaksi (count > 0) —
   tanpa background/border box, cuma warna yang berubah. Diklik lagi
   buat batalin reaksi kamu sendiri. */
.reaction-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.72rem;
  font-weight: 600;
  color: rgba(232, 241, 242, 0.45);
  cursor: pointer;
  transition: color 0.15s ease;
}
.reaction-chip:hover {
  color: rgba(232, 241, 242, 0.8);
}
.reaction-chip.is-active {
  color: #fe7e3c;
}

/* Pilihan 5 emoji, muncul SEJAJAR di baris yang sama (bukan popover
   ngambang) begitu tombol "Tambah reaksi" diklik. */
.reaction-picker-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding-left: 0.7rem;
  border-left: 1px solid rgba(255, 255, 255, 0.1);
}
.reaction-picker-inline button {
  font-size: 0.95rem;
  line-height: 1;
  opacity: 0.55;
  cursor: pointer;
  transition:
    opacity 0.15s ease,
    transform 0.1s ease;
}
.reaction-picker-inline button:hover {
  opacity: 1;
  transform: scale(1.15);
}

input:focus,
textarea:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(254, 126, 60, 0.5);
}

/* ===== Project Categories (Featured Projects) =====
   4 kategori sekarang jadi 4 "mini hero showcase" sendiri-sendiri
   (terinspirasi referensi Stitch: eyebrow pill + heading gradient +
   deskripsi di tengah atas, lalu showcase visual unik di bawahnya).
   Hampir semua styling-nya pakai utility class Tailwind langsung di
   index.html (arbitrary value kaya bg-[#fe7e3c]/10, rotate-[-12deg],
   dst) -- rule di bawah ini cuma base/shared yang dipakai di semua
   4 section + microinteraction hover (gap CTA, ring focus).
   Klik di mana aja pada .project-cat (atau Enter/Space pas fokus)
   buka galeri penuh kategori itu di folderModal. */
.project-categories {
  display: flex;
  flex-direction: column;
  gap: 5rem;
  width: 100%;
}

.project-cat {
  position: relative;
  /* cursor default sementara -- klik-nya lagi dimatikan di script.js
     selama acc-images 4 kategori ini masih kosong. Balikin ke
     "pointer" pas fitur klik-nya dinyalain lagi. */
  cursor: default;
  outline: none;
  border-radius: 2rem;
}
.project-cat:focus-visible {
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 4px var(--cat-accent, #fe7e3c);
}
/* Kategori yang acc-images-nya udah diisi foto asli (lihat script.js) --
   dikasih cursor pointer beneran, biar keliatan bisa diklik buka galeri. */
.project-cat--clickable {
  cursor: pointer;
}

.project-cat-index {
  font-weight: 800;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--cat-accent, #fe7e3c);
}
.project-cat-title {
  color: #fff;
}
.project-cat-desc {
  color: rgba(232, 241, 242, 0.62);
}
.project-cat-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--cat-accent, #fe7e3c);
  transition: gap 0.25s ease;
}
.project-cat-btn .material-symbols-outlined {
  font-size: 18px;
  transition: transform 0.25s ease;
}
.project-cat:hover .project-cat-btn,
.project-cat:focus-visible .project-cat-btn {
  gap: 0.65rem;
}
.project-cat:hover .project-cat-btn .material-symbols-outlined,
.project-cat:focus-visible .project-cat-btn .material-symbols-outlined {
  transform: translate(3px, -3px);
}

/* =========================================================================
   Vanilla-JS TextType (porting dari komponen React Bits "TextType",
   dependensi gsap) -- efek ngetik buat heading 4 kategori project.
   Logikanya di script.js ("Vanilla TextType"); di sini cuma tampilan
   kursornya. Kursor selalu jadi child terakhir <h3 data-texttype>, jadi
   posisinya otomatis ngikut ujung teks yang lagi diketik.
   ========================================================================= */
.tt-cursor {
  display: inline-block;
  margin-left: 0.06em;
  font-weight: 400;
  color: var(--cat-accent, #fe7e3c);
  opacity: 0;
}
.tt-cursor.is-on {
  opacity: 1;
}
/* Reduced motion / JS gak jalan -> teks langsung tampil penuh tanpa
   diketik, kursornya gak usah muncul sama sekali. */
@media (prefers-reduced-motion: reduce) {
  .tt-cursor {
    display: none;
  }
}

/* =========================================================================
   01. PHOTO EDITING -- 2 panel sejajar, tiap panel punya slider
   before/after sendiri + tombol panah buat ganti pasangan fotonya.
   ========================================================================= */
.pe-stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
  margin: 3rem auto 1.5rem;
  width: 100%;
  max-width: 1500px;
  align-items: stretch;
}
@media (min-width: 900px) {
  .pe-stage {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2rem;
  }
}
@media (min-width: 1440px) {
  .pe-stage {
    gap: 2.75rem;
  }
}

.pe-panel {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}
.pe-panel-title {
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: #fff;
  text-align: center;
}
@media (min-width: 1280px) {
  .pe-panel-title {
    font-size: 1.25rem;
  }
}

/* ---------- Frame: kotak besar tempat before/after tampil ---------- */
.pe-frame {
  position: relative;
  flex: 1;
  border-radius: 1.75rem;
  overflow: hidden;
  background: var(--surface-2);
  border: 1px solid rgba(255, 255, 255, 0.16);
  aspect-ratio: 4 / 5;
  box-shadow: 0 30px 70px -28px rgba(228, 32, 27, 0.45);
  contain: paint;
}
@media (min-width: 900px) {
  .pe-frame {
    aspect-ratio: auto;
    min-height: 30rem;
  }
}
@media (min-width: 1280px) {
  .pe-frame {
    min-height: 36rem;
  }
}
@media (min-width: 1536px) {
  .pe-frame {
    min-height: 40rem;
  }
}

.pe-track {
  position: absolute;
  inset: 0;
}

/* Satu pasang before/after = satu slide */
.pe-pair {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.4s ease,
    visibility 0.4s;
}
.pe-pair.is-active {
  opacity: 1;
  visibility: visible;
}

.pe-ba-frame {
  position: absolute;
  inset: 0;
  touch-action: pan-y;
}

.pe-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Selama src masih kosong / gagal dimuat, <img> disembunyiin dan
   placeholder .pe-ph yang tampil. */
.pe-img:not([src]),
.pe-img[src=""],
.pe-img.is-missing {
  display: none;
}

/* ---------- Placeholder sebelum foto asli dipasang ---------- */
.pe-ph {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  text-align: center;
  background:
    repeating-linear-gradient(
      135deg,
      rgba(255, 255, 255, 0.025) 0 10px,
      transparent 10px 20px
    ),
    var(--surface-3);
  color: rgba(232, 241, 242, 0.45);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.pe-ph--raw {
  filter: grayscale(1);
}
.pe-img:not(.is-missing)[src]:not([src=""]) ~ .pe-ph {
  display: none;
}

/* ---------- Layer before/after ---------- */
.pe-ba-layer {
  position: absolute;
  inset: 0;
}
/* Layer BEFORE dipotong dari kiri sampe posisi handle (--pe-pos). */
.pe-ba-layer--before {
  clip-path: inset(0 calc(100% - var(--pe-pos, 50%)) 0 0);
}

.pe-ba-tag {
  position: absolute;
  bottom: 1rem;
  z-index: 5;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  pointer-events: none;
}
.pe-ba-tag--before {
  left: 1rem;
  background: rgba(11, 21, 23, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: rgba(255, 255, 255, 0.85);
}
.pe-ba-tag--after {
  right: 1rem;
  background: var(--cat-accent, #fe7e3c);
  color: #0f1b1e;
}

/* Garis + knob handle: cuma visual, interaksinya dipegang input range. */
.pe-ba-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pe-pos, 50%);
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  transform: translateX(-50%);
  pointer-events: none;
}
.pe-ba-line {
  flex: 1;
  width: 2px;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 0 12px rgba(0, 0, 0, 0.55);
}
.pe-ba-knob {
  flex: none;
  display: grid;
  grid-auto-flow: column;
  place-items: center;
  width: 3.1rem;
  height: 3.1rem;
  border-radius: 999px;
  background: #fff;
  color: #0f1b1e;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
  transition: transform 0.2s ease;
}
.pe-ba-knob .material-symbols-outlined {
  font-size: 20px;
  margin: 0 -3px;
}
.pe-ba-frame:hover .pe-ba-knob,
.pe-ba-range:focus-visible ~ .pe-ba-handle .pe-ba-knob {
  transform: scale(1.08);
}
.pe-ba-range:focus-visible ~ .pe-ba-handle .pe-ba-knob {
  outline: 3px solid var(--cat-accent, #fe7e3c);
  outline-offset: 2px;
}

/* Input range asli: transparan, nutupin seluruh frame biar drag di mana
   aja kebaca (mouse, sentuh) dan panah kiri/kanan jalan pas fokus.
   Dikasih inset di kiri-kanan supaya tombol panah tetep bisa dipencet. */
.pe-ba-range {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 4.2rem;
  right: 4.2rem;
  z-index: 7;
  margin: 0;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: none;
  cursor: ew-resize;
  outline: none;
}
.pe-ba-range::-webkit-slider-runnable-track {
  height: 100%;
  background: transparent;
}
.pe-ba-range::-moz-range-track {
  height: 100%;
  background: transparent;
}
.pe-ba-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 3.4rem;
  height: 100%;
  background: transparent;
  border: none;
  cursor: ew-resize;
}
.pe-ba-range::-moz-range-thumb {
  width: 3.4rem;
  height: 100%;
  background: transparent;
  border: none;
  cursor: ew-resize;
}

/* ---------- Tombol panah ganti pasangan foto ---------- */
.pe-nav {
  position: absolute;
  top: 50%;
  z-index: 8;
  width: 2.8rem;
  height: 2.8rem;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: rgba(11, 21, 23, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: #fff;
  cursor: pointer;
  transform: translateY(-50%);
  transition:
    background 0.25s ease,
    border-color 0.25s ease,
    transform 0.25s ease;
}
.pe-nav .material-symbols-outlined {
  font-size: 24px;
}
.pe-nav--prev {
  left: 0.7rem;
}
.pe-nav--next {
  right: 0.7rem;
}
.pe-nav:hover {
  background: var(--cat-accent, #fe7e3c);
  border-color: transparent;
  color: #0f1b1e;
}
.pe-nav--prev:hover {
  transform: translateY(-50%) translateX(-2px);
}
.pe-nav--next:hover {
  transform: translateY(-50%) translateX(2px);
}
.pe-nav:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* ---------- Counter + dots ---------- */
.pe-counter {
  position: absolute;
  top: 0.9rem;
  left: 1rem;
  z-index: 8;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: rgba(11, 21, 23, 0.8);
  border: 1px solid rgba(255, 255, 255, 0.12);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.8);
}
.pe-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 3.1rem;
  z-index: 8;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
}
.pe-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  border: none;
  padding: 0;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.35);
  transition:
    width 0.3s ease,
    background 0.3s ease;
}
.pe-dot.is-active {
  width: 1.4rem;
  background: var(--cat-accent, #fe7e3c);
}
.pe-dot:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.pe-ba-hint {
  text-align: center;
  margin-bottom: 2rem;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: rgba(232, 241, 242, 0.5);
}

@media (prefers-reduced-motion: reduce) {
  .pe-pair,
  .pe-nav,
  .pe-dot,
  .pe-ba-knob {
    transition: none;
  }
}

/* ===== Kartu di dalam showcase Featured Projects: solid ===== */
.rt-card {
  background: var(--surface-2);
  border: 1px solid var(--surface-border);
}

/* Kartu mini generik (feed preview, kartu undangan, dst) */
.gm-mini-card {
  background: var(--surface-2);
  border: 1px solid var(--surface-border);
  border-radius: 1.25rem;
  box-shadow: 0 6px 20px -8px rgba(0, 0, 0, 0.5);
  transition: border-color 0.3s ease, background 0.3s ease;
}
.gm-mini-card:hover {
  border-color: #3f6d75;
  background: var(--surface-3);
}

/* Tile kecil grid (thumbnail feed, mockup apparel) */
.gm-tile {
  background: var(--surface-3);
  border: 1px solid var(--surface-border);
  border-radius: 1rem;
}
/* =========================================================================
   03. APPAREL DESIGN -- "Lookbook Index"
   Konsep: lookbook editorial ala studio. Kiri = panggung produk (frame krem
   + crop marks + nomor besar transparan di belakang produk), kanan = daftar
   bernomor yang jadi "daftar isi" -- klik satu baris, panggung ganti produk
   dan baris itu buka spek teknisnya (fabric / teknik / fit / colorway).
   Tiap produk punya warna aksen sendiri (--acc) yang ngewarnain nomor,
   garis atas baris, progress bar, dan tombol. Semua warna solid, tanpa
   glass/blur. Font: Archivo buat angka & judul, Plus Jakarta Sans sisanya.
   ========================================================================= */
#apparel {
  --ap-surface: #24191a;
  --ap-surface-2: #33262a;
  --ap-cream: #ede6dd;
  --ap-ink: #1c1411;
  --ap-text: #f6efe8;
  --ap-muted: rgba(246, 239, 232, 0.56);
  --ap-rule: rgba(246, 239, 232, 0.13);
  --ap-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---- Header: judul kiri, deskripsi kanan (desktop) ---- */
.apparel-head {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-bottom: 2rem;
  text-align: left;
}
.apparel-desc {
  max-width: 26rem;
  margin: 0;
}

/* ---- Grid utama: panggung + daftar ---- */
.apparel-lookbook {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.5rem;
  width: 100%;
}

/* ---- Panggung ---- */
.apparel-stage {
  background: var(--ap-surface);
  border-radius: 1.5rem;
  padding: 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  min-width: 0;
}
.apparel-stage-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.25rem 0.6rem 0;
  font-family: "Archivo", "Inter Tight", "Plus Jakarta Sans", sans-serif;
  font-weight: 700;
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ap-muted);
}
.apparel-stage-count b {
  color: var(--acc);
  font-weight: 800;
  transition: color 0.4s ease;
}
.apparel-canvas {
  isolation: isolate;
  contain: paint;
  position: relative;
  background: var(--ap-cream);
  border-radius: 1rem;
  overflow: hidden;
  aspect-ratio: var(--ar, 1 / 1.08);
  max-height: 80vh;
  touch-action: pan-y;
}
.apparel-slide {
  will-change: opacity, transform;
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 2.4rem 1.5rem 3rem;
  display: grid;
  place-items: center;
  opacity: 0;
  transform: scale(0.96);
  pointer-events: none;
  transition: opacity 0.4s ease, transform 0.5s var(--ap-ease);
}
.apparel-slide.is-active {
  opacity: 1;
  transform: none;
}
.apparel-slide img {
  position: absolute;
  inset: 2.2rem 1.25rem 2.7rem;
  width: calc(100% - 2.5rem);
  height: calc(100% - 4.9rem);
  object-fit: contain;
  mix-blend-mode: multiply;
  user-select: none;
}
.apparel-slide figcaption {
  position: absolute;
  left: 1.4rem;
  bottom: 1.1rem;
  font-family: "Archivo", "Inter Tight", sans-serif;
  font-weight: 700;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(28, 20, 17, 0.6);
}
/* Crop marks di 4 pojok */
.apparel-crop {
  position: absolute;
  width: 14px;
  height: 14px;
  border: 0 solid rgba(28, 20, 17, 0.38);
  pointer-events: none;
}
.apparel-crop--tl { top: 0.8rem; left: 0.8rem; border-top-width: 1.5px; border-left-width: 1.5px; }
.apparel-crop--tr { top: 0.8rem; right: 0.8rem; border-top-width: 1.5px; border-right-width: 1.5px; }
.apparel-crop--bl { bottom: 0.8rem; left: 0.8rem; border-bottom-width: 1.5px; border-left-width: 1.5px; }
.apparel-crop--br { bottom: 0.8rem; right: 0.8rem; border-bottom-width: 1.5px; border-right-width: 1.5px; }

.apparel-stage-foot {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0 0.3rem 0.2rem;
}
.apparel-progress {
  flex: 1;
  display: flex;
  gap: 0.4rem;
}
.apparel-progress span {
  flex: 1;
  height: 3px;
  border-radius: 3px;
  background: var(--ap-rule);
  transition: background 0.4s ease;
}
.apparel-progress span.is-active {
  background: var(--acc);
}
.apparel-nav {
  display: flex;
  gap: 0.5rem;
}
.apparel-nav-btn {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  border-radius: 999px;
  background: var(--ap-surface-2);
  color: var(--ap-text);
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease, transform 0.25s ease;
}
.apparel-nav-btn .material-symbols-outlined {
  font-size: 20px;
}
.apparel-nav-btn:hover {
  background: var(--acc);
  color: var(--ap-ink);
  transform: translateY(-2px);
}
.apparel-nav-btn:focus-visible,
.apparel-item-btn:focus-visible {
  outline: 2px solid var(--acc, #dcb5a8);
  outline-offset: 3px;
}

/* ---- Daftar produk (accordion) ---- */
.apparel-index {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.apparel-item {
  border-top: 1px solid var(--ap-rule);
  transition: border-color 0.35s ease;
}
.apparel-item:last-child {
  border-bottom: 1px solid var(--ap-rule);
}
.apparel-item.is-active {
  border-top-color: var(--acc);
}
.apparel-item-btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.35rem 0.25rem;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.apparel-item-idx {
  min-width: 2.7rem;
  font-family: "Archivo", "Inter Tight", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: 1.9rem;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ap-muted);
  transition: color 0.35s ease;
}
.apparel-item.is-active .apparel-item-idx,
.apparel-item-btn:hover .apparel-item-idx {
  color: var(--acc);
}
.apparel-item-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.apparel-item-cat {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ap-muted);
}
.apparel-item-title {
  font-family: "Archivo", "Inter Tight", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: 1.05rem;
  line-height: 1.2;
  letter-spacing: -0.005em;
  color: rgba(246, 239, 232, 0.72);
  transition: color 0.3s ease;
}
.apparel-item.is-active .apparel-item-title,
.apparel-item-btn:hover .apparel-item-title {
  color: var(--ap-text);
}
.apparel-item-toggle {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.2rem;
  height: 2.2rem;
  border-radius: 999px;
  background: var(--ap-surface-2);
  color: var(--ap-text);
  font-size: 20px !important;
  transition: transform 0.4s var(--ap-ease), background 0.3s ease, color 0.3s ease;
}
.apparel-item.is-active .apparel-item-toggle {
  transform: rotate(45deg);
  background: var(--acc);
  color: var(--ap-ink);
}
.apparel-item-body {
  display: none;
}
.apparel-item.is-active .apparel-item-body {
  display: block;
}
.apparel-item-clip {
  padding: 0 0.25rem 1.5rem 3.7rem;
}
.apparel-item.is-active .apparel-item-clip {
  animation: apparelIn 0.35s var(--ap-ease) both;
}
@keyframes apparelIn {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
.apparel-item-desc {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.6;
  color: rgba(246, 239, 232, 0.72);
}
.apparel-specs {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 0.6rem 1.4rem;
  margin: 1.1rem 0 1.2rem;
  padding: 1rem 1.1rem;
  background: var(--ap-surface);
  border-radius: 0.9rem;
}
.apparel-specs dt {
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ap-muted);
  padding-top: 0.15rem;
}
.apparel-specs dd {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ap-text);
}
.apparel-item-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.apparel-swatches {
  display: inline-flex;
  gap: 0.4rem;
}
.apparel-swatch {
  width: 1.15rem;
  height: 1.15rem;
  border-radius: 999px;
  background: var(--sw);
  box-shadow: 0 0 0 2px var(--ap-surface-2);
}
.apparel-item-action {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--acc);
  transition: gap 0.25s ease;
}
.apparel-item-action .material-symbols-outlined {
  font-size: 18px;
}
.apparel-item:hover .apparel-item-action {
  gap: 0.6rem;
}

/* ---- Animasi reveal: header -> panggung -> baris -> CTA, sekali pas
   section pertama kali kesorot (class .apparel-inview dari script.js). ---- */
#apparel .apparel-head,
#apparel .apparel-stage,
#apparel .apparel-item,
#apparel .apparel-cta {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.7s var(--ap-ease), transform 0.7s var(--ap-ease),
    border-color 0.35s ease;
}
#apparel.apparel-inview .apparel-head,
#apparel.apparel-inview .apparel-stage,
#apparel.apparel-inview .apparel-item,
#apparel.apparel-inview .apparel-cta {
  opacity: 1;
  transform: none;
}
#apparel.apparel-inview .apparel-head { transition-delay: 0.02s; }
#apparel.apparel-inview .apparel-stage { transition-delay: 0.14s; }
#apparel.apparel-inview .apparel-item:nth-child(1) { transition-delay: 0.22s; }
#apparel.apparel-inview .apparel-item:nth-child(2) { transition-delay: 0.3s; }
#apparel.apparel-inview .apparel-item:nth-child(3) { transition-delay: 0.38s; }
#apparel.apparel-inview .apparel-item:nth-child(4) { transition-delay: 0.46s; }
#apparel.apparel-inview .apparel-cta { transition-delay: 0.56s; }

#apparel.apparel-settled .apparel-head,
#apparel.apparel-settled .apparel-stage,
#apparel.apparel-settled .apparel-item,
#apparel.apparel-settled .apparel-cta {
  transition: border-color 0.3s ease !important;
  transition-delay: 0s !important;
}
@media (prefers-reduced-motion: reduce) {
  #apparel .apparel-head,
  #apparel .apparel-stage,
  #apparel .apparel-item,
  #apparel .apparel-cta {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .apparel-slide,
  .apparel-slide img,
  .apparel-item-clip {
    animation: none !important;
  }
}

/* ---- Tablet ke atas ---- */
@media (min-width: 640px) {
  .apparel-canvas {
    aspect-ratio: var(--ar, 1 / 0.9);
  }
  .apparel-item-title {
    font-size: 1.2rem;
  }
}

/* ---- Desktop (>=1024px): panggung nempel (sticky) di kiri, daftar
   produk di kanan -- panggung tetap kelihatan selagi baris dibuka. ---- */
@media (min-width: 1024px) {
  #apparel .apparel-card-inner {
    padding: 5.5rem 3rem 3rem;
  }
  .apparel-head {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: 3rem;
    margin-bottom: 2.75rem;
  }
  .apparel-desc {
    padding-bottom: 0.6rem;
  }
  .apparel-lookbook {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 2.5rem;
    align-items: start;
  }
  .apparel-stage {
    grid-column: span 7;
    position: sticky;
    top: 6rem;
    padding: 1rem;
  }
  .apparel-canvas {
    aspect-ratio: var(--ar, 1 / 0.9);
    max-height: min(74vh, 46rem);
  }
  .apparel-index {
    grid-column: span 5;
  }
  .apparel-item-btn {
    padding: 1.5rem 0.25rem;
  }
  .apparel-item-idx {
    font-size: 2.3rem;
    min-width: 3.2rem;
  }
  .apparel-item-clip {
    padding-left: 4.2rem;
  }
}

/* =========================================================================
   02. SOCIAL MEDIA -- "ChromaGrid", porting utuh dari komponen React Bits
   ChromaGrid (varian JavaScript + Tailwind, dependency: gsap). Struktur
   kartunya (.chroma-grid > .chroma-card) langsung ditulis di markup
   index.html (bukan di-generate JS kayak DriftWall versi lama), soalnya
   ChromaGrid aslinya emang nerima data lewat prop "items" yang statis --
   gak ada alasan buat bikin lapisan JS tambahan cuma buat nge-render
   kartu yang isinya juga statis.

   Yang di-porting ke JS (lihat initChromaGrid() di script.js):
   1. Spotlight warna per-kartu (chroma-card-spotlight) yang ngikutin
      posisi kursor DI DALAM kartu itu sendiri pas di-hover -- versi
      React-nya nulis --mouse-x/--mouse-y lewat onMouseMove per kartu.
   2. Efek "spotlight" abu-abu/warna buat SELURUH grid (chroma-grid-mask
      + chroma-grid-fade) yang ngikutin kursor dengan damping halus (gsap
      quickSetter + gsap.to, persis logic moveTo()/handleMove()/
      handleLeave() di komponen aslinya) -- CSS mask dua lapis di bawah
      ini nilainya disalin APA ADANYA dari inline style komponen React
      aslinya (radius/opacity/stop percentage sama persis), cuma
      dipindah dari inline style ke custom property --x/--y/--r di sini
      biar bisa di-update tiap frame dari JS tanpa nulis ulang seluruh
      style string.

   Warna border tiap kartu (--card-border, dipakai pas hover/focus) dikasih
   langsung lewat inline style di tiap <article class="chroma-card"> di
   index.html (persis kayak prop borderColor di item React-nya), jadi
   gampang diganti per-foto tanpa nyentuh CSS ini. Prop "gradient" komponen
   aslinya SENGAJA gak dipakai -- foto-fotonya jadi full-bleed tanpa
   background warna di belakangnya (lihat .chroma-card-image di bawah).
   ========================================================================= */
.chroma-grid-wrap {
  position: relative;
  border-radius: 1.5rem;
}

.chroma-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.85rem;
}
@media (min-width: 640px) {
  .chroma-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
  }
}
/* Dari desktop ke atas, kolomnya auto-fill (bukan angka tetap) --
   browser bakal ngisi sebanyak mungkin kolom selebar minmax()-nya biar
   grid-nya SELALU penuh sampai tepi kanan-kiri container (gak nyisain
   ruang kosong kayak grid-template-columns tetap 4 kolom dulu), dan
   otomatis nambah kolom sendiri kalau layarnya makin lebar. */
@media (min-width: 1024px) {
  .chroma-grid {
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1.15rem;
  }
}
@media (min-width: 1536px) {
  .chroma-grid {
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1.35rem;
  }
}

/* ---- Satu kartu ChromaGrid ----
   background = warna netral gelap (BUKAN --card-gradient kayak komponen
   React aslinya -- fotonya sengaja dibiarin full-bleed tanpa panel
   warna di belakangnya), border nyala warna --card-border (prop
   "borderColor") pas di-hover atau di-focus (keyboard nav, kartu-nya
   emang tabindex="0" -- klik ngebuka galeri lightbox lewat handler
   .project-cat yang udah ada). */
.chroma-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 20px;
  border: 2px solid transparent;
  background: #0d0f10;
  cursor: pointer;
  transition:
    border-color 0.3s ease,
    transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
.chroma-card:hover,
.chroma-card:focus-visible {
  border-color: var(--card-border, transparent);
  transform: translateY(-4px);
  box-shadow: 0 18px 40px -20px rgba(0, 0, 0, 0.65);
  z-index: 2;
}
.chroma-card:focus-visible {
  outline: none;
}

/* Spotlight warna di dalam kartu, ngikutin --mx/--my yang di-update
   lewat mousemove per-kartu di initChromaGrid() -- sama persis
   background radial-gradient di komponen React aslinya. */
.chroma-card-spotlight {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s ease;
  background: radial-gradient(
    circle at var(--mx, 50%) var(--my, 50%),
    rgba(255, 255, 255, 0.3),
    transparent 70%
  );
}
.chroma-card:hover .chroma-card-spotlight,
.chroma-card:focus-visible .chroma-card-spotlight {
  opacity: 1;
}

.chroma-card-image {
  position: relative;
  z-index: 1;
  aspect-ratio: 4 / 5;
}
.chroma-card-image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  user-select: none;
}

/* Gak ada background warna lagi di belakang foto, jadi footer-nya
   dikasih background gelap sendiri (bukan nempel ke gradient kartu)
   biar judul/subjudulnya tetap gampang dibaca di atas foto apa pun. */
.chroma-card-footer {
  position: relative;
  z-index: 1;
  padding: 0.6rem 0.85rem 0.75rem;
  color: #fff;
  font-family: inherit;
  background: #0d0f10;
}
.chroma-card-footer h4 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.25;
}
.chroma-card-footer p {
  margin: 0.15rem 0 0;
  font-size: 0.78rem;
  opacity: 0.85;
}

/* ---- Spotlight buat seluruh grid, dua lapis ----
   Nilai radial-gradient di bawah ini disalin persis dari inline style
   komponen React aslinya (cuma posisi %/px-nya diganti custom property
   --x/--y/--r biar bisa di-update tiap frame dari JS lewat
   gsap.quickSetter, lihat initChromaGrid()).

   .chroma-grid-mask = lapisan bawah, SELALU aktif: dalam radius --r di
   sekitar kursor jadi transparan (foto asli/berwarna keliatan), makin
   jauh dari kursor makin opaque (backdrop-filter grayscale+brightness
   di elemen ini kepakai penuh).
   .chroma-grid-fade = lapisan atas, mask-nya KEBALIKAN dari yang di
   atas (opaque di tengah/dekat kursor, transparan di tepi). Defaultnya
   opacity 1 -- jadi nutupin "lubang" warna yang dibikin mask di bawah,
   hasilnya grid keliatan abu-abu semua. Pas pointer masuk grid,
   opacity-nya di-animate ke 0 (nyingkepin lubang warna = efek
   spotlight), dan pas pointer keluar di-animate balik ke 1 (fadeOut). */
.chroma-grid-mask,
.chroma-grid-fade {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  border-radius: 1.5rem;
  background: rgba(0, 0, 0, 0.001);
  -webkit-backdrop-filter: grayscale(1) brightness(0.78);
  backdrop-filter: grayscale(1) brightness(0.78);
}
.chroma-grid-mask {
  -webkit-mask-image: radial-gradient(
    circle var(--r, 300px) at var(--x, 50%) var(--y, 50%),
    transparent 0%,
    transparent 15%,
    rgba(0, 0, 0, 0.1) 30%,
    rgba(0, 0, 0, 0.22) 45%,
    rgba(0, 0, 0, 0.35) 60%,
    rgba(0, 0, 0, 0.5) 75%,
    rgba(0, 0, 0, 0.68) 88%,
    #fff 100%
  );
  mask-image: radial-gradient(
    circle var(--r, 300px) at var(--x, 50%) var(--y, 50%),
    transparent 0%,
    transparent 15%,
    rgba(0, 0, 0, 0.1) 30%,
    rgba(0, 0, 0, 0.22) 45%,
    rgba(0, 0, 0, 0.35) 60%,
    rgba(0, 0, 0, 0.5) 75%,
    rgba(0, 0, 0, 0.68) 88%,
    #fff 100%
  );
}
.chroma-grid-fade {
  z-index: 4;
  opacity: 1;
  -webkit-mask-image: radial-gradient(
    circle var(--r, 300px) at var(--x, 50%) var(--y, 50%),
    #fff 0%,
    #fff 15%,
    rgba(255, 255, 255, 0.9) 30%,
    rgba(255, 255, 255, 0.78) 45%,
    rgba(255, 255, 255, 0.65) 60%,
    rgba(255, 255, 255, 0.5) 75%,
    rgba(255, 255, 255, 0.32) 88%,
    transparent 100%
  );
  mask-image: radial-gradient(
    circle var(--r, 300px) at var(--x, 50%) var(--y, 50%),
    #fff 0%,
    #fff 15%,
    rgba(255, 255, 255, 0.9) 30%,
    rgba(255, 255, 255, 0.78) 45%,
    rgba(255, 255, 255, 0.65) 60%,
    rgba(255, 255, 255, 0.5) 75%,
    rgba(255, 255, 255, 0.32) 88%,
    transparent 100%
  );
}

@media (prefers-reduced-motion: reduce) {
  .chroma-card,
  .chroma-card-spotlight {
    transition: none;
  }
  .chroma-grid-fade {
    transition: none !important;
  }
}

/* Layar sentuh gak punya hover/pointermove yang berarti -- daripada
   grid-nya keliatan redup permanen (karena --x/--y gak pernah di-update
   dan fade gak pernah di-animate ke 0), spotlight seluruh grid dimatiin
   total di touch device; spotlight per-kartu (:active) tetap jalan. */
@media (hover: none) {
  .chroma-grid-mask,
  .chroma-grid-fade {
    display: none;
  }
  .chroma-card:active .chroma-card-spotlight {
    opacity: 1;
  }
}

/* ===== Folder Preview Modal ===== */
.folder-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  visibility: hidden;
  opacity: 0;
  transition:
    opacity 0.25s ease,
    visibility 0.25s ease;
}
.folder-modal.is-open {
  visibility: visible;
  opacity: 1;
}
.folder-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(8, 14, 16, 0.82);
}
.folder-modal-panel {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 880px;
  max-height: 85vh;
  overflow-y: auto;
  border-radius: 1.25rem;
  padding: 2rem;
  transform: scale(0.92) translateY(12px);
  transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.folder-modal.is-open .folder-modal-panel {
  transform: scale(1) translateY(0);
}
.folder-modal-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  border: 1px solid var(--surface-border);
  color: #e8f1f2;
  cursor: pointer;
  transition: all 0.25s ease;
}
.folder-modal-close:hover {
  background: #5e4534;
  border-color: #fe7e3c;
  transform: rotate(90deg);
}
.folder-modal-title {
  font-size: 1.4rem;
  font-weight: 800;
  color: #fff;
  margin-bottom: 1.5rem;
  padding-right: 2.5rem;
}
.folder-modal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
}
.folder-modal-item {
  margin: 0;
  border-radius: 0.75rem;
  overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--surface-border);
  display: flex;
  align-items: center;
  justify-content: center;
}
.folder-modal-item img {
  width: 100%;
  height: auto;
  /* Rasio asli foto ditampilkan penuh di sini, gak di-crop sama sekali */
  object-fit: contain;
  display: block;
}

/* Kontainer galeri foto project: Stage = foto besar yang lagi dipilih
   (crossfade GSAP tiap ganti), Strip = deretan thumbnail di bawahnya
   yang bisa di-scroll horizontal (native) & diklik buat ganti foto. */
.folder-modal-stage {
  position: relative;
  width: 100%;
  height: min(46vh, 400px);
  min-height: 240px;
  border-radius: 0.75rem;
  overflow: hidden;
  background: #0b1416;
  margin-bottom: 0.85rem;
}
.folder-modal-stage-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  opacity: 0;
}
.folder-modal-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(232, 241, 242, 0.4);
  font-size: 0.9rem;
  text-align: center;
  padding: 1rem;
}
.folder-modal-stage::before {
  content: "Menyiapkan galeri…";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(232, 241, 242, 0.4);
  font-size: 0.85rem;
  pointer-events: none;
}
.folder-modal-stage.is-ready::before {
  content: none;
}

.folder-modal-strip {
  position: relative;
  width: 100%;
  height: 96px;
  border-radius: 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.5rem;
  outline: none;
  scroll-behavior: smooth;
  background: var(--surface-2);
  border: 1px solid var(--surface-border);
}
.folder-modal-thumb {
  height: 100%;
  aspect-ratio: 1;
  flex: 0 0 auto;
  border-radius: 0.55rem;
  object-fit: cover;
  cursor: pointer;
  box-sizing: border-box;
  border: 2px solid transparent;
  opacity: 0.55;
  filter: grayscale(0.5);
  transition:
    border-color 0.25s ease,
    opacity 0.25s ease,
    filter 0.25s ease,
    transform 0.25s ease;
}
.folder-modal-thumb:hover {
  opacity: 0.85;
  transform: translateY(-2px);
}
.folder-modal-thumb.is-active {
  opacity: 1;
  filter: grayscale(0);
  border-color: rgba(254, 126, 60, 0.9);
  box-shadow: 0 0 14px rgba(254, 126, 60, 0.35);
}
.folder-modal-strip:focus-visible {
  box-shadow: 0 0 0 2px rgba(254, 126, 60, 0.6);
}
.folder-modal-strip::before {
  content: "Menyiapkan galeri…";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(232, 241, 242, 0.4);
  font-size: 0.8rem;
  pointer-events: none;
}
.folder-modal-strip.is-ready::before {
  content: none;
}

/* ===== Search Modal ===== */
.search-modal-panel {
  max-width: 480px;
  padding: 1.75rem;
}
.search-input-wrap {
  position: relative;
  margin-bottom: 0.75rem;
}
.search-input-icon {
  position: absolute;
  left: 0.9rem;
  top: 50%;
  transform: translateY(-50%);
  color: rgba(232, 241, 242, 0.4);
  font-size: 20px;
  pointer-events: none;
}
#searchInput {
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--surface-border);
  border-radius: 0.75rem;
  padding: 0.7rem 1rem 0.7rem 2.5rem;
  color: #e8f1f2;
  font-size: 0.95rem;
}
#searchInput::placeholder {
  color: rgba(232, 241, 242, 0.35);
}
.search-results {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 320px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.search-result-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  text-align: left;
  padding: 0.65rem 0.85rem;
  border-radius: 0.65rem;
  background: transparent;
  border: 1px solid transparent;
  color: #e8f1f2;
  cursor: pointer;
  transition:
    background 0.2s ease,
    border-color 0.2s ease;
}
.search-result-item:hover,
.search-result-item.is-active {
  background: #3e3932;
  border-color: #8c5536;
}
.search-result-item .material-symbols-outlined {
  font-size: 18px;
  color: rgba(254, 126, 60, 0.9);
  flex-shrink: 0;
}
.search-result-text {
  display: flex;
  flex-direction: column;
}
.search-result-label {
  font-size: 0.9rem;
  font-weight: 700;
}
.search-result-group {
  font-size: 0.75rem;
  color: rgba(232, 241, 242, 0.45);
}
.search-empty {
  text-align: center;
  padding: 1rem 0;
  color: rgba(232, 241, 242, 0.4);
  font-size: 0.85rem;
}

/* Glow blur di dalam tiap pricing card, nyala pas di-hover */
.pricing-card {
  isolation: isolate;
  transition:
    transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),
    border-color 0.35s ease,
    box-shadow 0.35s ease;
}
.pricing-card:hover {
  transform: translateY(-10px) scale(1.02);
}
.card-glow {
  position: absolute;
  inset: -20%;
  z-index: 0;
  opacity: 0;
  filter: blur(42px);
  background-size: 300% 300%;
  animation: cardGlowShift 8s ease infinite;
  transition: opacity 0.35s ease;
  pointer-events: none;
}
.pricing-card:hover .card-glow {
  opacity: 0.7;
}
@keyframes cardGlowShift {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}
.card-glow-purple {
  background-image: linear-gradient(45deg, #fe7e3c, #e4201b);
}
.card-glow-orange {
  background-image: linear-gradient(45deg, #38b2c1, #0e6873);
}
.card-glow-mixed {
  background-image: linear-gradient(45deg, #dcb5a8, #fe7e3c);
}

/* ==========================================================================
   Services — daftar harga (satu layanan per baris)
   Menggantikan 4 card kembar yang tinggi. Tiap baris: judul + deskripsi
   satu-dua baris | catatan kecil | harga | tombol. Baris "Best Seller"
   ditandai garis oranye di kiri + tombol oranye solid.
   Count-up harga tetap pakai .psc-amount[data-count-to] (script.js).
   ========================================================================== */
#services {
  --svc-line: rgba(255, 255, 255, 0.14);
  --svc-accent: #fe7e3c;
  font-family: "Inter Tight", "Plus Jakarta Sans", sans-serif;
}
#services h2 {
  text-wrap: balance; /* judul di HP gak menyisakan 1 kata sendirian */
}
.svc-sub {
  margin: 0.75rem 0 0;
  font-size: 0.95rem;
  font-weight: 500;
  color: rgba(232, 241, 242, 0.68);
}

.svc-list {
  max-width: 64rem;
  margin: 0 auto;
  border-top: 1px solid var(--svc-line);
}
.svc {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 12.5rem 9.5rem 10.5rem;
  grid-template-areas: "main meta price cta";
  align-items: center;
  gap: 0.75rem 1.5rem;
  padding: 1.2rem 1.25rem;
  border-bottom: 1px solid var(--svc-line);
  transition: background 0.25s ease;
}
.svc::before {
  content: "";
  position: absolute;
  left: 0;
  top: -1px;
  bottom: -1px;
  width: 3px;
  background: var(--svc-accent);
  transform: scaleY(0);
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.svc:hover {
  background: rgba(255, 255, 255, 0.04);
}
.svc:hover::before,
.svc.is-popular::before {
  transform: scaleY(1);
}

.svc-main {
  grid-area: main;
  min-width: 0;
}
.svc-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  margin: 0;
  font-size: 1.4rem;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: #fff;
}
.svc-badge {
  padding: 0.2rem 0.65rem;
  border-radius: 9999px;
  background: var(--svc-accent);
  color: #0f1b1e;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0;
  line-height: 1.3;
}
.svc-desc {
  max-width: 34rem;
  margin: 0.4rem 0 0;
  font-size: 0.88rem;
  font-weight: 500;
  line-height: 1.5;
  color: rgba(232, 241, 242, 0.7);
}

.svc-meta {
  grid-area: meta;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.85rem;
  font-weight: 500;
  line-height: 1.35;
  color: rgba(232, 241, 242, 0.82);
}
.svc-meta .material-symbols-outlined {
  flex-shrink: 0;
  font-size: 1.2rem;
  color: var(--svc-accent);
}

.svc-price {
  grid-area: price;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
}
.psc-currency,
.psc-amount,
.psc-unit {
  font-size: 2.25rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.svc-note {
  flex-basis: 100%;
  margin-top: 0.35rem;
  font-size: 0.74rem;
  font-weight: 500;
  color: rgba(232, 241, 242, 0.6);
}

.svc-cta {
  grid-area: cta;
  justify-self: end;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.75rem 1.15rem;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 9999px;
  color: #fff;
  font-size: 0.85rem;
  font-weight: 700;
  white-space: nowrap;
  text-decoration: none;
  transition:
    background 0.2s ease,
    border-color 0.2s ease,
    color 0.2s ease;
}
.svc-cta .material-symbols-outlined {
  font-size: 1.1rem;
  transition: transform 0.25s ease;
}
.svc-cta:hover,
.svc-cta:focus-visible {
  background: var(--svc-accent);
  border-color: var(--svc-accent);
  color: #0f1b1e;
}
.svc-cta:hover .material-symbols-outlined {
  transform: translate(2px, -2px);
}
.svc.is-popular .svc-cta {
  background: var(--svc-accent);
  border-color: var(--svc-accent);
  color: #0f1b1e;
}
.svc.is-popular .svc-cta:hover,
.svc.is-popular .svc-cta:focus-visible {
  background: #ffaa80;
  border-color: #ffaa80;
}
.svc-cta:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

/* Tablet: harga & tombol pindah ke kanan, catatan turun di bawah deskripsi */
@media (max-width: 899px) {
  .svc {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "main price"
      "meta cta";
    padding: 1.25rem 1rem;
  }
  .svc-price {
    justify-self: end;
    text-align: right;
    justify-content: flex-end;
  }
}
/* HP: satu kolom; harga di kiri, tombol di kanan pada baris yang sama */
@media (max-width: 560px) {
  .svc {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "main main"
      "meta meta"
      "price cta";
    gap: 0.6rem 1rem;
    padding: 1.15rem 0.75rem;
  }
  .svc-title {
    font-size: 1.25rem;
  }
  .svc-price {
    justify-self: start;
    text-align: left;
    justify-content: flex-start;
    margin-top: 0.4rem;
  }
  .psc-currency,
  .psc-amount,
  .psc-unit {
    font-size: 1.75rem;
  }
}

/* ===== Nav lang/theme toggle buttons: kecilin transisi ikon ===== */
#themeToggleIcon {
  transition: transform 0.3s ease;
}
#themeToggle:active #themeToggleIcon {
  transform: rotate(20deg);
}
#langToggleLabel {
  min-width: 1.4em;
  text-align: center;
}

/* ===== Mobile Nav Menu (garis 3 / hamburger) =====
   Dropdown glass panel yang muncul di bawah navbar saat tombol
   hamburger di-tap. Di-animasikan lewat max-height + opacity biar
   transisinya halus tanpa perlu JS animation library. */
.mobile-menu {
  overflow: hidden;
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  transition:
    max-height 0.35s cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 0.25s ease,
    margin-top 0.35s ease;
}
.mobile-menu.is-open {
  max-height: 28rem;
  opacity: 1;
  margin-top: 0.75rem;
}
.mobile-menu-panel {
  display: flex;
  flex-direction: column;
  padding: 0.9rem;
  border-radius: 1.5rem;
  gap: 0.25rem;
}
.mobile-nav-link {
  display: block;
  width: 100%;
  padding: 0.75rem 1rem;
  border-radius: 0.9rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: rgba(232, 241, 242, 0.75);
  transition:
    background 0.2s ease,
    color 0.2s ease;
}
.mobile-nav-link:hover,
.mobile-nav-link.active {
  background: var(--surface-2);
  color: #fff;
}
.mobile-nav-cta {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: 0.4rem;
  padding: 0.8rem 1rem;
  border-radius: 0.9rem;
  background: #fe7e3c;
  color: #0f1b1e;
  font-size: 0.9rem;
  font-weight: 700;
}
#mobileMenuToggleIcon {
  transition: transform 0.25s ease;
}
#mobileMenuToggle[aria-expanded="true"] #mobileMenuToggleIcon {
  transform: rotate(90deg);
}

/* ===== Perbaikan tambahan buat layar HP kecil (<=480px) =====
   Ngurangin padding modal & memastikan gak ada elemen yang
   kepotong / tumpang tindih di layar sempit. */
@media (max-width: 480px) {
  .folder-modal {
    padding: 0.85rem;
  }
  .folder-modal-panel {
    padding: 1.25rem;
    border-radius: 1rem;
  }
  .folder-modal-title {
    font-size: 1.15rem;
    padding-right: 2rem;
  }
  .search-modal-panel {
    padding: 1.25rem;
  }
  .folder-modal-stage {
    height: min(38vh, 300px);
    min-height: 200px;
  }
  .folder-modal-strip {
    height: 78px;
  }
}

/* Pastikan navbar gak pernah lebih lebar dari viewport di HP super kecil */
@media (max-width: 360px) {
  nav .glass {
    padding-left: 0.75rem;
    padding-right: 0.75rem;
  }
}

/* ===== Anti-navbar-kepanjangan di HP =====
   Tailwind CDN nge-generate utility class (termasuk "hidden md:flex")
   secara runtime, jadi ada jeda dimana class itu belum "nyala" —
   kalau pas jeda itu ukurannya kepepet/koneksi lambat, menu desktop
   bisa numpuk gak keitung lebarnya dan bikin pill navbar meluber ke
   luar layar (harus di-zoom out atau digeser buat lihat semuanya).
   Baris di bawah ini CSS murni (gak nunggu Tailwind sama sekali) yang
   MEMAKSA menu itu selalu ke-hide di layar HP. (Tombol search & Hire
   Me sudah dihapus total dari HTML, jadi gak perlu ditarget lagi.) */
@media (max-width: 767px) {
  nav .glass > div.md\:flex {
    display: none !important;
  }
}
@media (min-width: 768px) {
  nav #mobileMenuToggle {
    display: none !important;
  }
}
nav {
  max-width: 100vw;
}

/* Kunci ukuran logo pakai CSS biasa (bukan class Tailwind w-9 h-9),
   supaya gambar logo GAK PERNAH bisa nongol dalam ukuran aslinya
   (yang jauh lebih besar dari 36px) walau Tailwind lagi lambat/belum
   sempat kebaca duluan — ini penyebab pill navbar ikut "membengkak"
   dan nutupin konten di bawahnya. */
.nav-logo-img {
  width: 2.25rem !important;
  height: 2.25rem !important;
  object-fit: cover;
  flex-shrink: 0;
  display: block;
}

/* Jaring pengaman terakhir: pill navbar-nya sendiri gak boleh lebih
   lebar ATAU lebih tinggi dari batas wajar, apapun penyebabnya. Cuma
   ditarget ke pill utama (.nav-pill), BUKAN ke semua ".glass" di
   dalam nav, biar panel dropdown menu mobile (yang juga pakai class
   "glass") gak ikut kepotong. */
.nav-pill {
  max-width: 100%;
  max-height: 3.75rem;
  overflow: hidden;
}

/* ===== Permukaan solid =====
   Tidak ada backdrop-filter di mana pun. Semua kartu/panel (navbar,
   dropdown mobile, modal, popup) pakai warna solid 100% opaque dari
   variabel --surface / --surface-2 di atas. */
.glass,
.rt-card,
.gm-mini-card {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.mobile-menu-panel.glass,
.folder-modal-panel.glass {
  background: var(--surface);
}

/* Navbar: gradasi oren (bukan solid --surface kaya panel lain), biar
   jadi aksen paling nyolok di atas halaman. Grup link, tombol bahasa
   & menu mobile tetep pakai bg gelap sendiri (bg-[#233c42] inline di
   HTML) jadi ngambang kontras di atas gradasinya. */
.nav-pill.glass {
  background: linear-gradient(115deg, #ffb066 0%, #fe7e3c 45%, #e4201b 100%);
  border-color: transparent;
}

/* Elemen yang ngambang DI DALAM navbar (grup link, tombol bahasa,
   tombol menu mobile) sengaja dikasih warna gelap HANGAT sendiri
   (bukan biru/teal kaya --surface-2 yang dipakai panel lain), biar
   nyambung sama gradasi oren navbar-nya, gak keliatan nyasar. */
.nav-pill-inset {
  background: #2a1c16;
  border: 1px solid rgba(255, 255, 255, 0.12);
  transition: background 0.25s ease;
}
.nav-pill-inset:hover {
  background: #3c2820;
}

/* Isolasi paint: kasih tau browser isi kartu gak pernah "bocor" keluar
   kotaknya, jadi pas ada perubahan di dalam satu kartu, dia gak perlu
   ngitung ulang area di luarnya. */
.rt-card,
.gm-mini-card,
.pricing-card {
  contain: paint;
}

/* ===== Tombol aksen: flat & solid, tanpa gradient glossy ===== */
.lg-btn-primary,
.lg-btn-secondary,
.lg-btn-ghost {
  transition:
    transform 0.25s ease,
    filter 0.25s ease;
}
.lg-btn-primary {
  background: #fe7e3c;
  color: #0f1b1e;
  border: none;
}
.lg-btn-secondary {
  background: var(--surface-2);
  color: #e8f1f2;
  border: 1px solid var(--surface-border);
}
.lg-btn-ghost {
  background: transparent;
  color: #e8f1f2;
  border: 1px solid rgba(255, 255, 255, 0.18);
}
.lg-btn-primary:hover,
.lg-btn-secondary:hover,
.lg-btn-ghost:hover {
  transform: translateY(-2px);
  filter: brightness(1.1);
}
.lg-btn-primary:active,
.lg-btn-secondary:active,
.lg-btn-ghost:active {
  transform: translateY(0);
  filter: brightness(0.95);
}

/* Ring ikon sosial: outline polos, ganti ring conic pelangi berputar. */
.lg-icon-ring {
  background: var(--surface-2);
  border: 1px solid var(--surface-border);
}

/* ==========================================================================
   Skills & Toolkit -- daftar per kelompok kerja (tanpa kotak / background
   per ikon). Judul kelompok di kiri, ikon + nama alat mengalir di kanan,
   dipisah garis tipis antar kelompok.
   ========================================================================== */

.skills-list {
  max-width: 62rem;
  margin: 0 auto;
}

.skill-group {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: 1.25rem 2.5rem;
  align-items: center;
  padding: 1.6rem 0;
  border-top: 1px solid rgba(246, 239, 232, 0.12);
}
.skill-group:last-child {
  border-bottom: 1px solid rgba(246, 239, 232, 0.12);
}

.skill-group-title {
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: #fff;
}

.skill-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 1.1rem 2rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.skill-tool {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.skill-tool img {
  width: 40px;
  height: 40px;
  object-fit: contain;
  flex: none;
}

.skill-name {
  font-size: 0.95rem;
  font-weight: 600;
  color: rgba(232, 241, 242, 0.85);
  line-height: 1.2;
  transition: color 0.2s ease;
}
.skill-tool:hover .skill-name {
  color: var(--primary-light, #ffaa80);
}

@media (max-width: 720px) {
  .skill-group {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    padding: 1.3rem 0;
  }
  .skill-tools {
    gap: 1rem 1.5rem;
  }
  .skill-tool img {
    width: 36px;
    height: 36px;
  }
}

/* ==========================================================================
   Background per section
   Tiap section punya gradasi sendiri dari palet yang sama (Burnt Orange,
   Lust, Copper, Blue Lagoon, Black Pearl), dibuat tetap GELAP supaya kartu
   solid & teks di atasnya tetap kontras. Semua statis (tanpa animasi dan
   tanpa background-attachment: fixed), jadi ringan di HP.
   Ubah angka alpha (0.xx) di tiap rgba() untuk mengatur kuat-lemahnya glow.
   ========================================================================== */

/* Hero — background krem ada di blok "Hero" paling bawah file ini. */

/* Services — Blue Lagoon: teal dalam, glow lagoon di area judul */
#services {
  background:
    radial-gradient(ellipse 60% 36% at 50% 22%, rgba(14, 104, 115, 0.38) 0%, transparent 70%),
    radial-gradient(ellipse 40% 30% at 95% 80%, rgba(56, 178, 193, 0.12) 0%, transparent 70%),
    linear-gradient(200deg, #071c21 0%, #0a2a31 50%, #06181c 100%);
}

/* Projects — Copper: cokelat tembaga dengan glow oranye dan copper bergantian */
#projects {
  background:
    radial-gradient(ellipse 70% 10% at 10% 12%, rgba(254, 126, 60, 0.16) 0%, transparent 70%),
    radial-gradient(ellipse 70% 10% at 92% 34%, rgba(97, 65, 60, 0.55) 0%, transparent 70%),
    radial-gradient(ellipse 70% 10% at 8% 58%, rgba(254, 126, 60, 0.14) 0%, transparent 70%),
    radial-gradient(ellipse 70% 10% at 92% 84%, rgba(97, 65, 60, 0.55) 0%, transparent 70%),
    linear-gradient(170deg, #1a1210 0%, #2b1e1a 45%, #1c1513 100%);
}

/* Skills — Lust: maroon dalam dengan glow merah */
#skills {
  background:
    radial-gradient(ellipse 50% 50% at 16% 50%, rgba(228, 32, 27, 0.24) 0%, transparent 70%),
    radial-gradient(ellipse 42% 44% at 90% 42%, rgba(254, 126, 60, 0.13) 0%, transparent 70%),
    linear-gradient(135deg, #200c0e 0%, #2f1012 50%, #1a0e10 100%);
}

/* Experience — Diagonal teal ke copper */
#experience {
  background:
    radial-gradient(ellipse 50% 34% at 10% 22%, rgba(14, 104, 115, 0.32) 0%, transparent 70%),
    radial-gradient(ellipse 50% 34% at 92% 80%, rgba(97, 65, 60, 0.55) 0%, transparent 70%),
    linear-gradient(115deg, #06191d 0%, #0b2a30 40%, #2a1d19 100%);
}

/* Contact — Ember: gelap ke hangat, glow oranye seperti matahari terbenam di bawah */
#contact {
  background:
    radial-gradient(ellipse 60% 28% at 50% 84%, rgba(254, 126, 60, 0.32) 0%, transparent 70%),
    radial-gradient(ellipse 40% 26% at 10% 24%, rgba(228, 32, 27, 0.18) 0%, transparent 70%),
    radial-gradient(ellipse 36% 24% at 94% 16%, rgba(14, 104, 115, 0.16) 0%, transparent 70%),
    linear-gradient(180deg, #170f0d 0%, #2e1610 55%, #3a1a10 100%);
}

/* Mobile: section jadi sangat tinggi, jadi glow pakai ukuran piksel tetap
   (bukan persen) supaya bentuknya tetap membulat, tidak memanjang. */
@media (max-width: 767px) {
  #services {
    background:
      radial-gradient(ellipse 400px 360px at 50% 7%, rgba(14, 104, 115, 0.38) 0%, transparent 70%),
      radial-gradient(ellipse 300px 320px at 100% 55%, rgba(56, 178, 193, 0.12) 0%, transparent 70%),
      radial-gradient(ellipse 360px 320px at 0% 92%, rgba(14, 104, 115, 0.26) 0%, transparent 70%),
      linear-gradient(200deg, #071c21 0%, #0a2a31 50%, #06181c 100%);
  }
  #projects {
    background:
      radial-gradient(ellipse 360px 420px at 0% 8%, rgba(254, 126, 60, 0.16) 0%, transparent 70%),
      radial-gradient(ellipse 360px 420px at 100% 24%, rgba(97, 65, 60, 0.55) 0%, transparent 70%),
      radial-gradient(ellipse 360px 420px at 0% 42%, rgba(254, 126, 60, 0.14) 0%, transparent 70%),
      radial-gradient(ellipse 360px 420px at 100% 60%, rgba(97, 65, 60, 0.55) 0%, transparent 70%),
      radial-gradient(ellipse 360px 420px at 0% 78%, rgba(254, 126, 60, 0.14) 0%, transparent 70%),
      radial-gradient(ellipse 360px 420px at 100% 94%, rgba(97, 65, 60, 0.55) 0%, transparent 70%),
      linear-gradient(170deg, #1a1210 0%, #2b1e1a 45%, #1c1513 100%);
  }
  #skills {
    background:
      radial-gradient(ellipse 340px 300px at 10% 38%, rgba(228, 32, 27, 0.24) 0%, transparent 70%),
      radial-gradient(ellipse 280px 260px at 100% 74%, rgba(254, 126, 60, 0.13) 0%, transparent 70%),
      linear-gradient(135deg, #200c0e 0%, #2f1012 50%, #1a0e10 100%);
  }
  #experience {
    background:
      radial-gradient(ellipse 380px 360px at 0% 12%, rgba(14, 104, 115, 0.32) 0%, transparent 70%),
      radial-gradient(ellipse 380px 360px at 100% 52%, rgba(97, 65, 60, 0.55) 0%, transparent 70%),
      radial-gradient(ellipse 340px 320px at 6% 88%, rgba(14, 104, 115, 0.26) 0%, transparent 70%),
      linear-gradient(115deg, #06191d 0%, #0b2a30 40%, #2a1d19 100%);
  }
  #contact {
    background:
      radial-gradient(ellipse 420px 380px at 50% 88%, rgba(254, 126, 60, 0.32) 0%, transparent 70%),
      radial-gradient(ellipse 300px 300px at 0% 16%, rgba(228, 32, 27, 0.18) 0%, transparent 70%),
      radial-gradient(ellipse 280px 280px at 100% 8%, rgba(14, 104, 115, 0.16) 0%, transparent 70%),
      linear-gradient(180deg, #170f0d 0%, #2e1610 55%, #3a1a10 100%);
  }
}

/* ==========================================================================
   Hero — layout ala referensi "visual poetry", warna ikut tema situs
   (dark teal + burnt orange). Headline tebal rapat, foto blob dengan
   tombol bulat di lekukannya. Semua pakai CSS biasa (bukan utility Tailwind) supaya tampil
   benar dari frame pertama, gak nunggu Tailwind CDN selesai dimuat.

   Cara kerja posisi tombol: file foto (blob) itu kotak 1:1 dengan area
   transparan di sekelilingnya + 2 lekukan. Tombol diposisikan pakai persen
   dari kotak itu, jadi tetap pas di semua ukuran layar.
   ========================================================================== */
#home {
  --hero-dark: #0f1b1e; /* warna ikon di atas tombol oranye */
  --hero-ink: #ffffff;
  --hero-ink-soft: rgba(232, 241, 242, 0.78);
  --hero-line: rgba(255, 255, 255, 0.2);
  --hero-accent: #fe7e3c; /* primary */
  --hero-accent-light: #ffaa80; /* primary-light */
  position: relative;
  overflow: hidden;
  color: var(--hero-ink);
  font-family: "Inter Tight", "Plus Jakarta Sans", sans-serif;
  /* Sunset over lagoon (sama seperti hero sebelumnya): teal gelap ke umber
     hangat. Glow oranye sekarang di belakang foto (kanan), merah di
     pojok kanan-atas, lagoon di kiri-bawah. */
  background:
    radial-gradient(ellipse 42% 54% at 74% 52%, rgba(254, 126, 60, 0.3) 0%, transparent 70%),
    radial-gradient(ellipse 34% 34% at 98% 6%, rgba(228, 32, 27, 0.2) 0%, transparent 70%),
    radial-gradient(ellipse 40% 38% at 2% 88%, rgba(14, 104, 115, 0.32) 0%, transparent 70%),
    linear-gradient(160deg, #0f1b1e 0%, #14282c 45%, #2a1712 100%);
}
@media (max-width: 767px) {
  #home {
    background:
      radial-gradient(ellipse 340px 380px at 50% 44%, rgba(254, 126, 60, 0.3) 0%, transparent 70%),
      radial-gradient(ellipse 240px 260px at 96% 6%, rgba(228, 32, 27, 0.2) 0%, transparent 70%),
      radial-gradient(ellipse 300px 340px at 0% 92%, rgba(14, 104, 115, 0.3) 0%, transparent 70%),
      linear-gradient(160deg, #0f1b1e 0%, #14282c 45%, #2a1712 100%);
  }
}

.hero,
.hero *,
.hero *::before,
.hero *::after {
  box-sizing: border-box;
}
.hero {
  max-width: 96rem;
  margin: 0 auto;
  padding: 7.5rem 1.25rem 3.5rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "title"
    "stage"
    "body";
  row-gap: 1.75rem;
}

/* ----- Headline ----- */
.hero-title {
  grid-area: title;
  display: flex;
  flex-direction: column;
  margin: 0;
  font-weight: 800;
  text-transform: lowercase;
  letter-spacing: -0.055em;
  line-height: 0.86;
  /* "pramelda" (8 huruf) selalu muat di lebar kolomnya */
  font-size: clamp(3.5rem, calc((100vw - 2.5rem) / 4.3), 8rem);
}

/* ----- Foto blob ----- */
.hero-stage {
  grid-area: stage;
  position: relative;
  width: min(100%, 34rem);
  aspect-ratio: 1;
  justify-self: center;
}
.hero-slides {
  position: absolute;
  inset: 0;
  /* drop-shadow ngikutin bentuk blob (alpha), bukan kotaknya */
  filter: drop-shadow(0 24px 40px rgba(254, 126, 60, 0.32));
}
.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transform: scale(1.05);
  z-index: 0;
  transition:
    opacity 0.5s ease,
    transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}
/* Foto lama (.is-prev) tetap opaque di bawah selama foto baru
   (.is-active) fade-in di atasnya. */
.hero-slide.is-prev {
  opacity: 1;
  transform: none;
  z-index: 1;
}
.hero-slide.is-active {
  opacity: 1;
  transform: none;
  z-index: 2;
}

/* ----- Tombol bulat & thumbnail di lekukan foto ----- */
.hero-orb,
.hero-thumb {
  position: absolute;
  z-index: 3;
  width: 10.4%;
  min-width: 2.75rem;
  aspect-ratio: 1;
  border-radius: 50%;
  translate: -50% -50%;
}
.hero-orb {
  display: grid;
  place-items: center;
  background: var(--hero-accent);
  color: var(--hero-dark);
  text-decoration: none;
  transition:
    background 0.25s ease,
    color 0.25s ease,
    transform 0.25s ease;
}
.hero-orb .material-symbols-outlined {
  font-size: clamp(1.25rem, 2.6vw, 1.75rem);
  transition: transform 0.25s ease;
}
.hero-orb:hover {
  background: var(--hero-accent-light);
  transform: scale(1.06);
}
.hero-orb--go:hover .material-symbols-outlined {
  transform: translate(2px, -2px);
}
.hero-orb--cv:hover .material-symbols-outlined {
  transform: translateY(2px);
}
/* posisi = pusat lekukan, dalam persen dari kotak foto */
.hero-orb--cv {
  left: 89.2%;
  top: 8.4%;
}
.hero-thumb--1 {
  left: 11.9%;
  top: 67.5%;
}
.hero-thumb--2 {
  left: 11.9%;
  top: 78.8%;
}
.hero-orb--go {
  left: 11.9%;
  top: 90%;
}

.hero-thumb {
  padding: 0;
  border: 0;
  overflow: hidden;
  cursor: pointer;
  background: var(--surface-2, #233c42);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.22);
  transition:
    transform 0.25s ease,
    box-shadow 0.25s ease;
}
.hero-thumb:hover {
  transform: scale(1.08);
  box-shadow: 0 0 0 2px var(--hero-accent);
}
.hero-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.9); /* zoom ke wajah; titik fokus diatur lewat data-focus */
  pointer-events: none;
  transition: opacity 0.15s ease;
}

/* ----- Paragraf, sosial, stat ----- */
.hero-body {
  grid-area: body;
  align-self: end;
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}
.hero-desc {
  margin: 0;
  max-width: 24rem;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.5;
  color: rgba(232, 241, 242, 0.88);
}

.hero-social {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.hero-chip {
  flex-shrink: 0;
  display: block;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.65rem;
  line-height: 0;
}
.hero-chip img {
  display: block;
  width: 100%;
  height: 100%;
  transform: scale(var(--fit, 1));
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.hero-chip:hover img {
  transform: translateY(-3px) scale(calc(var(--fit, 1) * 1.08));
}
.hero-social-line {
  flex: 1;
  height: 1px;
  margin-left: 0.5rem;
  background: var(--hero-line);
}

.hero-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}
.hero-stat {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.hero-stat-num {
  font-size: clamp(2.9rem, 6.2vw, 4.4rem);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
}
.hero-stat-num sup {
  display: inline-block;
  vertical-align: top;
  margin-right: 0.06em;
  font-size: 0.42em;
  line-height: 1;
  color: var(--hero-accent);
}
.hero-stat-label {
  max-width: 14rem;
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--hero-ink-soft);
}

/* ----- Fokus keyboard (semua kontrol interaktif di hero) ----- */
.hero-orb:focus-visible,
.hero-thumb:focus-visible,
.hero-chip:focus-visible {
  outline: 2px solid var(--hero-accent);
  outline-offset: 3px;
}

/* ----- HP kecil: bulatan di lekukan mengecil mengikuti lebar foto ----- */
@media (max-width: 560px) {
  .hero-stage {
    width: 111.1%;
    justify-self: start;
    margin-left: -5.55%;
  }
  /* Thumbnail tetap tampil di HP kecil: ukuran ikut lebar foto (10.4%),
     min-width dilonggarkan supaya 3 bulatan muat di lekukan. */
  .hero-orb,
  .hero-thumb {
    min-width: 1.75rem;
  }
}

/* ----- Desktop / tablet lebar: 2 kolom ----- */
@media (min-width: 900px) {
  .hero {
    padding: 8.5rem 2.5rem 5rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    grid-template-areas:
      "title stage"
      "body  stage";
    column-gap: clamp(1.5rem, 3vw, 3rem);
    row-gap: 2rem;
  }
  .hero-title {
    font-size: clamp(5rem, calc((min(100vw, 96rem) - 7rem) / 8.3), 11rem);
  }
  /* Kotak foto dilebarkan sedikit & digeser ke kiri supaya blob-nya
     (yang punya margin transparan ~5%) pas mengisi kolom kanan. */
  .hero-stage {
    width: 111.1%;
    max-width: none;
    justify-self: start;
    align-self: center;
    margin-left: -5.55%;
  }
  .hero-desc {
    margin-left: auto;
    max-width: 20rem;
    font-size: 0.95rem;
    text-align: right;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero-slide,
  .hero-thumb img,
  .hero-orb,
  .hero-thumb {
    transition: none;
  }
}

/* ==========================================================================
   Hero — animasi teks (tiap elemen beda gerakan, satu urutan saat load)

     0 ms     headline  : huruf naik dari balik masker, satu-satu
     620 ms   paragraf  : fade + naik + blur hilang
     820 ms   chip      : pop membesar sambil muter, bergiliran
     1120 ms  garis     : memanjang dari kiri
     980 ms+  stat      : "+" berputar masuk, angka count-up, lalu label naik

   Kondisi awal (tersembunyi) HANYA aktif kalau <html> punya class
   .reveal-ready (dipasang di <head>: browser dukung IntersectionObserver &
   user gak minta reduced-motion). Class .hero-go dipasang script.js begitu
   font siap; tanpa JS / reduced-motion semua teks langsung tampil normal.
   ========================================================================== */

/* Masker per baris headline: overflow hidden + padding negatif-margin supaya
   ujung huruf (ascender "d" / "l", kaki "p") gak ikut terpotong. */
.hero-line {
  display: block;
  overflow: hidden;
  padding: 0.1em 0.06em 0.22em;
  margin: -0.1em -0.06em -0.22em;
}
.hero-char,
.hero-stat-val {
  display: inline-block;
}

/* --- headline --- */
.hero-line--2 {
  --base: 180ms;
}
.reveal-ready #home .hero-char {
  transform: translateY(140%) rotate(8deg);
  transform-origin: 0 100%;
  transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1)
    calc(var(--base, 0ms) + var(--i, 0) * 42ms);
}
.reveal-ready #home.hero-go .hero-char {
  transform: none;
}

/* --- paragraf --- */
.reveal-ready #home .hero-desc {
  opacity: 0;
  transform: translateY(16px);
  filter: blur(6px);
  transition:
    opacity 0.8s ease 620ms,
    transform 0.8s cubic-bezier(0.22, 1, 0.36, 1) 620ms,
    filter 0.8s ease 620ms;
}
.reveal-ready #home.hero-go .hero-desc {
  opacity: 1;
  transform: none;
  filter: none;
}

/* --- chip sosial + garis --- */
.reveal-ready #home .hero-chip {
  opacity: 0;
  transform: scale(0.4) rotate(-30deg);
  transition:
    transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1)
      calc(820ms + var(--i, 0) * 70ms),
    opacity 0.35s ease calc(820ms + var(--i, 0) * 70ms);
}
.reveal-ready #home.hero-go .hero-chip {
  opacity: 1;
  transform: none;
}
.reveal-ready #home .hero-social-line {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1) 1120ms;
}
.reveal-ready #home.hero-go .hero-social-line {
  transform: none;
}

/* --- stat: --s = urutan stat (0, 1); --b = kapan stat itu mulai --- */
.hero-stat {
  --b: calc(980ms + var(--s, 0) * 140ms);
}
.reveal-ready #home .hero-stat-num sup {
  opacity: 0;
  transform: rotate(-90deg) scale(0.3);
  transition:
    transform 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) var(--b),
    opacity 0.3s ease var(--b);
}
.reveal-ready #home .hero-stat-val {
  opacity: 0;
  transform: translateY(0.35em);
  transition:
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--b) + 80ms),
    opacity 0.5s ease calc(var(--b) + 80ms);
}
.reveal-ready #home .hero-stat-label {
  opacity: 0;
  transform: translateY(10px);
  transition:
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1) calc(var(--b) + 320ms),
    opacity 0.6s ease calc(var(--b) + 320ms);
}
.reveal-ready #home.hero-go .hero-stat-num sup,
.reveal-ready #home.hero-go .hero-stat-val,
.reveal-ready #home.hero-go .hero-stat-label {
  opacity: 1;
  transform: none;
}

/* --- headline: loop gelombang (jalan setelah animasi masuk selesai) ---
   Tiap huruf naik sedikit + berubah oranye saat gelombang lewat, lalu
   balik putih. Gelombang jalan dari huruf pertama baris 1 sampai huruf
   terakhir baris 2, terus jeda sebentar sebelum ulang.
   - Durasi satu siklus: 4.2s (angka setelah "hero-wave")
   - Jeda antar huruf: 80ms (dua kali muncul di bawah, samakan)
   - Baris 2 mulai setelah baris 1 selesai: --wave-base = jumlah huruf
     baris 1 x 80ms (nendar = 6 huruf -> 480ms). Kalau ganti nama,
     sesuaikan angka ini. */
.hero-line--2 {
  --wave-base: 480ms;
}
@keyframes hero-wave {
  0%,
  15%,
  100% {
    transform: none;
    color: var(--hero-ink);
  }
  7.5% {
    transform: translateY(-0.07em);
    color: var(--hero-accent);
  }
}
/* class .hero-loop dipasang script.js setelah intro selesai */
#home.hero-loop .hero-line {
  overflow: visible; /* masker gak dibutuhkan lagi, jadi ujung huruf gak mungkin terpotong */
}
#home.hero-loop .hero-char {
  animation: hero-wave 4.2s ease-in-out
    calc(var(--wave-base, 0ms) + var(--i, 0) * 80ms) infinite;
}
@media (prefers-reduced-motion: reduce) {
  #home.hero-loop .hero-char {
    animation: none;
  }
}

/* =========================================================================
   Featured Projects -- nav: 3 kartu cover (foto hasil kerja + nama kategori
   + jumlah karya). Klik = lompat ke kategori. Kartu yang kategorinya lagi
   tampil di layar dapet ring warna aksen (scroll-spy di script.js, class
   .is-active). Warna aksen dari --acc di tiap link.
   ========================================================================= */
.fp-nav {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  max-width: 72rem;
  margin: 0 auto 4.5rem;
}
@media (min-width: 720px) {
  .fp-nav {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.25rem;
  }
}
.fp-link {
  position: relative;
  display: block;
  aspect-ratio: 16 / 8;
  overflow: hidden;
  border-radius: 1.25rem;
  background: color-mix(in srgb, var(--acc) 18%, #1a2c30);
  color: #fff;
  text-decoration: none;
  box-shadow: 0 0 0 1px rgba(246, 239, 232, 0.1);
  transition: box-shadow 0.35s ease, transform 0.35s ease;
}
@media (min-width: 720px) {
  .fp-link {
    aspect-ratio: 4 / 5;
  }
}
.fp-cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
}
/* gradasi gelap di bawah biar teks tetap kebaca di foto apa pun */
.fp-link::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(12, 20, 22, 0.92) 0%,
    rgba(12, 20, 22, 0.45) 38%,
    rgba(12, 20, 22, 0) 65%
  );
  pointer-events: none;
}
.fp-info {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.1rem 1.25rem 1.2rem;
}
.fp-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.fp-name {
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: clamp(1.2rem, 2vw, 1.55rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
}
.fp-count {
  font-size: 0.85rem;
  color: rgba(246, 239, 232, 0.72);
}
.fp-arrow {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  font-size: 20px !important;
  color: #16130f;
  background: var(--acc);
  transition: transform 0.35s ease;
}
.fp-link:hover,
.fp-link.is-active {
  box-shadow: 0 0 0 2px var(--acc);
}
.fp-link:hover .fp-cover,
.fp-link.is-active .fp-cover {
  transform: scale(1.05);
}
.fp-link:hover .fp-arrow,
.fp-link.is-active .fp-arrow {
  transform: translateY(4px);
}
.fp-link:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .fp-cover,
  .fp-arrow,
  .fp-link {
    transition: none;
  }
}

/* =========================================================================
   Featured Projects nav + Skills -- v2 (dipasangkan dengan anime-sections.js)
   ========================================================================= */
.fp-cover {
  transform: translate3d(var(--px, 0px), var(--py, 0px), 0) scale(1.08);
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}
.fp-link:hover .fp-cover,
.fp-link.is-active .fp-cover {
  transform: translate3d(var(--px, 0px), var(--py, 0px), 0) scale(1.12);
}
.fp-cursor {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 60;
  pointer-events: none;
}
.fp-cursor span {
  display: block;
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  color: #16130f;
  font: 700 0.8rem "Plus Jakarta Sans", sans-serif;
  transform-origin: 0 0;
}
/* garis pemisah skills digambar oleh JS (kalau JS mati, border biasa tetap ada) */
.skills-list.has-rule .skill-group,
.skills-list.has-rule .skill-group:last-child {
  position: relative;
  border-top: 0;
  border-bottom: 0;
}
.skill-rule {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: rgba(246, 239, 232, 0.18);
  transform-origin: left;
}
.skill-rule--end {
  top: auto;
  bottom: 0;
}
.skill-tool img {
  will-change: transform;
}

/* =========================================================================
   Experience & Education -- timeline vertikal (pengganti stepper) + daftar
   sertifikat sticky. Dianimasikan oleh anime-sections.js (rail terisi
   mengikuti scroll, tiap entri terbuka sekali saat sampai).
   ========================================================================= */
.xp-layout {
  display: grid;
  gap: 3.5rem;
  max-width: 76rem;
  margin: 0 auto;
}
@media (min-width: 1024px) {
  .xp-layout {
    grid-template-columns: minmax(0, 1fr) 21rem;
    gap: 4.5rem;
    align-items: start;
  }
}
.xp-track {
  position: relative;
  --gutter: 3rem;
}
.xp-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.xp-rail {
  position: absolute;
  top: 1.5rem;
  bottom: 1.5rem;
  left: calc(var(--gutter) / 2 - 1px);
  width: 2px;
  background: rgba(246, 239, 232, 0.12);
}
.xp-rail-fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(#ffaa80, #fe7e3c);
  transform: scaleY(0);
  transform-origin: top;
}
.xp-item {
  display: grid;
  grid-template-columns: var(--gutter) minmax(0, 1fr);
  column-gap: 1.25rem;
  padding-bottom: 3.5rem;
}
.xp-item:last-child {
  padding-bottom: 0;
}
.xp-dot {
  grid-column: 1;
  grid-row: 1 / span 2;
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: var(--gutter);
  height: var(--gutter);
  border-radius: 50%;
  background: #0f1b1e;
  color: var(--acc);
  box-shadow: inset 0 0 0 2px rgba(246, 239, 232, 0.16);
  transition: background 0.4s ease, color 0.4s ease, box-shadow 0.4s ease;
}
.xp-dot .material-symbols-outlined {
  font-size: 22px;
}
.xp-item.is-lit .xp-dot {
  background: var(--acc);
  color: #16130f;
  box-shadow: inset 0 0 0 2px var(--acc);
}
.xp-year {
  grid-column: 2;
  align-self: center;
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: 1.1rem;
  color: var(--acc);
}
.xp-body {
  grid-column: 2;
  display: grid;
  gap: 1.25rem 2rem;
  padding-top: 0.5rem;
}
@media (min-width: 720px) {
  .xp-item {
    grid-template-columns: 5rem var(--gutter) minmax(0, 1fr);
    column-gap: 1.25rem;
  }
  .xp-track {
    --left: 6.25rem;
  }
  .xp-track .xp-rail {
    left: calc(6.25rem + var(--gutter) / 2 - 1px);
  }
  .xp-year {
    grid-column: 1;
    grid-row: 1;
    justify-self: end;
    font-size: clamp(1.4rem, 2.2vw, 1.9rem);
  }
  .xp-dot {
    grid-column: 2;
    grid-row: 1;
  }
  .xp-body {
    grid-column: 3;
    grid-row: 1;
    grid-template-columns: minmax(0, 1fr) 13rem;
    padding-top: 0.35rem;
  }
}
.xp-title {
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: clamp(1.3rem, 2.2vw, 1.85rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: #fff;
}
.xp-meta {
  margin-top: 0.4rem;
  font-weight: 700;
  font-size: 0.92rem;
  color: var(--acc);
}
.xp-desc {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
  max-width: 34rem;
  color: rgba(232, 241, 242, 0.72);
  font-size: 0.95rem;
  line-height: 1.55;
}
.xp-desc li {
  position: relative;
  padding-left: 1.1rem;
}
.xp-desc li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--acc);
}
.xp-media {
  align-self: start;
  overflow: hidden;
  border-radius: 1rem;
  aspect-ratio: 4 / 5;
  background: rgba(246, 239, 232, 0.06);
}
.xp-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
@media (max-width: 719px) {
  .xp-media {
    aspect-ratio: 16 / 10;
  }
}
/* sertifikat */
.xp-certs {
  padding-top: 0.25rem;
}
@media (min-width: 1024px) {
  .xp-certs {
    position: sticky;
    top: 7rem;
  }
}
.xp-certs-title {
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: 1.5rem;
  color: #fff;
  padding-bottom: 1rem;
  border-bottom: 1px solid rgba(246, 239, 232, 0.14);
}
.xp-certs-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.xp-cert {
  display: flex;
  gap: 1rem;
  align-items: center;
  padding: 1.1rem 0;
  border-bottom: 1px solid rgba(246, 239, 232, 0.14);
  color: inherit;
  text-decoration: none;
}
.xp-cert img {
  flex: none;
  width: 5.5rem;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 0.6rem;
  transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.xp-cert:hover img {
  transform: rotate(-3deg) scale(1.06);
}
.xp-cert-text {
  display: grid;
  gap: 0.2rem;
}
.xp-cert-name {
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.3;
  color: #fff;
  transition: color 0.2s ease;
}
.xp-cert:hover .xp-cert-name {
  color: #ffaa80;
}
.xp-cert-by {
  font-size: 0.82rem;
  color: rgba(232, 241, 242, 0.55);
}
.xp-cert:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .xp-cert img,
  .xp-dot {
    transition: none;
  }
}

/* =========================================================================
   Services -- v2: selebar navbar (95% / maks 2xl) dan setinggi satu layar
   di desktop. Judul besar di kiri, 4 baris layanan membagi sisa tinggi
   layar sama rata. Animasi masuk & garis "digambar" oleh anime-sections.js.
   ========================================================================= */
.svc-wrap {
  width: 95%;
  max-width: 96rem; /* = max-w-screen-2xl, sama dengan navbar */
  margin: 0 auto;
  padding: 6rem 0 3rem;
}
.svc-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  margin-bottom: 2rem;
}
#services .svc-h2 {
  margin: 0;
  font-size: clamp(2.4rem, 6.2vw, 6rem);
  font-weight: 800;
  line-height: 0.95;
  letter-spacing: -0.045em;
  color: #e8f1f2;
}
.svc-head .svc-sub {
  margin: 0 0 0.6rem;
  font-size: 1.05rem;
}
.svc-list.has-rule,
.svc-list.has-rule .svc {
  border-color: transparent;
}
.svc-rule {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: rgba(255, 255, 255, 0.2);
  transform-origin: left;
}
.svc-rule--end {
  top: auto;
  bottom: 0;
}
/* sorotan lembut mengikuti pointer di baris */
.svc::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(38rem circle at var(--mx, 50%) 50%, rgba(254, 126, 60, 0.14), transparent 65%);
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}
.svc:hover::after {
  opacity: 1;
}
.svc {
  isolation: isolate;
}
.svc:hover {
  background: transparent;
}
@media (min-width: 900px) {
  #services {
    min-height: 100svh;
    display: flex;
  }
  .svc-wrap {
    display: flex;
    flex-direction: column;
    min-height: 100svh;
  }
  .svc-list {
    flex: 1;
    display: flex;
    flex-direction: column;
    max-width: none;
    margin: 0;
  }
  .svc {
    flex: 1;
    min-height: 7rem;
    grid-template-columns: minmax(0, 1fr) 17rem 13rem 13.5rem;
    gap: 0.75rem 2rem;
    padding: 0.75rem 1.75rem;
  }
  .svc-title {
    font-size: clamp(1.7rem, 2.7vw, 2.8rem);
    letter-spacing: -0.035em;
    transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  }
  .svc:hover .svc-title {
    transform: translateX(0.6rem);
  }
  .svc-desc {
    font-size: 1rem;
    max-width: 38rem;
  }
  .svc-meta {
    font-size: 0.95rem;
  }
  .psc-currency,
  .psc-amount,
  .psc-unit {
    font-size: clamp(2.6rem, 4vw, 3.9rem);
  }
  .svc-cta {
    padding: 0.9rem 1.5rem;
    font-size: 0.95rem;
  }
}

/* =========================================================================
   Footer v2 -- CTA besar, kolom info, wordmark raksasa. Selebar navbar.
   Animasi masuk & tombol magnetik di anime-sections.js.
   ========================================================================= */
.ft {
  position: relative;
  z-index: 10;
  background: #0b1518;
  border-top: 1px solid rgba(246, 239, 232, 0.1);
  color: rgba(232, 241, 242, 0.72);
  overflow: hidden;
}
.ft-wrap {
  width: 95%;
  max-width: 96rem;
  margin: 0 auto;
  padding: 5rem 0 1.5rem;
}
.ft-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.75rem 3rem;
  padding-bottom: 4rem;
  border-bottom: 1px solid rgba(246, 239, 232, 0.14);
}
.ft-lead {
  margin: 0;
  max-width: 14ch;
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: clamp(2.2rem, 5.5vw, 5rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
  color: #fff;
}
.ft-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 1.15rem 2rem;
  border-radius: 999px;
  background: #fe7e3c;
  color: #16130f;
  font-weight: 800;
  font-size: 1.1rem;
  text-decoration: none;
  transition: background 0.25s ease;
}
.ft-btn:hover,
.ft-btn:focus-visible {
  background: #ffaa80;
}
.ft-btn:focus-visible,
.ft-link:focus-visible,
.ft-top:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 4px;
}
.ft-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2.5rem 2rem;
  padding: 3rem 0;
}
@media (min-width: 900px) {
  .ft-cols {
    grid-template-columns: 1.5fr 1fr 1fr 1fr;
    gap: 2rem 3rem;
  }
}
@media (max-width: 599px) {
  .ft-about {
    grid-column: 1 / -1;
  }
}
.ft-tag {
  margin: 0;
  max-width: 22rem;
  font-size: 1rem;
  line-height: 1.55;
}
.ft-status {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 1.1rem 0 0;
  font-size: 0.92rem;
  font-weight: 600;
  color: #fff;
}
.ft-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #4ade80;
  box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.55);
  animation: ft-pulse 2.2s ease-out infinite;
}
@keyframes ft-pulse {
  70%, 100% { box-shadow: 0 0 0 9px rgba(74, 222, 128, 0); }
}
.ft-h {
  margin: 0 0 1rem;
  font-size: 0.95rem;
  font-weight: 700;
  color: #ffaa80;
}
.ft-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}
.ft-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: rgba(232, 241, 242, 0.72);
  text-decoration: none;
  font-size: 1rem;
  transition: color 0.2s ease;
}
.ft-link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1px;
  background: #fe7e3c;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.ft-link:hover,
.ft-link:focus-visible {
  color: #fff;
}
.ft-link:hover::after,
.ft-link:focus-visible::after {
  transform: scaleX(1);
}
.ft-soc img {
  width: 20px;
  height: 20px;
  object-fit: contain;
}
.ft-clock {
  margin: 0;
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: clamp(2rem, 3.2vw, 3rem);
  letter-spacing: -0.02em;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.ft-mark {
  margin: 0;
  display: flex;
  justify-content: center;
  overflow: hidden;
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-stretch: 112%;
  font-weight: 900;
  font-size: 9vw; /* cadangan; ukuran pasnya dihitung ulang oleh anime-sections.js */
  line-height: 1;
  letter-spacing: -0.045em;
  white-space: pre;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.03));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  user-select: none;
}
.ft-ch {
  display: inline-block;
}
.ft-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(246, 239, 232, 0.14);
  font-size: 0.9rem;
}
.ft-bar p {
  margin: 0;
}
.ft-top {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: none;
  border: 0;
  color: rgba(232, 241, 242, 0.8);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  transition: color 0.2s ease;
}
.ft-top:hover {
  color: #ffaa80;
}
.ft-top .material-symbols-outlined {
  font-size: 1.1rem;
}
@media (prefers-reduced-motion: reduce) {
  .ft-dot { animation: none; }
}

/* =========================================================================
   Contact / Community Feedback -- v2: tanpa kartu kaca. Form berupa garis
   bawah (underline) yang "menyala" saat fokus, daftar komentar berupa thread
   terbuka. Selebar navbar. Animasi di anime-sections.js.
   ========================================================================= */
.cf-wrap {
  width: 95%;
  max-width: 96rem;
  margin: 0 auto;
  padding: 7rem 0 9rem;
}
.cf-h2 {
  margin: 0 0 4rem;
  font-family: "Archivo", "Plus Jakarta Sans", sans-serif;
  font-weight: 800;
  font-size: clamp(2.4rem, 6.2vw, 6rem);
  line-height: 0.95;
  letter-spacing: -0.04em;
  color: #fff;
  text-wrap: balance;
}
.cf-grid {
  display: grid;
  gap: 4rem;
}
@media (min-width: 960px) {
  .cf-grid {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
    gap: 6rem;
    align-items: start;
  }
}
.cf-h3 {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 800;
  color: #fff;
}
.cf-form {
  position: relative;
  margin-top: 2rem;
}
.cf-field {
  margin-bottom: 2rem;
}
.cf-labelrow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.3rem;
}
.cf-label {
  font-size: 0.92rem;
  font-weight: 700;
  color: #ffaa80;
}
.cf-count {
  font-size: 0.8rem;
  color: rgba(232, 241, 242, 0.45);
  font-variant-numeric: tabular-nums;
}
.cf-inputwrap {
  position: relative;
}
.cf-input {
  display: block;
  width: 100%;
  padding: 0.6rem 0;
  border: 0;
  border-bottom: 1px solid rgba(246, 239, 232, 0.28);
  border-radius: 0;
  background: transparent;
  color: #fff;
  font: inherit;
  font-size: 1.25rem;
  outline: none;
  resize: vertical;
}
.cf-input::placeholder {
  color: rgba(232, 241, 242, 0.3);
}
.cf-line {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: #fe7e3c;
  transform: scaleX(0);
  transform-origin: left;
  pointer-events: none;
}
#commentRatingGroup {
  padding-top: 0.25rem;
}
#commentRatingGroup label {
  font-size: 2.1rem !important;
  display: inline-block;
}
.cf-submit {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 1.05rem 2rem;
  border: 0;
  border-radius: 999px;
  background: #fe7e3c;
  color: #16130f;
  font: inherit;
  font-weight: 800;
  font-size: 1.05rem;
  cursor: pointer;
  transition: background 0.25s ease, transform 0.15s ease;
}
.cf-submit:hover {
  background: #ffaa80;
}
.cf-submit:active {
  transform: scale(0.96);
}
.cf-submit:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.cf-submit:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 4px;
}
.cf-status {
  min-height: 1.2em;
  margin: 1rem 0 0;
  font-size: 0.9rem;
  color: rgba(232, 241, 242, 0.6);
}
.cf-listhead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem 1rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid rgba(246, 239, 232, 0.2);
}
.cf-list {
  display: flex;
  flex-direction: column;
}
.cf-list > p {
  margin: 0;
  padding: 2rem 0;
  font-size: 1.3rem !important;
  line-height: 1.35;
  color: rgba(232, 241, 242, 0.5) !important;
  max-width: 22ch;
}
.cf-list .comment-row {
  padding: 1.4rem 0;
  border-bottom: 1px solid rgba(246, 239, 232, 0.14);
}
