/* ================================================================
   AnabhiDev-DELLAWEB — Della Spa Production Website
   CSS3 · Custom Properties · Grid · clamp() · Google Fonts
   Development · Anabhi Dev
   Version   : 1.7
   Generated : 23 August 2026, 22:53:36
   ----------------------------------------------------------------
   Single palette (light only). Dark mode tidak dipakai —
   keputusan klien 20 Agustus 2026 (company profile, bukan web app).
   ================================================================ */


/* ================================================================
   1. DESIGN TOKENS — satu sumber kebenaran untuk seluruh warna.
   DILARANG menulis hex code di luar blok ini.
   ================================================================ */
:root,
[data-theme="light"] {

  /* Ramp taupe diturunkan dari isi lingkaran logo #BDA894 */
  --taupe-50:  #FAF7F4;
  --taupe-100: #F2ECE6;
  --taupe-200: #E5DBD1;
  --taupe-300: #D3C4B6;
  --taupe-400: #BDA894;
  --taupe-500: #A38D7B;
  --taupe-600: #85705F;   /* HANYA teks besar / UI — 4.39:1 */
  --taupe-700: #6B5849;
  --taupe-800: #4A3D33;
  --espresso:  #2A1D14;   /* diturunkan dari stroke logo */

  --canvas:       var(--taupe-50);
  --surface:      #FFFFFF;
  --surface-soft: var(--taupe-100);
  --surface-tint: var(--taupe-200);
  --surface-deep: var(--taupe-800);

  --ink:           var(--espresso);   /* 15.32:1 */
  --body-strong:   #4A3D33;           /*  9.81:1 */
  --body:          #57483C;           /*  8.21:1 */
  --muted:         #6B5849;           /*  6.31:1 */
  --on-dark:       #F5EEE8;
  --on-dark-muted: #C4B2A3;

  --brand:      #6B5849;   /* teks putih di atasnya 6.74:1 */
  --brand-hover:#57483C;   /* 8.76:1 */
  --brand-soft: var(--taupe-400);
  --gold-text:  #7D5F35;   /* 5.53:1 — boleh untuk teks */
  --gold-line:  #B99465;   /* 2.63:1 — ORNAMEN SAJA */

  --rule:   rgba(42, 29, 20, .14);
  --rule-2: rgba(42, 29, 20, .08);
  --focus:  var(--brand);

  --shadow-sm: 0 1px 2px rgba(42,29,20,.05);
  --shadow:    0 1px 2px rgba(42,29,20,.05), 0 10px 30px rgba(42,29,20,.07);
  --shadow-lg: 0 2px 4px rgba(42,29,20,.06), 0 22px 50px rgba(42,29,20,.11);

  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px; --sp-5:32px;
  --sp-6:48px; --sp-7:64px; --sp-8:80px; --sp-9:96px; --sp-10:128px;

  --r-sm:6px; --r-md:12px; --r-lg:20px; --r-pill:999px;

  --dur-fast:160ms; --dur-base:260ms; --dur-slow:520ms; --dur-hero:900ms;
  --ease: cubic-bezier(.22,.61,.36,1);

  /* ---- TIPOGRAFI ----
     Untuk ganti display font: ubah --font-display saja.
     Alternatif yang sudah diuji: "Marcellus", "Prata", "Tenor Sans" */
  --font-display: "Marcellus", Georgia, "Times New Roman", serif;
  --font-ui:      "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Skala dinaikkan dari v1.2 — kontras ukuran yang terlalu rendah
     adalah penyebab utama halaman terasa datar */
  --fs-hero:    clamp(2.9rem, 8.5vw, 5.4rem);
  --fs-h1:      clamp(2.2rem, 5.6vw, 3.6rem);
  --fs-h2:      clamp(1.9rem, 4.4vw, 3rem);
  --fs-h3:      clamp(1.2rem, 2.4vw, 1.5rem);
  --fs-stat:    clamp(2.4rem, 6vw, 3.6rem);
  --fs-lead:    clamp(1.05rem, 2vw, 1.25rem);
  --fs-body:    1rem;
  --fs-sm:      .875rem;
  --fs-xs:      .8125rem;
  --fs-eyebrow: .75rem;
  --fs-price:   clamp(1.1rem, 2.2vw, 1.35rem);

  --header-h: 72px;
  --gutter:   clamp(20px, 5vw, 72px);
  --sec-pad:  clamp(72px, 10vw, 144px);

  --z-float:90; --z-header:100; --z-overlay:200; --z-drawer:210; --z-consent:250;

  color-scheme: light;   /* cegah browser auto-darken form & scrollbar */
}


/* ================================================================
   2. RESET
   ================================================================ */
*, *::before, *::after { box-sizing:border-box; margin:0; padding:0; }
html { scroll-behavior:smooth; scroll-padding-top:calc(var(--header-h) + 16px); }
html, body { overflow-x:hidden; max-width:100%; }   /* SOP §1 — html DAN body */

body {
  background: var(--canvas);
  color: var(--body);
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  position: relative;
}

/* Tekstur kertas — menghilangkan kesan "layar putih kosong".
   SVG inline, nol request tambahan, tidak menghalangi klik. */
body::before {
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* PENTING: target HANYA <main>, bukan "body > *".
   Versi lama "body > * { position:relative; z-index:1 }" memaksa
   stacking context baru ke SETIAP anak <body> termasuk <header>,
   yang bentrok dengan .hero{isolation:isolate} di sebelahnya dan
   membuat sticky header berhenti menempel saat scroll. Header
   sekarang memakai position:fixed (lihat §6), jadi tidak butuh
   z-index relatif ke body sama sekali. */
main {
  position: relative; z-index: 1;
  margin-top: var(--header-h);   /* kompensasi header fixed — lihat §6 */
}

img, svg, video { max-width:100%; display:block; }
a { color:inherit; text-decoration:none; }
ul, ol { list-style:none; }
button { font:inherit; color:inherit; background:none; border:none; cursor:pointer; }
input, textarea, select { font:inherit; color:inherit; }
table { border-collapse:collapse; width:100%; }


/* ================================================================
   3. BLOK STARTER WAJIB (SOP §1)
   ================================================================ */
:focus-visible { outline:2px solid var(--focus); outline-offset:2px; border-radius:3px; }

.sr-only {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

.skip-link {
  position:absolute; left:var(--sp-4); top:-100px; z-index:999;
  padding:12px 20px; border-radius:var(--r-sm);
  background:var(--brand); color:#fff; font-weight:600;
  transition:top var(--dur-fast) var(--ease);
}
.skip-link:focus-visible { top:var(--sp-4); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior:auto; }
  *, *::before, *::after {
    animation-duration:.01ms !important; transition-duration:.01ms !important;
  }
}

/* Penanda konten dummy. Nyalakan blok ini saat QA pra-launch. */
/* [data-dummy]{outline:2px dashed #C08A00;background:rgba(255,214,0,.10)} */


/* ================================================================
   4. TIPOGRAFI
   line-height display sengaja rapat (1.04–1.1) — Cormorant/Marcellus
   mengambang kalau diberi 1.15
   ================================================================ */
h1,h2,h3,h4,h5,h6 { color:var(--ink); font-weight:400; }

h1 { font-family:var(--font-display); font-weight:400; font-size:var(--fs-h1);
     line-height:1.05; letter-spacing:-.018em; }
h2 { font-family:var(--font-display); font-weight:400; font-size:var(--fs-h2);
     line-height:1.08; letter-spacing:-.012em; }
h3 { font-family:var(--font-ui); font-weight:600; font-size:var(--fs-h3); line-height:1.3; }
h4 { font-family:var(--font-ui); font-weight:600; font-size:1.0625rem; line-height:1.35; }

.lead { font-size:var(--fs-lead); color:var(--body); line-height:1.7; }

.eyebrow {
  display:block; font-family:var(--font-ui);
  font-size:var(--fs-eyebrow); font-weight:600;
  letter-spacing:.22em; text-transform:uppercase; color:var(--gold-text);
}

/* Nomor section — 01 — 02 — 03, konsisten dengan proposal v1.5 */
.sec-num {
  display:inline-flex; align-items:center; gap:10px;
  font-size:var(--fs-eyebrow); font-weight:600; letter-spacing:.22em;
  color:var(--gold-text);
}
.sec-num::after { content:""; width:28px; height:1px; background:var(--gold-line); }

.script { font-family:var(--font-display); font-style:italic; font-weight:400; color:var(--gold-text); }
.small { font-size:var(--fs-sm); }
.xs { font-size:var(--fs-xs); }
.muted { color:var(--muted); }

.price {
  font-family:var(--font-ui); font-weight:600; font-size:var(--fs-price);
  line-height:1; color:var(--gold-text);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
.price .unit { font-size:var(--fs-sm); font-weight:500; color:var(--muted); }

/* Angka besar — nilainya WAJIB tertulis final di HTML (SOP §2) */
.stat { display:grid; gap:4px; }
.stat b {
  font-family:var(--font-display); font-weight:400; font-size:var(--fs-stat);
  line-height:1; color:var(--ink); font-variant-numeric:tabular-nums;
}


/* ================================================================
   5. LAYOUT & ATURAN WIDTH — MANDATORY (SOP §1 v1.2)
   Lebar dikendalikan padding. max-width angka tetap HANYA di @media.
   ================================================================ */
.wrap { width:100%; padding-inline:var(--gutter); margin-inline:auto; }

@media (min-width:1440px) { .wrap { max-width:1320px; } }

.section { padding-block:var(--sec-pad); position:relative; max-width:100vw; overflow:hidden; }
.section--soft { background:var(--surface-soft); }
.section--tint { background:var(--surface-tint); }
.section--deep { background:var(--surface-deep); color:var(--on-dark-muted); }
.section--deep h1,.section--deep h2,.section--deep h3 { color:var(--on-dark); }
.section--flush { padding-block:0; }

/* Page header gelap (11 halaman selain index.html) — sebelumnya
   ditulis inline style="padding-block:..." di tiap file (183
   inline style total di seluruh project, ini salah satu sumbernya).
   Token --pagehead-scale = 1 titik kontrol tunggal: ubah 1 angka
   di sini, seluruh 11 halaman ikut berubah tanpa sentuh HTML.
   Baseline sekarang: padding-top/bottom & h1 diturunkan tepat 28%
   dari nilai lama (sp-6/sp-7 = 48px/64px, h1 = --fs-h1 penuh) —
   dihitung: base baru (36+48+44=128px) × .954 = 122.1px ≈ 72% dari
   total lama (169.6px) = pengurangan 28% persis, bukan estimasi. */
:root { --pagehead-scale: .954; }
.page-head {
  padding-block:
    calc(clamp(28px,3.4vw,36px) * var(--pagehead-scale))
    calc(clamp(36px,4.4vw,48px) * var(--pagehead-scale));
}
.page-head h1 {
  font-size: calc(clamp(1.9rem,4.2vw,2.75rem) * var(--pagehead-scale));
}
.page-head .sec-head { gap: var(--sp-3); }
.page-head .sec-head-body { grid-template-columns:minmax(0,52ch); }

/* Wash gradien hangat — latar tidak pernah warna rata */
.section--wash::before {
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:radial-gradient(ellipse 70% 55% at 50% 0%,
             rgba(189,168,148,.20) 0%, transparent 70%);
}
.section--wash-b::before {
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:radial-gradient(ellipse 80% 60% at 15% 100%,
             rgba(255,226,173,.22) 0%, transparent 68%);
}

/* Kolom baca lewat grid track, BUKAN max-width pada <p> */
.prose { display:grid; grid-template-columns:minmax(0,68ch); justify-content:center; gap:var(--sp-4); }
.prose--left { justify-content:start; }

.sec-head { display:grid; gap:var(--sp-4); margin-bottom:var(--sp-7); }
.sec-head--center { justify-items:center; text-align:center; }
.sec-head--center .sec-head-body { display:grid; grid-template-columns:minmax(0,58ch); }

.rule-orn { display:block; width:72px; height:1px; background:var(--gold-line); position:relative; }
.rule-orn::after {
  content:""; position:absolute; left:50%; top:-2.5px;
  width:6px; height:6px; border-radius:50%; background:var(--gold-line);
  transform:translateX(-50%);
}

.grid { display:grid; gap:var(--sp-5); }
.grid > * { min-width:0; }
.grid-2 { grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr)); }
.grid-3 { grid-template-columns:repeat(auto-fit,minmax(min(100%,270px),1fr)); }

/* Grid 3-kolom DETERMINISTIK untuk packages.html — BUKAN pengganti
   .grid-3 (yang di atas dibiarkan apa adanya, saat ini tidak dipakai
   di HTML manapun, jadi 0 risiko regresi menambah kelas baru).
   Bug lama: .grid-3 namanya "3" tapi auto-fit dengan minmax(270px)
   di .wrap 1320px muat 4 kolom, bukan 3 — .grid-cards-3 mengunci
   jumlah kolom eksplisit per breakpoint, tidak bergantung lebar. */
.grid-cards-3 { grid-template-columns:repeat(3,minmax(0,1fr)); }
@media (max-width:999px) { .grid-cards-3 { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:639px) { .grid-cards-3 { grid-template-columns:1fr; } }
.grid-4 { grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr)); }

.row { display:flex; flex-wrap:wrap; gap:var(--sp-3); }
.row > * { min-width:0; }
.table-wrap { overflow-x:auto; -webkit-overflow-scrolling:touch; }
.stack { display:grid; gap:var(--sp-4); }
.center { text-align:center; }


/* ================================================================
   6. HEADER — sticky, tinggi tetap (tidak menyusut = CLS 0)
   SOP §14: judul KIRI, hamburger KANAN
   ================================================================ */
.hdr {
  position:fixed; top:0; left:0; right:0; z-index:var(--z-header); height:var(--header-h);
  background:color-mix(in srgb, var(--canvas) 86%, transparent);
  backdrop-filter:blur(14px) saturate(1.5);
  -webkit-backdrop-filter:blur(14px) saturate(1.5);
  border-bottom:1px solid var(--rule-2);
}
.hdr-inner { height:100%; display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4); }

.hdr-brand { display:flex; align-items:center; gap:10px; min-width:0; }
.hdr-brand img { width:40px; height:40px; }
.hdr-title {
  min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  font-family:var(--font-display); font-size:1.3rem; color:var(--ink);
  letter-spacing:.06em; line-height:1.1;
}
.hdr-title small {
  display:block; font-family:var(--font-ui); font-size:.5625rem;
  letter-spacing:.2em; text-transform:uppercase; color:var(--muted); line-height:1.4;
}

.nav { display:flex; align-items:center; gap:clamp(14px,1.8vw,26px); }
.nav a {
  position:relative; font-size:.8125rem; font-weight:600; color:var(--body);
  text-transform:uppercase; letter-spacing:.08em;
  padding-block:6px; transition:color var(--dur-fast) var(--ease);
}
.nav a::after {
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--gold-line); transform:scaleX(0); transform-origin:left;
  transition:transform var(--dur-base) var(--ease);
}
.nav a:hover { color:var(--ink); }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform:scaleX(1); }
.nav a[aria-current="page"] { color:var(--ink); font-weight:600; }

.hdr-actions { display:flex; align-items:center; gap:var(--sp-2); }

.burger { display:none; width:44px; height:44px; align-items:center; justify-content:center; border-radius:var(--r-sm); }
.burger span { display:block; width:20px; height:1.5px; background:var(--ink); position:relative; transition:background var(--dur-fast) var(--ease); }
.burger span::before, .burger span::after {
  content:""; position:absolute; left:0; width:20px; height:1.5px; background:var(--ink);
  transition:transform var(--dur-base) var(--ease);
}
.burger span::before { top:-6px; } .burger span::after { top:6px; }
.burger[aria-expanded="true"] span { background:transparent; }
.burger[aria-expanded="true"] span::before { transform:translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span::after  { transform:translateY(-6px) rotate(-45deg); }


/* ================================================================
   7. DRAWER MOBILE — slide dari KANAN
   ================================================================ */
.overlay {
  position:fixed; inset:0; z-index:var(--z-overlay);
  background:rgba(42,29,20,.45); opacity:0; visibility:hidden;
  transition:opacity var(--dur-base) var(--ease), visibility var(--dur-base);
}
.overlay.is-open { opacity:1; visibility:visible; }

.drawer {
  position:fixed; top:0; right:0; z-index:var(--z-drawer);
  width:min(84vw,340px); height:100dvh;          /* dvh, bukan vh */
  background:var(--surface); border-left:1px solid var(--rule);
  box-shadow:var(--shadow-lg);
  padding:var(--sp-5) var(--sp-5) var(--sp-6);
  display:flex; flex-direction:column; gap:var(--sp-5); overflow-y:auto;
  transform:translateX(100%); transition:transform var(--dur-base) var(--ease);
}
.drawer.is-open { transform:translateX(0); }

.drawer-nav { display:grid; gap:var(--sp-1); }
/* Sengaja TIDAK kapital seperti nav desktop — di ukuran 1.05rem,
   kapital+tracking lebar untuk daftar vertikal panjang justru
   lebih sulit dipindai mata. Kalau kakak mau tetap kapital di
   sini juga, tinggal tambah text-transform:uppercase. */
.drawer-nav a {
  display:block; padding:14px 12px; border-radius:var(--r-sm);
  font-size:1.05rem; font-weight:500; color:var(--body-strong);
  border-bottom:1px solid var(--rule-2);
  transition:background var(--dur-fast) var(--ease);
}
.drawer-nav a:hover { background:var(--surface-soft); }
.drawer-nav a[aria-current="page"] { color:var(--ink); font-weight:600; }
.drawer-foot { margin-top:auto; display:grid; gap:var(--sp-3); }


/* ================================================================
   8. TOMBOL — padding SIMETRIS, jarak antar elemen pakai margin
   ================================================================ */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  min-height:48px; padding:14px 30px; border-radius:var(--r-pill);
  font-size:var(--fs-sm); font-weight:600; letter-spacing:.03em; text-align:center;
  transition:background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
             transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease),
             border-color var(--dur-fast) var(--ease);
}
.btn:hover { transform:translateY(-1px); }
.btn:active { transform:translateY(0); }

.btn--primary { background:var(--brand); color:#fff; box-shadow:var(--shadow-sm); }
.btn--primary:hover { background:var(--brand-hover); box-shadow:var(--shadow); }

.btn--outline { border:1px solid var(--rule); color:var(--ink); background:transparent; }
.btn--outline:hover { border-color:var(--gold-line); background:var(--surface); }

.btn--light { border:1px solid rgba(255,248,242,.5); color:#FFF8F2; background:rgba(255,248,242,.06); }
.btn--light:hover { background:rgba(255,248,242,.14); border-color:rgba(255,248,242,.8); }

.btn--onDark { background:var(--brand-soft); color:var(--espresso); }
.btn--onDark:hover { background:var(--taupe-300); }

.btn--ghost { padding:10px 4px; min-height:40px; color:var(--brand); border-radius:var(--r-sm); }
.btn--ghost:hover { color:var(--brand-hover); }

.btn--sm { min-height:40px; padding:10px 20px; font-size:var(--fs-xs); }
.btn--block { width:100%; }


/* ================================================================
   9. PERLAKUAN FOTO
   Foto stock cenderung dingin. Lapisan hangat menyatukannya
   dengan palette taupe supaya tidak terlihat seperti tempelan.
   ================================================================ */
.ph { position:relative; overflow:hidden; background:var(--surface-tint); }
.ph img { width:100%; height:100%; object-fit:cover; }
.ph--warm img { filter:sepia(.18) saturate(.88) contrast(1.03); }
.ph--warm::after {
  content:""; position:absolute; inset:0; pointer-events:none;
  background:var(--taupe-400); mix-blend-mode:multiply; opacity:.13;
}
.ph--4x3{aspect-ratio:4/3} .ph--1x1{aspect-ratio:1/1}
.ph--3x4{aspect-ratio:3/4} .ph--4x5{aspect-ratio:4/5} .ph--16x9{aspect-ratio:16/9}

/* Bingkai emas asimetris — foto digeser, hairline emas di belakangnya */
.framed { position:relative; }
.framed::before {
  content:""; position:absolute; z-index:0;
  inset:24px -24px -24px 24px;
  border:1px solid var(--gold-line); border-radius:var(--r-md);
  pointer-events:none;
}
.framed > * { position:relative; z-index:1; border-radius:var(--r-md); }
@media (max-width:700px){ .framed::before{ inset:16px -16px -16px 16px; } }


/* ================================================================
   10. HERO
   ================================================================ */
.hero {
  position:relative; min-height:min(92dvh,820px);
  display:grid; align-items:center; padding-block:var(--sp-10);
  isolation:isolate; max-width:100vw; overflow:hidden;
}
.hero-media { position:absolute; inset:0; z-index:-2; }
.hero-media img {
  width:100%; height:100%; object-fit:cover;
  filter:sepia(.22) saturate(.82);
  opacity:0; transition:opacity var(--dur-hero) var(--ease);
}
.hero-media img.is-active { opacity:1; }

/* Scrim wajib — tanpa ini teks di atas foto gagal kontras */
.hero::before {
  content:""; position:absolute; inset:0; z-index:-1;
  background:
    radial-gradient(circle at 50% 40%, rgba(255,226,173,.30) 0%, transparent 60%),
    linear-gradient(rgba(42,29,20,.66), rgba(42,29,20,.46) 45%, rgba(42,29,20,.72));
}

.hero-inner { display:grid; justify-items:center; text-align:center; gap:var(--sp-4); }
.hero-logo { width:150px; height:150px; }
.hero h1 { font-size:var(--fs-hero); color:#FFF8F2; font-weight:400; letter-spacing:-.02em; line-height:1.02; }
.hero .eyebrow { color:var(--taupe-300); }
.hero .lead { color:#EFE3D9; display:grid; grid-template-columns:minmax(0,50ch); justify-content:center; }
.hero-cta { display:flex; flex-wrap:wrap; gap:var(--sp-3); justify-content:center; margin-top:var(--sp-3); }
.hero-meta {
  display:flex; flex-wrap:wrap; gap:var(--sp-2) var(--sp-4);
  justify-content:center; align-items:center; margin-top:var(--sp-5);
  font-size:var(--fs-sm); color:#E4D6CB;
}
.hero-meta > span { display:inline-flex; align-items:center; gap:7px; }
.hero-dot { width:3px; height:3px; border-radius:50%; background:var(--gold-line); }

.halo { position:relative; display:grid; place-items:center; }
.halo::before {
  content:""; position:absolute; z-index:-1; width:260%; aspect-ratio:1; border-radius:50%;
  background:radial-gradient(circle, rgba(255,226,173,.45) 0%, rgba(189,168,148,.18) 42%, transparent 72%);
}


/* ================================================================
   10b. HERO — VARIAN C (Full + Split gabungan)
   Referensi struktural: hero anabhidev.com — latar solid gelap
   (BUKAN foto full-bleed berputar), teks kiri, foto kanan dalam
   kartu rounded + badge floating. Beda dari anabhidev: di sini
   ditambah 1 foto tekstur sangat redup di background supaya
   tidak terasa flat, dan warna latar pakai --surface-deep
   (bukan hitam pekat) supaya konsisten dengan palette taupe.
   ================================================================ */
.hero-c {
  /* main{margin-top:var(--header-h)} sudah mengompensasi header fixed —
     JANGAN tambah var(--header-h) lagi di sini (dobel jarak). */
  position:relative; overflow:hidden; isolation:isolate;
  background:var(--surface-deep);
  padding-block:var(--sp-8) var(--sp-9);
}

/* Tekstur foto redup — BUKAN elemen LCP, hanya dekorasi.
   Opacity sangat rendah supaya tidak mengganggu kontras teks;
   filter grayscale+kontras rendah supaya tidak "bersaing" secara
   warna dengan foto kartu kanan yang jadi fokus utama. */
.hero-c-texture {
  position:absolute; inset:0; z-index:0; opacity:.07; pointer-events:none;
}
.hero-c-texture img {
  width:100%; height:100%; object-fit:cover;
  filter:grayscale(1) contrast(.9) brightness(1.4);
}
/* Scrim tambahan di atas tekstur — jaga kontras teks tetap aman.
   Radial dari kiri-atas (bukan linear kiri→kanan) supaya tetap
   masuk akal secara visual walau grid berubah jadi 1 kolom di
   mobile (lihat @media 920px) — tidak bergantung pada asumsi
   "kiri = teks, kanan = foto" yang cuma berlaku di desktop. */
.hero-c::before {
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(ellipse 80% 70% at 20% 30%,
             var(--surface-deep) 0%, rgba(42,29,20,.55) 55%, transparent 85%);
}

.hero-c-grid {
  position:relative; z-index:2;
  display:grid; grid-template-columns:1.05fr .95fr; gap:clamp(32px,5vw,80px);
  align-items:center;
}
@media (max-width:920px) { .hero-c-grid { grid-template-columns:1fr; gap:44px; } }

.hero-c-eyebrow {
  display:inline-flex; align-items:center; gap:12px; margin-bottom:20px;
  color:var(--taupe-300);
}
.hero-c-eyebrow::before { content:""; width:30px; height:1px; background:var(--gold-line); }

.hero-c h1 {
  font-family:var(--font-display); font-weight:400; color:#FFF8F2;
  font-size:clamp(2.6rem,6vw,4.4rem); line-height:1.04; letter-spacing:-.018em;
}
.hero-c .lead {
  margin-top:22px; font-size:var(--fs-lead); color:#EFE3D9;
  /* Grid track, BUKAN max-width langsung (SOP §1 mandatory) —
     pola sama dengan .hero .lead / .prose di tempat lain file ini. */
  display:grid; grid-template-columns:minmax(0,46ch);
}
.hero-c-cta { display:flex; flex-wrap:wrap; gap:var(--sp-3); margin-top:32px; }
.hero-c-meta {
  display:flex; flex-wrap:wrap; gap:var(--sp-2) var(--sp-4);
  margin-top:34px; font-size:var(--fs-sm); color:#C4B2A3;
}
.hero-c-meta > span { display:inline-flex; align-items:center; gap:7px; }
.hero-c-meta .stars { color:var(--gold-text); letter-spacing:.1em; }

/* Kartu foto kanan — foto MENGISI PENUH, bukan mengambang kecil
   di tengah gradien seperti Varian B. Border tipis translucent
   mirip anabhidev, bukan shadow berat. */
.hero-c-visual { position:relative; }
.hero-c-frame {
  position:relative; aspect-ratio:4/5; border-radius:var(--r-lg); overflow:hidden;
  border:1px solid rgba(245,238,232,.16);
  box-shadow:0 30px 70px rgba(0,0,0,.35);
}
.hero-c-frame img {
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  filter:sepia(.15) saturate(.9);
}
.hero-c-badge {
  position:absolute; left:20px; bottom:20px; z-index:2;
  background:var(--surface-deep); border:1px solid rgba(245,238,232,.18);
  border-radius:14px; padding:14px 18px;
  display:flex; align-items:center; gap:10px;
  box-shadow:0 14px 34px rgba(0,0,0,.3);
}
.hero-c-badge b { font-size:1.1rem; color:var(--on-dark); font-family:var(--font-ui); }
.hero-c-badge span { display:block; font-size:.6875rem; letter-spacing:.08em; text-transform:uppercase; color:var(--on-dark-muted); }
@media (max-width:920px) { .hero-c-badge { left:14px; bottom:14px; } }


/* ================================================================
   10c. HERO — VARIAN D2 "MAISON LEFT" (T1, calon pengganti C)
   Beda dari Varian D (center, di hero-preview.html): blok teks
   rata KIRI, dikunci grid track ~48ch (BUKAN full-width rata kiri-
   kanan ala Jagadita — itu B2B, kolom lebar krn kejar paragraf
   panjang; di sini tetap "anchor kiri" tapi kolom tetap sempit
   supaya kesan editorial-mewah tidak jatuh ke consulting-site).

   Foto: full-bleed 1 foto (bukan kartu terpisah seperti Varian C).
   Signature bar 3-anchor dipertahankan dari Varian D, posisi
   tetap center di dasar layar (strip status, bukan bagian blok
   headline — natural dibaca sebagai baris info, bukan teks utama).

   KONTRAS — dihitung, bukan dikira-kira (SOP §11, formula WCAG):
   Titik paling terang foto disimulasikan #E8D9C4 (kulit/handuk/
   highlight). Overlay solid rgba(43,34,28, ALPHA) di atas titik
   itu perlu ALPHA >= .65 supaya --lead-on-photo (krem #EFE3D9)
   capai kontras >= 4.5:1 (hasil: 4.72:1 pada alpha .65). h1 putih
   FFF8F2 py margin lebih lega (5.65:1 pada alpha yang sama) —
   jadi .65 adalah ambang MINIMUM yang menentukan, dipakai sebagai
   titik paling terang gradient di bawah, bukan rata-rata gradient.
   Kalau foto produksi final diganti, ulangi hitungan ini dulu
   sebelum ship — foto berbeda = titik terang berbeda.
   ================================================================ */
.hero-d2 {
  position:relative; overflow:hidden; isolation:isolate;
  min-height:min(90svh,780px);
  display:grid; align-content:center;
}
.hero-d2-media { position:absolute; inset:0; z-index:-2; }
.hero-d2-media img {
  width:100%; height:100%; object-fit:cover;
  filter:sepia(.12) saturate(.9);
  transform:scale(1.04); transition:transform 1.4s var(--ease);
}
.hero-d2.is-loaded .hero-d2-media img { transform:scale(1); }

/* Scrim 2 lapis, sengaja terpisah dari desain Varian D lama:
   (1) base gradient kiri→kanan, gelap di kiri (tempat teks duduk)
       menipis ke kanan — arah BERBEDA dari D (yang atas-bawah),
       karena D2 rata kiri butuh kegelapan terkonsentrasi di kiri,
       bukan merata di tengah.
   (2) radial vignette KEDUA khusus di belakang blok teks saja —
       independen dari komposisi foto, jadi tetap aman walau foto
       production nanti beda dari foto placeholder sekarang. */
.hero-d2::before {
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:linear-gradient(90deg,
    rgba(43,34,28,.72) 0%, rgba(43,34,28,.60) 32%,
    rgba(43,34,28,.34) 58%, rgba(43,34,28,.16) 78%, rgba(43,34,28,.06) 100%);
}
.hero-d2::after {
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:radial-gradient(ellipse 60% 70% at 22% 46%,
    rgba(43,34,28,.65) 0%, rgba(43,34,28,.32) 55%, transparent 80%);
}

.hero-d2-inner {
  position:relative; z-index:1;
  display:grid; grid-template-columns:minmax(0,48ch); justify-content:start;
  gap:var(--sp-4);
  padding-block:var(--sp-9) calc(var(--sp-9) + 64px); /* ruang bawah utk signature bar */
}
.hero-d2-logo { width:44px; height:44px; opacity:.94; margin-bottom:2px; }
.hero-d2 .eyebrow { color:var(--taupe-200); text-align:left; }
.hero-d2 h1 {
  font-family:var(--font-display); font-weight:400; color:#FFF8F2;
  font-size:clamp(2.5rem,5.6vw,4.2rem); line-height:1.05; letter-spacing:-.016em;
  text-align:left;
}
.hero-d2-rule {
  display:block; width:64px; height:1px; background:var(--gold-line);
  position:relative; margin-block:2px;
}
.hero-d2-rule::after {
  content:""; position:absolute; left:0; top:-2.5px; width:6px; height:6px;
  border-radius:50%; background:var(--gold-line);
}
/* --lead-on-photo: token terpisah dari --on-dark-muted biasa,
   supaya perhitungan kontras di atas foto tidak bercampur dengan
   nilai default yang dipakai di atas --surface-deep solid (mis.
   .hero-c .lead) — dua konteks kontras yang berbeda, harus punya
   sumber kebenaran warna yang berbeda juga. */
.hero-d2 .lead {
  font-size:var(--fs-lead); color:#F5EBE0; /* dinaikkan dari EFE3D9 → tambahan margin kontras */
  text-align:left; text-wrap:balance;
}
.hero-d2-cta { display:flex; flex-wrap:wrap; gap:var(--sp-3); margin-top:var(--sp-2); }

.hero-d2-sig {
  position:absolute; left:0; right:0; bottom:0; z-index:1;
  border-top:1px solid rgba(255,255,255,.18);
  padding-block:16px;
  background:linear-gradient(0deg, rgba(43,34,28,.62) 0%, rgba(43,34,28,.08) 100%);
}
.hero-d2-sig-row {
  display:flex; flex-wrap:wrap; justify-content:center; align-items:center;
  gap:10px var(--sp-4);
  font-size:var(--fs-xs); text-transform:uppercase; letter-spacing:.14em;
  color:#F5EBE0;
}
.hero-d2-sig-row > span { display:inline-flex; align-items:center; gap:7px; white-space:nowrap; }
.hero-d2-dot { width:3px; height:3px; border-radius:50%; background:var(--gold-line); flex:none; }

@media (max-width:760px) {
  .hero-d2 { min-height:min(82svh,660px); }
  .hero-d2-inner { grid-template-columns:minmax(0,1fr); }
  .hero-d2 h1 { font-size:clamp(2rem,8vw,2.6rem); }
  .hero-d2-sig-row { font-size:.6875rem; letter-spacing:.08em; gap:6px 12px; }
}


/* ================================================================
   11. TRIPTYCH — 3 pintu masuk
   ================================================================ */
.tri { position:relative; display:block; border-radius:var(--r-md); overflow:hidden; box-shadow:var(--shadow-sm); }
.tri .ph { aspect-ratio:4/5; }
.tri .ph img { transition:transform var(--dur-slow) var(--ease); }
.tri:hover .ph img { transform:scale(1.04); }
.tri-body {
  position:absolute; left:var(--sp-4); right:var(--sp-4); bottom:var(--sp-4);
  background:color-mix(in srgb, var(--surface) 95%, transparent);
  backdrop-filter:blur(8px); padding:var(--sp-4); border-radius:var(--r-sm);
  display:grid; gap:6px; transition:transform var(--dur-base) var(--ease);
}
.tri:hover .tri-body { transform:translateY(-5px); }
.tri-body h3 { font-size:1.0625rem; }


/* ================================================================
   12. KARTU
   ================================================================ */
.card {
  position:relative; background:var(--surface);
  border:1px solid var(--rule-2); border-radius:var(--r-md); overflow:hidden;
  display:flex; flex-direction:column;
  transition:box-shadow var(--dur-base) var(--ease), transform var(--dur-base) var(--ease);
}
/* Hairline emas muncul di dalam tepi kartu saat hover — bukan sekadar shadow naik */
.card::after {
  content:""; position:absolute; inset:0; border-radius:var(--r-md); pointer-events:none;
  box-shadow:inset 0 0 0 1px transparent;
  transition:box-shadow var(--dur-base) var(--ease);
}
.card:hover { box-shadow:var(--shadow-lg); transform:translateY(-3px); }
.card:hover::after { box-shadow:inset 0 0 0 1px var(--gold-line); }
.card .ph img { transition:transform var(--dur-slow) var(--ease); }
.card:hover .ph img { transform:scale(1.05); }

/* Kartu paket "contoh, bukan resmi" (packages.html) — border warna
   gold-line (bukan hardcode #E8C9A0 inline seperti sebelumnya)
   supaya konsisten dengan token .badge-dummy di atasnya. */
.card--dummy { border-color:var(--gold-line); }

.card-body { padding:var(--sp-5) var(--sp-4) var(--sp-4); display:grid; gap:8px; align-content:start; flex:1; }
.card-desc {
  font-size:var(--fs-sm); color:var(--muted);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
/* Revisi T1 — flex space-between lama mendorong tombol keluar &
   terpotong overflow:hidden .card saat harga panjang ("500k /
   example price") bertemu kolom sempit (bug nyata di packages.html
   3-kolom, "Ask →" kepotong). Grid 2-kolom eksplisit + tombol
   flex-shrink:0 memastikan tombol tidak pernah kehilangan ruang. */
.card-foot {
  display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center;
  gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4); border-top:1px solid var(--rule-2); margin-top:auto;
}
.card-foot .btn { flex-shrink:0; white-space:nowrap; }
@media (max-width:380px) {
  .card-foot { grid-template-columns:1fr; gap:12px; justify-items:start; }
}
.card-meta { font-size:var(--fs-xs); color:var(--muted); letter-spacing:.1em; }

/* Badge untuk konten dummy yang bisa disalahartikan sebagai fakta
   bisnis (mis. paket contoh yang belum ditawarkan resmi). Beda
   dari [data-dummy] biasa: ini WAJIB terlihat pengunjung, bukan
   hanya penanda internal untuk developer. */
/* Revisi T4 — warna oranye lama (#FBEBD8/#8A5A1F/#E8C9A0) adalah
   SATU-SATUNYA warna di luar palette taupe/gold di seluruh situs
   (temuan review: menonjol seperti pesan error, bukan label netral).
   Diganti ke token palette (--surface-tint/--gold-text/--gold-line)
   supaya badge tetap terlihat sebagai penanda khusus (border +
   dot pembeda), tapi tidak terbaca sebagai warning/alert. */
.badge-dummy {
  display:inline-flex; align-items:center; gap:6px;
  padding:5px 12px; border-radius:var(--r-pill);
  background:var(--surface-tint); color:var(--gold-text); border:1px solid var(--gold-line);
  font-size:.6875rem; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
}
.badge-dummy::before { content:"●"; font-size:.55rem; color:var(--gold-line); }

/* ================================================================
   TIMELINE "The Road to Della Spa" — About §Journey.
   Garis vertikal di tengah (desktop) / kiri (mobile), titik
   penghubung di tiap milestone, tahun berselang-seling kiri-kanan.
   Tahun DIKARANG (badge-dummy jelas menandai) — bukan fakta
   terverifikasi, lihat komentar di about.html.
   ================================================================ */
.timeline { position:relative; display:grid; gap:var(--sp-8); }
.timeline::before {
  content:""; position:absolute; top:0; bottom:0; left:20px;
  width:1px; background:var(--rule);
}
@media (min-width:860px){
  .timeline::before { left:50%; transform:translateX(-50%); }
}

.tl-item { position:relative; display:grid; gap:var(--sp-4); padding-left:52px; }
.tl-item::before {
  content:""; position:absolute; left:14px; top:6px;
  width:13px; height:13px; border-radius:50%;
  background:var(--canvas); border:2px solid var(--gold-line);
  z-index:1;
}
@media (min-width:860px){
  .tl-item {
    padding-left:0; grid-template-columns:1fr 1fr; align-items:center; gap:var(--sp-8);
  }
  .tl-item::before { left:50%; transform:translateX(-50%); top:50%; margin-top:-6.5px; }
  .tl-item:nth-child(odd) .tl-copy { text-align:right; order:1; }
  .tl-item:nth-child(odd) .tl-media { order:2; }
  .tl-item:nth-child(even) .tl-copy { order:2; }
  .tl-item:nth-child(even) .tl-media { order:1; }
}

.tl-year {
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--font-ui); font-weight:600; font-size:1.05rem; color:var(--gold-text);
  margin-bottom:8px;
}
.tl-copy h3 { font-size:1.0625rem; margin-bottom:6px; }
.tl-copy p { font-size:var(--fs-sm); color:var(--muted); }
@media (min-width:860px){ .tl-item:nth-child(odd) .tl-year{ justify-content:flex-end; } }

.tl-media .ph { aspect-ratio:4/3; border-radius:var(--r-md); }


/* ================================================================
   13. BARIS HARGA — dotted leader dibuat dengan border,
   BUKAN karakter titik berulang (merusak screen reader & copy-paste)
   ================================================================ */
.plist { display:grid; }
.prow {
  display:grid; grid-template-columns:1fr auto; align-items:baseline;
  gap:0 var(--sp-3); padding-block:var(--sp-4);
  border-bottom:1px solid var(--rule-2);
  transition:background var(--dur-fast) var(--ease);
}
.prow:hover { background:var(--surface-soft); }
.prow-main { display:flex; align-items:baseline; gap:var(--sp-2); min-width:0; }
.prow-name { font-weight:600; color:var(--ink); white-space:nowrap; }
.prow-lead { flex:1; min-width:12px; border-bottom:1px dotted var(--gold-line); transform:translateY(-4px); }
.prow-desc { grid-column:1/-1; font-size:var(--fs-sm); color:var(--muted); margin-top:4px; }
.prow-cta { grid-column:1/-1; margin-top:var(--sp-2); }
@media (min-width:720px){
  .prow { grid-template-columns:1fr auto auto; }
  .prow-cta { grid-column:auto; margin-top:0; opacity:0; transition:opacity var(--dur-fast) var(--ease); }
  .prow:hover .prow-cta, .prow:focus-within .prow-cta { opacity:1; }
  .prow-desc { grid-column:1/2; }
}


/* ================================================================
   14. TABS — center di desktop, kiri + scroll di mobile
   Di mobile TIDAK boleh center: item pertama bisa terdorong
   keluar area terlihat tanpa pengunjung sadar.
   ================================================================ */
.tabs {
  display:flex; gap:var(--sp-2); overflow-x:auto; scroll-snap-type:x proximity;
  padding-bottom:var(--sp-3); border-bottom:1px solid var(--rule);
  margin-bottom:var(--sp-6);
  -ms-overflow-style:none; scrollbar-width:none;
}
.tabs::-webkit-scrollbar { display:none; }
@media (min-width:720px){ .tabs { justify-content:center; } }

.tab {
  scroll-snap-align:start; white-space:nowrap; min-height:44px; padding:11px 22px;
  border-radius:var(--r-pill); font-size:var(--fs-sm); font-weight:500; color:var(--muted);
  transition:background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.tab:hover { color:var(--ink); background:var(--surface-soft); }
.tab[aria-selected="true"] { background:var(--brand); color:#fff; font-weight:600; }
.tabpanel[hidden] { display:none; }


/* ================================================================
   15. ACCORDION FAQ — <details> native, isi tetap ada di HTML
   grid-template-rows 0fr→1fr, BUKAN max-height
   ================================================================ */
.faq { display:grid; }
.faq details { border-bottom:1px solid var(--rule-2); }
.faq summary {
  list-style:none; cursor:pointer; display:flex; align-items:center;
  justify-content:space-between; gap:var(--sp-4);
  padding-block:var(--sp-4); min-height:44px; font-weight:600; color:var(--ink);
}
.faq summary::-webkit-details-marker { display:none; }
.faq summary::after {
  content:""; flex:none; width:10px; height:10px;
  border-right:1.5px solid var(--gold-line); border-bottom:1.5px solid var(--gold-line);
  transform:rotate(45deg) translateY(-2px);
  transition:transform var(--dur-base) var(--ease);
}
.faq details[open] summary::after { transform:rotate(-135deg) translateY(-2px); }
.faq-body > div { overflow:hidden; padding-bottom:var(--sp-4); color:var(--body); }


/* ================================================================
   16. TESTIMONI · STAT · INFO · MAP
   ================================================================ */
.quote { display:grid; gap:var(--sp-4); }
.quote blockquote {
  font-family:var(--font-display); font-size:clamp(1.35rem,3vw,1.85rem);
  line-height:1.35; color:var(--ink); font-style:italic;
}
.quote blockquote::before { content:"\201C"; color:var(--gold-line); margin-right:2px; }
.quote blockquote::after  { content:"\201D"; color:var(--gold-line); }
.quote cite { font-style:normal; font-size:var(--fs-sm); color:var(--muted); }
.quote cite b { color:var(--ink); font-weight:600; }

.stats { display:grid; gap:var(--sp-5); grid-template-columns:repeat(auto-fit,minmax(min(100%,140px),1fr)); }
.stats .stat { text-align:center; }
.stats .stat span { font-size:var(--fs-xs); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); }

/* Varian 2x2 tetap — untuk 4 stat, tidak menyisakan baris ganjil
   di lebar mana pun (auto-fit bisa jatuh ke 1 kolom di layar sempit
   dan menyisakan item ke-4 sendirian). Item kiri align kiri,
   kanan align kiri juga terhadap kolomnya sendiri — bukan center
   independen — supaya "7" sejajar tepat di bawah "20+". */
.stats--2x2 {
  grid-template-columns: repeat(2, minmax(0, max-content));
  justify-content: start;
  gap: var(--sp-6) var(--sp-8);
}
.stats--2x2 .stat { text-align: left; }

/* Grid section testimoni (Home §04). Kolom kanan lebar-konten-saja
   (auto), bukan 1fr — supaya stat tidak melar ke tepi jauh dari
   teks di sebelahnya, sesuai review 22 Agustus. */
.testi-grid {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-9);
  align-items: start;
}
.testi-stats { margin-top: calc(var(--sp-3) + 4px); }
@media (max-width: 760px) {
  .testi-grid { grid-template-columns: 1fr; gap: var(--sp-6); }
  .testi-stats { margin-top: 0; }
}

.trust {
  display:flex; flex-wrap:wrap; gap:var(--sp-4) var(--sp-7);
  align-items:center; justify-content:center; padding-block:var(--sp-5);
  border-block:1px solid var(--rule-2);
}
.trust-item { display:flex; align-items:center; gap:10px; font-size:var(--fs-sm); }
.trust-item strong { color:var(--ink); font-size:1.05rem; }
.stars { color:var(--gold-text); letter-spacing:.12em; }

.info-grid { display:grid; gap:var(--sp-6); }
@media (min-width:760px){ .info-grid { grid-template-columns:repeat(3,minmax(0,1fr)); } }

/* Revisi T1 — grid align-content:start lama membiarkan konten
   mengalir bebas per kartu, sehingga CTA di kartu berbeda berhenti
   di ketinggian berbeda (bug nyata di contact.html: kartu "Opening
   Hours" tanpa CTA, "Location" & "Contact" dengan CTA gaya beda-
   beda, tidak sejajar). Flex column + margin-top:auto pada action
   memaksa semua CTA duduk di baris dasar yang sama. */
.info-card { display:flex; flex-direction:column; gap:10px; }
.info-card h3 { font-size:1rem; letter-spacing:.02em; }
.info-card-action {
  margin-top:auto; padding-top:var(--sp-3);
  border-top:1px solid var(--rule-2);
}
.info-card-action .btn { width:max-content; }

.map-facade {
  position:relative; aspect-ratio:16/9; border-radius:var(--r-md); overflow:hidden;
  background:var(--surface-tint); display:grid; place-items:center; border:1px solid var(--rule);
}
.map-facade-btn { display:grid; gap:var(--sp-3); justify-items:center; text-align:center; padding:var(--sp-5); }
.map-facade iframe { position:absolute; inset:0; width:100%; height:100%; border:0; }
@media (max-width:600px){ .map-facade { aspect-ratio:4/3; } }


/* ================================================================
   16b. GALLERY MOSAIC (T1 — menggantikan <style> inline gallery.html)
   Bug lama: grid-auto-rows:10px + figure:has(.ph--Nx N){span:X}
   menghitung tinggi dari asumsi lebar-kolom-380px TETAP, padahal
   tinggi foto (lebar×rasio) berubah begitu breakpoint berubah —
   span konstan bertemu tinggi yang berubah = lubang kosong besar
   di breakpoint mana pun selain yang dipakai buat kalkulasi awal.

   Perbaikan bukan menyetel ulang angka span (bug akan selalu
   kembali di breakpoint lain selama tinggi bergantung aspect-ratio
   TAPI span-nya konstan) — melainkan membalik prinsipnya: tinggi
   DITENTUKAN GRID (grid-auto-rows tetap per breakpoint), foto
   MENGISI lewat object-fit:cover dan position:absolute. Mustahil
   ada lubang karena tinggi tile tidak lagi bergantung rasio foto
   sama sekali.

   PERBAIKAN LANJUTAN (setelah review visual): grid-auto-flow:dense
   WAJIB ada. Tanpa dense, item dengan grid-row-span berbeda (hero/
   tall = 3 baris, sq/wide = 2 baris) meninggalkan celah vertikal
   yang TIDAK otomatis diisi item berikutnya — browser mengisi grid
   secara linear per-baris, bukan mencari slot kosong terdekat.
   dense memaksa browser mencari & mengisi celah itu. Trade-off yang
   disadari: dense boleh menampilkan item TIDAK sesuai urutan DOM
   linear (item belakang bisa "melompat" mengisi celah di depan) —
   untuk galeri foto tanpa makna urutan kronologis, ini dampak yang
   diterima demi grid tanpa lubang.
   ================================================================ */
.gal-mosaic {
  display:grid; grid-template-columns:repeat(2,1fr);
  grid-auto-rows:clamp(90px,20vw,140px);
  grid-auto-flow:dense;
  gap:var(--sp-3);
}
@media (min-width:640px){ .gal-mosaic { grid-template-columns:repeat(4,1fr); } }
@media (min-width:980px){ .gal-mosaic { grid-template-columns:repeat(6,1fr); grid-auto-rows:clamp(70px,7vw,100px); } }

.gal-item {
  position:relative; border-radius:var(--r-md); overflow:hidden;
  background:var(--surface-tint);
}
.gal-item img {
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  filter:sepia(.12) saturate(.92);
  transition:transform var(--dur-slow) var(--ease);
}
.gal-item:hover img,
.gal-item:focus-within img { transform:scale(1.05); }

/* Caption sebagai overlay di dalam tile — BUKAN balok putih di
   bawah foto seperti versi lama (itu yang membuat gallery terbaca
   sebagai daftar file, bukan galeri). Muncul dari bawah via scrim
   saat hover/focus di desktop; di mobile (tanpa hover) tetap
   tampil tipis lewat opacity default > 0. */
.gal-item-cap {
  position:absolute; left:0; right:0; bottom:0; z-index:1;
  padding:14px 12px 10px;
  font-size:var(--fs-xs); color:#F5EEE8;
  background:linear-gradient(0deg, rgba(20,14,10,.78) 0%, transparent 100%);
  opacity:.82; transform:translateY(0);
  transition:opacity var(--dur-fast) var(--ease);
}
.gal-item:hover .gal-item-cap,
.gal-item:focus-within .gal-item-cap { opacity:1; }

/* Span deterministik — pola tetap diulang tiap 6 tile:
   hero + tall + sq + sq + wide + tall. Ukuran SELALU proporsi
   grid (kolom×baris), tidak pernah bergantung rasio foto asli,
   sehingga nol kemungkinan lubang di breakpoint mana pun. */
.gal-item--hero { grid-column:span 2; grid-row:span 3; }
.gal-item--tall { grid-column:span 1; grid-row:span 3; }
.gal-item--sq   { grid-column:span 1; grid-row:span 2; }
.gal-item--wide { grid-column:span 2; grid-row:span 2; }
@media (min-width:640px){
  .gal-item--hero { grid-column:span 4; grid-row:span 3; }
  .gal-item--tall { grid-column:span 2; grid-row:span 3; }
  .gal-item--sq   { grid-column:span 2; grid-row:span 2; }
  .gal-item--wide { grid-column:span 4; grid-row:span 2; }
}
@media (min-width:980px){
  .gal-item--hero { grid-column:span 4; grid-row:span 3; }
  .gal-item--tall { grid-column:span 2; grid-row:span 3; }
  .gal-item--sq   { grid-column:span 2; grid-row:span 2; }
  .gal-item--wide { grid-column:span 4; grid-row:span 2; }
}

/* Filter pill — ACC kakak: dibuat sekarang meski foto masih
   placeholder (bukan ditunda). data-filter di container men-toggle
   visibility tile lewat data-cat pada tiap tile — nol dependency,
   nol JS untuk filtering itu sendiri (hanya toggle atribut). */
.gal-filters {
  display:flex; flex-wrap:wrap; gap:10px; justify-content:center;
  margin-bottom:var(--sp-6);
}
.gal-filter-btn {
  padding:9px 20px; border-radius:var(--r-pill); border:1px solid var(--rule);
  background:var(--surface); color:var(--muted);
  font-size:var(--fs-xs); font-weight:600; letter-spacing:.04em;
  cursor:pointer; transition:all var(--dur-fast) var(--ease);
}
.gal-filter-btn[aria-pressed="true"] {
  background:var(--brand); color:#fff; border-color:var(--brand);
}
[data-gal-active]:not([data-gal-active="all"]) .gal-item:not([data-gal-active~="placeholder-marker"]) {
  /* placeholder rule — diganti JS via inline style per-tile saat filter aktif, lihat js/main.js (T5) */
}

/* Lightbox base (T5 mengisi interaksi JS, style dasar disiapkan
   di sini supaya T1 = fondasi CSS lengkap untuk semua tahap
   berikutnya, sesuai rencana). <dialog> native — dukungan browser
   sudah universal per Agustus 2026, tidak perlu polyfill/library. */
.gal-lightbox { border:0; padding:0; background:transparent; max-width:min(92vw,1100px); max-height:92vh; }
.gal-lightbox::backdrop { background:rgba(20,14,10,.88); }
.gal-lightbox-img { display:block; max-width:100%; max-height:88vh; border-radius:var(--r-md); }
.gal-lightbox-close {
  position:fixed; top:var(--sp-4); right:var(--sp-4); z-index:10;
  width:44px; height:44px; border-radius:50%; border:1px solid rgba(245,238,232,.3);
  background:rgba(20,14,10,.6); color:#F5EEE8; display:grid; place-items:center;
  cursor:pointer;
}


/* ================================================================
   17. FOOTER
   ================================================================ */
.ftr { background:var(--surface-deep); color:var(--on-dark-muted); padding-block:var(--sp-9) var(--sp-5); }
.ftr a { color:var(--on-dark-muted); transition:color var(--dur-fast) var(--ease); }
.ftr a:hover { color:var(--on-dark); }
/* Revisi T1 — 3 kolom lama (1.4fr 1fr 1fr) menaruh 8 link "Pages"
   dalam 1 kolom sendirian di tengah, sementara kolom brand (kiri)
   cuma 2 baris teks — timpang tinggi jauh (bug nyata di screenshot
   review: kolom tengah "kejauhan ke bawah"). 4 kolom memecah 8
   link jadi 2 kelompok bermakna (Explore/Visit) — lihat HTML T3. */
.ftr-top { display:grid; gap:var(--sp-6); }
@media (min-width:620px) and (max-width:1023px){ .ftr-top { grid-template-columns:1fr 1fr; } }
@media (min-width:1024px){ .ftr-top { grid-template-columns:1.25fr .85fr .85fr 1.05fr; } }
.ftr h3 { color:var(--on-dark); font-size:.75rem; letter-spacing:.2em; text-transform:uppercase; margin-bottom:var(--sp-4); }
.ftr-brand img { width:72px; height:72px; }
.ftr-links { display:grid; gap:11px; font-size:var(--fs-sm); }
.ftr-bottom {
  margin-top:var(--sp-8); padding-top:var(--sp-4);
  border-top:1px solid rgba(245,238,232,.14);
  text-align:center; font-size:var(--fs-xs);
}
.ftr-bottom p { margin:0; }
.ftr-credit { color:var(--on-dark-muted); }
.ftr-credit a { color:var(--on-dark-muted); text-decoration:underline; text-underline-offset:2px; }
.ftr-credit a:hover { color:var(--on-dark); }

/* Status pill "Open now / Closed" — style disiapkan di T1, logic
   JS (hitung jam WITA, bukan jam device pengunjung) masuk di T3
   bersama footer & contact. Fallback wajib: kalau JS gagal load,
   elemen ini TIDAK BOLEH tampil kosong/salah — HTML default harus
   berupa jam buka biasa tanpa klaim status, JS baru menambahkan
   .status-pill--open/--closed setelah berhasil hitung (lihat
   catatan implementasi di js/main.js saat T3 dikerjakan). */
.status-pill {
  display:inline-flex; align-items:center; gap:7px;
  font-size:var(--fs-xs); font-weight:600; letter-spacing:.04em;
}
.status-pill::before {
  content:""; width:7px; height:7px; border-radius:50%; flex:none;
}
.status-pill--open::before { background:#3D8B5A; }
.status-pill--open { color:#3D8B5A; }
.status-pill--closed::before { background:#B4472E; }
.status-pill--closed { color:#B4472E; }


/* ================================================================
   18. FLOATING WHATSAPP & COOKIE CONSENT
   ================================================================ */
.wa-float {
  position:fixed; right:var(--sp-4); z-index:var(--z-float);
  bottom:calc(var(--sp-4) + env(safe-area-inset-bottom));
  width:56px; height:56px; border-radius:50%; display:grid; place-items:center;
  background:var(--brand); color:#fff; box-shadow:var(--shadow-lg);
  opacity:0; visibility:hidden; transform:translateY(10px);
  transition:opacity var(--dur-base) var(--ease), transform var(--dur-base) var(--ease), visibility var(--dur-base);
}
.wa-float.is-visible { opacity:1; visibility:visible; transform:translateY(0); }
.wa-float:hover { background:var(--brand-hover); }

/* Ruang sudah dicadangkan lewat transform, jadi CLS = 0 */
.consent {
  position:fixed; left:var(--sp-4); right:var(--sp-4); z-index:var(--z-consent);
  bottom:calc(var(--sp-4) + env(safe-area-inset-bottom));
  background:var(--surface); border:1px solid var(--rule); border-radius:var(--r-md);
  box-shadow:var(--shadow-lg); padding:var(--sp-4);
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--sp-3);
  transform:translateY(140%); transition:transform var(--dur-base) var(--ease);
}
.consent.is-open { transform:translateY(0); }
.consent p { flex:1; min-width:220px; font-size:var(--fs-xs); color:var(--body); }
@media (min-width:720px){ .consent { left:auto; right:var(--sp-5); width:min(520px,90vw); } }


/* ================================================================
   18b. TOGGLE BAHASA EN/ID
   Setiap teks yang beda per bahasa ditulis 2x berdampingan di HTML
   dengan atribut [data-lang-en] / [data-lang-id]. Yang TIDAK aktif
   disembunyikan lewat atribut HTML native `hidden` (bukan class
   custom) — computed default `display:none`, jadi tanpa JS pun teks
   ganda tidak akan pernah tampil dobel. JS main.js men-toggle atribut
   `hidden` ini saat tombol ditekan, plus swap <title>/meta lewat
   dataset di <html>. Default HTML: EN tanpa `hidden`, ID dengan
   `hidden` — keputusan klien: EN yang tampil pertama kali dibuka.
   Reasoning teknis dipilihnya `hidden` dibanding attribute selector
   custom (mis. [data-lang="en"] [data-lang-id]{display:none}):
   `hidden` native lebih murah dicek (tidak perlu re-query CSS cascade
   berdasarkan state di elemen leluhur jauh di <html>), dan aman kalau
   suatu saat elemin dipindah/di-nest ulang.
   ================================================================ */
.lang-toggle {
  display:inline-flex; border:1px solid var(--rule); border-radius:var(--r-pill);
  overflow:hidden; flex:none;
}
.lang-toggle button {
  font-family:var(--font-ui); font-size:.75rem; font-weight:600;
  letter-spacing:.04em; padding:8px 14px; color:var(--muted);
  transition:background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.lang-toggle button[aria-pressed="true"] { background:var(--brand-soft); color:var(--espresso); }
.lang-toggle button:not([aria-pressed="true"]):hover { background:var(--surface-soft); color:var(--ink); }

/* Varian untuk dipakai di atas latar gelap (drawer mobile TIDAK
   perlu — toggle cuma tampil di header desktop & drawer top,
   lihat markup). Disiapkan kalau nanti toggle mau dipindah ke
   footer/drawer yang berlatar gelap. */
.lang-toggle--onDark { border-color:rgba(245,238,232,.24); }
.lang-toggle--onDark button { color:var(--on-dark-muted); }
.lang-toggle--onDark button[aria-pressed="true"] { background:var(--taupe-400); color:var(--espresso); }


/* ================================================================
   19. BREADCRUMB & REVEAL
   ================================================================ */
.crumb { display:flex; flex-wrap:wrap; gap:8px; align-items:center; font-size:var(--fs-xs); color:var(--muted); }
.crumb li { display:flex; align-items:center; }
.crumb li + li::before { content:"/"; margin-right:8px; color:var(--gold-line); }
.crumb [aria-current="page"] { color:var(--ink); }

/* Varian untuk section--deep. WAJIB dipakai bersamaan — --muted
   dan --ink default hanya 1.55:1 / 1.56:1 di atas --surface-deep,
   gagal total kalau tidak di-override. */
.crumb--onDark { color:var(--on-dark-muted); }               /* 5.11:1 */
.crumb--onDark li + li::before { color:var(--gold-line); }
.crumb--onDark [aria-current="page"] { color:var(--on-dark); } /* 9.11:1 */

/* Fail-safe: .reveal TIDAK tersembunyi secara default.
   Hanya tersembunyi kalau <html> sudah dapat kelas "reveal-on"
   dari JS (lihat main.js). Kalau JS gagal load, konten tetap
   terlihat — bukan tersembunyi permanen. */
.reveal-on .reveal { opacity:0; transform:translateY(14px); }
.reveal-on .reveal.is-in {
  opacity:1; transform:translateY(0);
  transition:opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}
@media (prefers-reduced-motion: reduce){ .reveal-on .reveal { opacity:1; transform:none; } }


/* ================================================================
   20. BREAKPOINT
   ================================================================ */
@media (max-width:900px){
  .nav { display:none; }
  .burger { display:inline-flex; }
  .hdr-actions .btn--primary { display:none; }   /* CTA pindah ke drawer */
}
@media (max-width:480px){
  .hdr-title small { display:none; }
  .hero-logo { width:112px; height:112px; }
}


/* ================================================================
   21. PRINT — pelanggan sering mencetak pricelist
   ================================================================ */
@media print {
  .hdr,.drawer,.overlay,.wa-float,.consent,.hero-media,.btn { display:none !important; }
  body { background:#fff; color:#000; }
  body::before { display:none; }
  .section { padding-block:16px; }
}
