/* KITAPOS landing page. Everything Uno utilities cannot express: faces,
   theme tokens, textures, the headline mask, the marquee, the pinned product
   tour, and the interactive storefront demo.

   Theme: light is the product default, dark is an explicit user choice stored
   in localStorage. Both palettes are declared as tokens on :root and
   :root[data-theme='dark'] so one utility class works in either, and no colour
   has its only definition inside a media query. */

@font-face {
  font-family: 'Plus Jakarta Sans';
  src: url('font/plus-jakarta-sans-latin.woff2') format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

:root {
  --paper: #F2EFEA;
  --card: #FFFFFF;
  --raise: #F7F5F1;
  --ink: #14120F;
  --muted: #625D55;
  --faint: #706B63;
  --line: rgba(20, 18, 15, .12);
  --line-strong: rgba(20, 18, 15, .24);
  --wash: rgba(20, 18, 15, .05);
  --accent: #A63F1E;
  --accent-ink: #FFFFFF;
  --accent-wash: rgba(166, 63, 30, .10);
  --inverse: #14120F;
  --inverse-ink: #F7F5F1;
  --nav-glass: rgba(255, 255, 255, .82);
  --shadow-soft: 0 40px 80px -46px rgba(20, 18, 15, .38);
  --shadow-deep: 0 60px 110px -48px rgba(20, 18, 15, .5);
  --doodle-opacity: .034;

  --dur: 220ms;
  --dur-slow: 720ms;
  --ease: cubic-bezier(.16, 1, .3, 1);
}

:root[data-theme='dark'] {
  --paper: #0C0B0A;
  --card: #161513;
  --raise: #121110;
  --ink: #F3F0EA;
  --muted: #A6A099;
  --faint: #8B857C;
  --line: rgba(255, 255, 255, .11);
  --line-strong: rgba(255, 255, 255, .22);
  --wash: rgba(255, 255, 255, .06);
  --accent: #E08155;
  --accent-ink: #1A0B04;
  --accent-wash: rgba(224, 129, 85, .14);
  --inverse: #F3F0EA;
  --inverse-ink: #14120F;
  --nav-glass: rgba(22, 21, 19, .82);
  --shadow-soft: 0 40px 80px -44px rgba(0, 0, 0, .9);
  --shadow-deep: 0 60px 110px -44px rgba(0, 0, 0, .95);
  --doodle-opacity: .045;
}

html { scroll-behavior: smooth; }
body { line-height: 1.6; transition: background-color var(--dur) ease, color var(--dur) ease; }
img { max-width: 100%; height: auto; display: block; }
h2, h1 { text-wrap: balance; }

:where(a, button, summary):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 10px;
}

/* ---------- nav ---------- */
/* A conventional top bar: transparent over the hero, and once the page has
   scrolled a hairline plus a translucent ground so the links stay readable over
   whatever section is passing under it. The glass colours are their own tokens
   because a `/opacity` modifier over a var()-backed colour emits no rule at all
   (all-lessons.md), which would leave this bar fully transparent while scrolled. */
.nav-bar {
  position: fixed;
  top: 0;
  inset-inline: 0;
  z-index: 50;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--dur) ease, border-color var(--dur) ease, backdrop-filter var(--dur) ease;
}
.nav-bar[data-stuck='true'] {
  background: var(--nav-glass);
  border-bottom-color: var(--line);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
}
.nav-row {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2vw, 28px);
  height: 68px;
}
.nav-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
  font-weight: 800;
  letter-spacing: -.03em;
  font-size: 1.02rem;
}

/* Carries the row's grow so the nav links keep their old position. */
.nav-brand-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  flex: 1 0 auto;
  line-height: 1.1;
}

/* Stacked under the wordmark and indented past the mark, so it reads as a
   byline rather than a nav item. Outside the brand link on purpose: the link's
   accessible name stays "KITAPOS" and the lockup is never "KITAPOS by …". */
.brand-by {
  margin-left: 36px;
  margin-top: 1px;
  color: var(--faint, var(--muted));
  font-weight: 500;
  font-size: .68rem;
  letter-spacing: .01em;
  white-space: nowrap;
}
/* Brand and actions each take the leftover space so the links sit centred, and
   the actions stay hard right on the breakpoints where the links are hidden —
   an adjacent-sibling rule cannot do that, because `hidden` only sets
   `display: none` and the element is still there for the selector to match. */
.nav-links {
  align-items: center;
  gap: clamp(18px, 2vw, 30px);
  flex: none;
  font-size: .92rem;
  font-weight: 600;
  color: var(--muted);
}
.nav-links a { transition: color var(--dur) ease; }
.nav-links a:hover { color: var(--ink); }
.nav-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex: 1 0 auto; }

.brand-mark {
  width: 26px;
  height: 26px;
  display: block;
  background: currentColor;
  mask: url('img/logo.svg') center / contain no-repeat;
  -webkit-mask: url('img/logo.svg') center / contain no-repeat;
}
.theme-toggle {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  cursor: pointer;
  transition: background-color var(--dur) ease, transform var(--dur) var(--ease);
}
.theme-toggle:hover { background: var(--wash); }
.theme-toggle:active { transform: scale(.94); transition-duration: 60ms; }
.theme-toggle .ic-moon { display: none; }
:root[data-theme='dark'] .theme-toggle .ic-moon { display: block; }
:root[data-theme='dark'] .theme-toggle .ic-sun { display: none; }

/* ---------- masuk ---------- */
/* Two surfaces have two separate logins and there is deliberately no chooser
   page, so the choice is made here rather than by inventing a /login route. */
.nav-login { position: relative; display: none; }
@media (min-width: 640px) { .nav-login { display: block; } }
.nav-login-btn { display: inline-flex; align-items: center; gap: 6px; }
.nav-login-btn svg { transition: transform var(--dur) var(--ease); }
.nav-login-btn[aria-expanded='true'] svg { transform: rotate(180deg); }
.nav-login-menu {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 258px;
  display: grid;
  gap: 2px;
  padding: 8px;
  border-radius: 22px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-soft);
  animation: sheet-in 180ms var(--ease);
}
.nav-login-menu[hidden] { display: none; }
.nav-login-menu a {
  display: grid;
  align-content: center;
  min-height: 52px;
  padding: 6px 12px;
  border-radius: 12px;
  transition: background-color var(--dur) ease;
}
.nav-login-menu a:hover { background: var(--wash); }
.nav-login-menu strong { font-size: .95rem; font-weight: 700; color: var(--ink); }
.nav-login-menu span { font-size: .78rem; color: var(--muted); }

/* ---------- mobile nav ---------- */
.nav-burger {
  width: 38px;
  height: 38px;
  display: none;
  place-items: center;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  cursor: pointer;
  transition: background-color var(--dur) ease;
}
.nav-burger:hover { background: var(--wash); }
.nav-burger > span { display: grid; gap: 4px; width: 16px; }
.nav-burger i {
  display: block;
  height: 1.8px;
  border-radius: 2px;
  background: currentColor;
  transition: transform var(--dur) var(--ease), opacity 120ms ease;
}
.nav-burger[aria-expanded='true'] i:nth-child(1) { transform: translateY(5.8px) rotate(45deg); }
.nav-burger[aria-expanded='true'] i:nth-child(2) { opacity: 0; }
.nav-burger[aria-expanded='true'] i:nth-child(3) { transform: translateY(-5.8px) rotate(-45deg); }
@media (max-width: 1023px) { .nav-burger { display: grid; } }

.nav-sheet {
  position: absolute;
  top: 100%;
  left: clamp(12px, 4vw, 28px);
  right: clamp(12px, 4vw, 28px);
  display: grid;
  margin-top: 10px;
  padding: 8px;
  border-radius: 22px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-soft);
  animation: sheet-in 200ms var(--ease);
}
.nav-sheet[hidden] { display: none; }
@keyframes sheet-in { from { opacity: 0; transform: translateY(-8px); } }
.nav-sheet a {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding-inline: 14px;
  border-radius: 14px;
  font-size: .98rem;
  font-weight: 600;
  color: var(--ink);
  transition: background-color var(--dur) ease;
}
.nav-sheet a:hover { background: var(--wash); }
/* A wrapper rather than `:first-of-type` on the login links — that pseudo-class
   is scoped to the element TYPE, so it would have matched the first <a> in the
   sheet, which is "Untuk Pelanggan". */
.nav-sheet-foot { display: grid; margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }
.nav-sheet-foot a { color: var(--muted); font-weight: 500; }

/* Below this the bar cannot hold a wordmark, a toggle, a login and a CTA on one
   line, and the brand is the half that survives as a mark. */
@media (max-width: 420px) {
  .nav-row { height: 62px; gap: 10px; }
  .brand-label { display: none; }
  /* Measured at 390px: mark + actions already end at 386 of 390, and without the
     wordmark beside it the byline would read "by Laju Labs" attached to nothing.
     The name still carries on this screen, in the footer and every legal page. */
  .brand-by { display: none; }
}

/* ---------- hero atmosphere ---------- */
.hero-wash {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(110% 75% at 82% 6%, var(--accent-wash), transparent 60%),
    radial-gradient(80% 60% at 4% 98%, var(--wash), transparent 64%);
}
.hero-doodles {
  position: absolute;
  inset: 0;
  z-index: 1;
  background-image: url('img/doodles.webp');
  background-size: 400px auto;
  background-repeat: repeat;
  opacity: var(--doodle-opacity);
  mask-image: radial-gradient(120% 90% at 50% 26%, #000 18%, transparent 76%);
  -webkit-mask-image: radial-gradient(120% 90% at 50% 26%, #000 18%, transparent 76%);
  pointer-events: none;
  filter: invert(1);
}
:root[data-theme='dark'] .hero-doodles { filter: none; }

/* ---------- headline mask reveal ---------- */
h1 .line {
  display: block;
  overflow: hidden;
  padding-block: .04em .16em;
  margin-bottom: -.14em;
}
h1 .line-in { display: block; will-change: transform; }
.js h1 .line-in { transform: translateY(108%); opacity: 0; }
.js.ready h1 .line-in {
  transform: none;
  opacity: 1;
  transition: transform 900ms var(--ease), opacity 620ms var(--ease);
}
.js.ready h1 .line:nth-child(2) .line-in { transition-delay: 110ms; }

.js .rise { opacity: 0; transform: translateY(16px); }
.js.ready .rise {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  transition-delay: var(--d, 0ms);
}

/* ---------- hero: one product, four scroll scenes ---------- */
/* Ordinary grid, spacing and type stay in Uno utilities. This state layer owns
   the sticky stage and the overlapping physical-device renders that cannot be
   expressed as independent utility boxes. Scrolling changes the whole sales
   argument, while the hardware silhouette remains a stable visual anchor. */
.hero-story { min-height: 100dvh; overflow: clip; }
.hero-sticky {
  position: relative;
  min-height: 100dvh;
  isolation: isolate;
}
.js .hero-story { height: 440dvh; }
.js .hero-sticky {
  position: sticky;
  top: 0;
  height: 100dvh;
  overflow: hidden;
}
.hero-story-region { z-index: 2; }
.hero-copy-frame {
  position: relative;
  min-height: 340px;
}
.hero-copy {
  position: absolute;
  inset: 0 0 auto;
  opacity: 0;
  visibility: hidden;
  filter: blur(2px);
  transform: translate3d(0, 8px, 0);
  pointer-events: none;
  transition:
    opacity 460ms var(--ease),
    transform 460ms var(--ease),
    filter 460ms var(--ease),
    visibility 0s linear 460ms;
  will-change: opacity, transform, filter;
}
.hero-copy[data-active='true'] {
  opacity: 1;
  visibility: visible;
  filter: none;
  transform: none;
  pointer-events: auto;
  transition-delay: 70ms, 70ms, 70ms, 0s;
}
.hero-actions {
  position: absolute;
  inset: auto 0 0;
  z-index: 3;
}
.hero-actions .btn-line {
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.hero-device-stage {
  position: relative;
  height: min(61dvh, 620px);
  min-height: 420px;
  isolation: isolate;
}
.hero-device {
  position: absolute;
  z-index: 1;
  inset: 50% -7% auto auto;
  width: min(112%, 760px);
  max-width: none;
  opacity: 0;
  visibility: hidden;
  filter: blur(2px);
  transform: translate3d(18px, calc(-50% + 8px), 0) scale(.975);
  transition:
    opacity 500ms var(--ease),
    transform 500ms var(--ease),
    filter 500ms var(--ease),
    visibility 0s linear 500ms;
  will-change: opacity, transform, filter;
  pointer-events: none;
}
.hero-device[data-active='true'] {
  opacity: 1;
  visibility: visible;
  filter: none;
  transform: translate3d(0, -50%, 0) scale(1);
  transition-delay: 50ms, 50ms, 50ms, 0s;
}
.hero-story[data-scene='1'] .hero-device[data-hero-device='orders'] {
  transform: translate3d(-1.5%, -50%, 0) scale(1.035);
}
.hero-storefront {
  position: absolute;
  z-index: 3;
  left: 1%;
  bottom: 1%;
  width: min(25%, 170px);
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  filter: drop-shadow(0 28px 22px rgba(20, 18, 15, .22));
  transform: rotate(-4deg);
  transform-origin: 50% 100%;
  transition: opacity 440ms var(--ease), transform 440ms var(--ease), filter 440ms var(--ease);
  will-change: opacity, transform, filter;
}
.hero-storefront:hover { transform: rotate(-2deg) translate3d(0, -5px, 0); }
.hero-story:not([data-scene='0']) .hero-storefront {
  opacity: 0;
  filter: blur(3px);
  transform: translate3d(-18px, 16px, 0) rotate(-7deg) scale(.94);
  pointer-events: none;
}
.hero-story-tabs {
  position: relative;
  z-index: 5;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid var(--line);
  border-radius: 999px;
  background: color-mix(in srgb, var(--card) 78%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--card) 86%, transparent), var(--shadow-soft);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  isolation: isolate;
}
.hero-tab-indicator {
  position: absolute;
  z-index: 0;
  inset-block: 3px;
  inset-inline-start: 3px;
  width: calc((100% - 6px) / 4);
  border-radius: 999px;
  background: var(--accent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 10px 22px -14px var(--accent);
  pointer-events: none;
  transition: transform var(--dur) var(--ease);
  will-change: transform;
}
.hero-story[data-scene='1'] .hero-tab-indicator { transform: translate3d(100%, 0, 0); }
.hero-story[data-scene='2'] .hero-tab-indicator { transform: translate3d(200%, 0, 0); }
.hero-story[data-scene='3'] .hero-tab-indicator { transform: translate3d(300%, 0, 0); }
.hero-story-tabs button {
  position: relative;
  z-index: 1;
  min-width: 0;
  border: 0;
  border-radius: 999px;
  color: var(--muted);
  background: transparent;
  font-weight: 800;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur) ease, transform var(--dur) var(--ease);
}
.hero-story-tabs button:hover { color: var(--ink); }
.hero-story-tabs button:active { transform: scale(.96); transition-duration: 80ms; }
.hero-story-tabs button[aria-pressed='true'] {
  color: var(--accent-ink);
}
.hero-tab-short { display: none; }

/* Every section after the hero belongs to one opaque sheet. The entire sheet
   spends one viewport travelling over the completed Owner scene; keeping the
   following content in the same stacking context prevents the sticky hero
   from bleeding back through after the short proof band has passed. */
.post-hero-sheet {
  position: relative;
  z-index: 8;
  background: var(--paper);
  border-radius: clamp(24px, 3vw, 42px) clamp(24px, 3vw, 42px) 0 0;
  box-shadow: 0 -34px 90px -52px rgba(20, 18, 15, .56);
  overflow: clip;
}
.js .post-hero-sheet { margin-top: -100dvh; }
:root[data-theme='dark'] .post-hero-sheet { box-shadow: 0 -34px 90px -44px rgba(0, 0, 0, .92); }

/* Reused by the interactive phone farther down the page. */
.phone-demo-badge {
  position: absolute;
  left: 50%;
  bottom: 4%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  padding: 7px 13px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: -.01em;
  box-shadow: 0 10px 24px -12px rgba(0, 0, 0, .55);
}

@media (max-width: 639px) {
  .js .hero-story { height: 460dvh; }
  .hero-copy-frame { min-height: 252px; }
  .hero-actions { flex-wrap: nowrap; }
  .hero-device-stage { height: 29dvh; min-height: 220px; max-height: 274px; }
  .hero-device { inset-inline-end: -5%; width: 104%; }
  .hero-storefront { left: 3%; bottom: -2%; width: min(22%, 82px); }
  .hero-storefront .phone-demo-badge { display: none; }
  .hero-story-tabs button { min-height: 36px; padding: 6px 5px; font-size: .68rem; }
  .hero-tab-full { display: none; }
  .hero-tab-short { display: inline; }
  .post-hero-sheet { border-radius: 24px 24px 0 0; }
}

@media (min-width: 1024px) and (max-width: 1279px) {
  .hero-device { inset-inline-end: -1%; width: 102%; }
}

@media (min-width: 640px) and (max-width: 1023px) {
  .hero-copy-frame { min-height: 290px; }
  .hero-device-stage { height: min(43dvh, 390px); min-height: 310px; }
  .hero-device { inset-inline-end: 1%; width: min(94%, 650px); }
  .hero-storefront { left: 10%; width: min(19%, 125px); }
}

/* ---------- marquee ---------- */
.marquee {
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  overflow: hidden;
}
.marquee-track { display: flex; width: max-content; animation: slide 38s linear infinite; }
.marquee-set { display: flex; align-items: center; gap: clamp(36px, 6vw, 76px); padding-right: clamp(36px, 6vw, 76px); }
.marquee-mark {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  white-space: nowrap;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 700;
  letter-spacing: -.02em;
  font-size: clamp(1.02rem, 1.9vw, 1.35rem);
  color: var(--ink);
}
.marquee-mark img {
  width: clamp(38px, 4vw, 50px);
  height: auto;
  flex: none;
}
@keyframes slide { to { transform: translate3d(-50%, 0, 0); } }

/* ---------- point lists ---------- */
.point { display: grid; grid-template-columns: 20px 1fr; gap: 14px; align-items: start; }
.point svg { margin-top: 4px; color: var(--accent); }
.point strong { display: block; font-weight: 700; letter-spacing: -.01em; }
.point span { color: var(--muted); font-size: .94rem; }

/* ---------- sebelum / sesudah ledger ---------- */
/* Two aligned columns rather than two stacked panels: one grid owns both sides,
   so the pairs cannot drift out of line as copy length changes. The "sebelum"
   side is deliberately flat and faint and the "sesudah" side is the only thing
   carrying a surface, which is what makes the direction readable before a word
   is read. Positional words are kept OUT of the copy above because this whole
   thing stacks vertically under 768px. */
.ba { --ba-gap: clamp(12px, 2vw, 28px); --ba-chip: 34px; }

.ba-head {
  display: grid;
  grid-template-columns: minmax(0, .82fr) var(--ba-chip) minmax(0, 1fr);
  gap: var(--ba-gap);
  align-items: center;
  margin-bottom: 14px;
}
.ba-head p { margin: 0; font-size: .82rem; font-weight: 700; letter-spacing: -.01em; }
/* Desktop: the middle cell is only a spacer holding the chip column open, so the
   arrow inside it stays hidden. Under 768px the two columns stop existing and
   the pair becomes a single legend line, where the arrow is what says which
   way to read it.
   Hide the GLYPH, never the cell: `display:none` on a grid item removes it from
   the grid entirely, which reflowed "Dengan KITAPOS" into the 34px chip column
   and wrapped it. Reading grid-template-columns does not catch that, because
   the template stays correct while the items land in the wrong cells. */
.ba-head-arrow { display: grid; place-items: center; color: var(--faint); }
.ba-head-arrow svg { display: none; }
.ba-head-l { color: var(--muted); }
.ba-head-r { color: var(--accent); }

.ba-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
/* Headroom for the mascot poking up out of the first card. */
.ba-list > li:first-child { margin-top: 34px; }

.ba-row {
  display: grid;
  grid-template-columns: minmax(0, .82fr) var(--ba-chip) minmax(0, 1fr);
  gap: var(--ba-gap);
  align-items: center;
}

.ba-before {
  margin: 0;
  padding: clamp(15px, 2vw, 22px) 0;
  /* --muted, NOT --faint: as a small metadata label --faint is fine, but this is
     a paragraph and it measured 3.81:1 on light paper, under the 4.5:1 floor.
     The "sebelum" side reads quieter because it carries no surface and no
     weight, never because its text is hard to read. */
  color: var(--muted);
  font-size: .95rem;
  line-height: 1.55;
}

.ba-link {
  width: var(--ba-chip);
  height: var(--ba-chip);
  display: grid;
  place-items: center;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--faint);
  transition: color var(--dur) ease, border-color var(--dur) ease, transform var(--dur) var(--ease);
}

.ba-after {
  padding: clamp(15px, 2vw, 22px) clamp(18px, 2.2vw, 26px);
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--card);
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}
/* Si Doeh hiding behind the first card. Anchored to the CARD, not the row, so
   the same offsets hold once the row collapses to one column under 768px. The
   z-index:-1 puts him behind the card's own background while still painting
   over the page, which is what leaves exactly the top half of him showing. */
.ba-after { position: relative; }
.ba-doeh {
  position: absolute;
  z-index: -1;
  right: 26px;
  top: -96px;
  width: auto;
  height: 132px;
  pointer-events: none;
  user-select: none;
}

.ba-after strong { display: block; font-weight: 700; font-size: 1.02rem; letter-spacing: -.015em; }
.ba-after span { display: block; margin-top: 6px; color: var(--muted); font-size: .92rem; line-height: 1.55; }

.ba-row:hover .ba-link { color: var(--accent); border-color: var(--accent); transform: translateX(2px); }
.ba-row:hover .ba-after { border-color: var(--line-strong); box-shadow: var(--shadow-soft); }

/* Not shipped yet. The tag is the whole reason these two rows may sit here at
   all; if the feature lands, delete the tag rather than softening it. */
.ba-soon {
  display: inline-block;
  margin-left: 8px;
  vertical-align: 2px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--accent);
  font-style: normal;
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .04em;
}

@media (max-width: 767px) {
  .ba-head { grid-template-columns: auto auto auto; justify-content: start; gap: 8px; }
  .ba-head-arrow svg { display: block; }
  .ba-list { gap: 26px; }
  .ba-row { grid-template-columns: 1fr; gap: 0; }
  .ba-before { padding: 0 0 12px; }
  .ba-link { transform: rotate(90deg); margin: 0 0 12px 4px; }
  .ba-row:hover .ba-link { transform: rotate(90deg); }
  /* One column means the "sebelum" paragraph runs full width directly above the
     card, so the desktop size sent his steam straight through the copy. Small
     enough here that he clears the text and only rises into the arrow gap. */
  .ba-doeh { height: 92px; top: -68px; right: 14px; }
}

/* ---------- screenshots and zoom ---------- */
.shot, .pan-shot {
  position: relative;
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--card);
  box-shadow: var(--shadow-soft);
}
.zoom-badge {
  position: absolute;
  right: 12px;
  bottom: 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  border-radius: 999px;
  background: rgba(16, 14, 12, .82);
  color: #F7F5F1;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: -.01em;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: .92;
  transition: opacity var(--dur) ease, transform var(--dur) var(--ease);
  pointer-events: none;
}
.js [data-zoom] { cursor: zoom-in; }
.js [data-zoom]:hover .zoom-badge { opacity: 1; transform: translateY(-2px); }

.phone-hand {
  position: relative;
  display: block;
  width: min(420px, 100%);
  cursor: pointer;
  filter: drop-shadow(0 40px 52px rgba(20, 18, 15, .30));
  transition: transform var(--dur) var(--ease), filter var(--dur) ease;
}
:root[data-theme='dark'] .phone-hand { filter: drop-shadow(0 40px 52px rgba(0, 0, 0, .75)); }
.phone-hand:hover { transform: translateY(-6px); }
.phone-hand:active { transform: translateY(-2px) scale(.995); transition-duration: 80ms; }
.phone-hand .phone-demo-badge { left: 57%; bottom: 25%; }

/* ---------- product tour ---------- */
.pan-head { padding-block: clamp(48px, 7vw, 84px) clamp(20px, 3vw, 30px); }
.pan-rail {
  height: 2px;
  background: var(--line);
  border-radius: 999px;
  margin-top: clamp(20px, 3vw, 30px);
  overflow: hidden;
}
.pan-fill { display: block; height: 100%; width: 100%; background: var(--accent); transform: scaleX(var(--p, 0)); transform-origin: left; }
.pan-track {
  display: flex;
  gap: clamp(16px, 2vw, 26px);
  padding-inline: max(20px, calc((100vw - 1240px) / 2 + 20px));
  will-change: transform;
}
.pan-card {
  flex: 0 0 min(560px, 84vw);
  border: 1px solid var(--line);
  border-radius: 26px;
  background: var(--card);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--shadow-soft);
}
/* The box carries the screenshots' own 1560x980, so `cover` has nothing left to
   crop. A fixed height here previously cut every shot down to its top-left
   corner, which is what made the tour read as five slices rather than five
   screens. Change this ratio only alongside the assets it describes. */
.pan-shot { aspect-ratio: 1560 / 980; margin-bottom: 6px; box-shadow: none; }
.pan-shot img { width: 100%; height: 100%; object-fit: cover; }
.pan-card h3 { font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 700; font-size: 1.18rem; letter-spacing: -.025em; }
.pan-card p { color: var(--muted); font-size: .93rem; }

.pan-stick { overflow-x: auto; scroll-snap-type: x mandatory; }
.pan-card { scroll-snap-align: center; }
.js .pan { position: relative; }
.js .pan-stick {
  position: sticky;
  top: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(18px, 3vw, 34px);
  overflow: hidden;
  scroll-snap-type: none;
}
.js .pan-head { padding-block: 0; }

/* ---------- cost ---------- */
.biaya-wash { position: absolute; inset: 0; background: radial-gradient(70% 55% at 50% 0%, var(--accent-wash), transparent 62%); }
.rate-table {
  margin-top: 3.5rem;
  display: grid;
  gap: 1px;
  background: var(--line);
  border-radius: 24px;
  overflow: hidden;
  border: 1px solid var(--line);
  max-width: 880px;
  margin-inline: auto;
}
.rate {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(0, 2.2fr) auto;
  gap: clamp(14px, 3vw, 32px);
  align-items: center;
  padding: 20px clamp(20px, 3vw, 30px);
  background: var(--card);
}
.rate.is-us { background: var(--accent-wash); }
.rate-name { font-weight: 700; letter-spacing: -.01em; }
.rate.is-us .rate-name { color: var(--accent); }
.rate-bar { height: 3px; border-radius: 999px; background: var(--line-strong); width: var(--w); }
.rate.is-us .rate-bar { background: var(--accent); }
.rate-val {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  font-size: clamp(1.2rem, 2.6vw, 1.7rem);
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.rate.is-us .rate-val { color: var(--accent); }
@media (max-width: 560px) {
  .rate { grid-template-columns: 1fr auto; }
  .rate-bar { grid-column: 1 / -1; order: 3; }
}

/* Cost calculator. Compares KITAPOS against the three ways POS vendors charge
   (flat subscription, per-order fee, percentage of sales) and names no vendor:
   masking a competitor's name still identifies it, so the structure is the
   subject rather than the company. Every figure comes from the visitor. */
.calc {
  display: grid;
  gap: clamp(24px, 3vw, 40px);
  margin: clamp(40px, 5vw, 64px) 0 0;
  align-items: start;
}
@media (min-width: 980px) { .calc { grid-template-columns: minmax(340px, 5fr) 7fr; } }

.calc-panel {
  padding: clamp(22px, 2.6vw, 30px);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 20px;
}

.calc-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; background: var(--wash); border-radius: 14px; }
.calc-tab {
  min-height: 44px;
  padding: 8px 6px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: .78rem;
  font-weight: 700;
  line-height: 1.25;
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.calc-tab:hover { color: var(--ink); }
.calc-tab[aria-pressed='true'] { background: var(--card); color: var(--accent); box-shadow: 0 1px 3px rgb(0 0 0 / .10); }

.calc-note { margin: 14px 0 0; font-size: .84rem; line-height: 1.5; color: var(--muted); min-height: 2.6em; }

.calc-plan { margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line); display: grid; gap: 10px; }
.calc-plan-opts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.calc-plan-opt {
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: .82rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.calc-plan-opt:hover { color: var(--ink); border-color: var(--line-strong); }
.calc-plan-opt[aria-pressed='true'] { background: var(--accent-wash); border-color: var(--accent); color: var(--accent); }

.calc-plan-note { margin: 10px 0 0; font-size: .78rem; line-height: 1.5; color: var(--faint); }
.calc-fields { display: grid; gap: 20px; margin-top: 22px; }
.calc-ctl { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 4px 16px; }
.calc-ctl[hidden] { display: none; }
.calc-lab { font-size: .82rem; font-weight: 700; color: var(--muted); }
.calc-out {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);
}
.calc-derived { margin: 18px 0 0; font-size: .8rem; color: var(--faint); }
.calc-derived[hidden] { display: none; }

.calc-range { grid-column: 1 / -1; width: 100%; margin-top: 10px; appearance: none; background: transparent; }
.calc-range::-webkit-slider-runnable-track { height: 3px; border-radius: 999px; background: var(--line-strong); }
.calc-range::-moz-range-track { height: 3px; border-radius: 999px; background: var(--line-strong); }
/* Drawn at 22px, caught at 44px via the input's own height. */
.calc-range::-webkit-slider-thumb {
  appearance: none; width: 22px; height: 22px; margin-top: -9.5px;
  border-radius: 999px; background: var(--accent); border: 4px solid var(--card);
  box-shadow: 0 1px 6px rgb(0 0 0 / .22); cursor: grab;
}
.calc-range::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 999px; background: var(--accent);
  border: 4px solid var(--card); box-shadow: 0 1px 6px rgb(0 0 0 / .22); cursor: grab;
}
.calc-range:active::-webkit-slider-thumb { cursor: grabbing; }
.calc-range:focus-visible { outline: none; }
.calc-range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--accent-wash); }
.calc-range:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px var(--accent-wash); }

.calc-result { display: grid; gap: clamp(20px, 2.4vw, 28px); }
@media (min-width: 980px) { .calc-result { min-height: 100%; align-content: space-between; } }
.calc-rows { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 18px; overflow: hidden; }
.calc-row {
  display: grid;
  grid-template-columns: minmax(150px, 1.15fr) minmax(0, 1.3fr) auto;
  gap: clamp(14px, 2.4vw, 28px);
  align-items: center;
  padding: 20px clamp(18px, 2.2vw, 26px);
  background: var(--card);
}
.calc-row.is-us { background: var(--accent-wash); }
.calc-row-name { display: grid; gap: 3px; font-weight: 700; font-size: .92rem; letter-spacing: -.01em; }
.calc-row-sub { font-size: .74rem; font-weight: 500; line-height: 1.4; color: var(--faint); letter-spacing: 0; }
.calc-row.is-us .calc-row-sub { color: var(--muted); }
.calc-row.is-us .calc-row-name { color: var(--accent); }
.calc-row-bar {
  height: 3px; border-radius: 999px; background: var(--line-strong);
  width: var(--w, 50%);
  transition: width 380ms var(--ease);
}
.calc-row.is-us .calc-row-bar { background: var(--accent); }
.calc-row-val {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  font-size: clamp(1.1rem, 2.2vw, 1.5rem);
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.calc-row.is-us .calc-row-val { color: var(--accent); }

.calc-delta-lab { margin: 0; font-size: .8rem; font-weight: 700; color: var(--faint); }
.calc-delta {
  margin: 6px 0 0;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  color: var(--accent);
  line-height: .9;
  letter-spacing: -.05em;
  font-variant-numeric: tabular-nums;
  font-size: clamp(2.6rem, 7vw, 5.2rem);
}
.calc.is-behind .calc-delta { color: var(--ink); }
/* Switching the model changes what the figure is ABOUT, so it settles in from a
   pre-state. A slider drag is one continuous value and gets no swap. */
@keyframes calc-swap {
  from { opacity: 0; transform: translateY(6px) scale(.985); filter: blur(3px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
.calc-delta.is-swap { animation: calc-swap 380ms var(--ease) both; }
.calc-cross { margin: 0; font-size: .9rem; line-height: 1.6; color: var(--muted); max-width: 54ch; }

@media (prefers-reduced-motion: reduce) {
  .calc-row-bar, .calc-tab, .calc-plan-opt { transition: none; }
  .calc-delta.is-swap { animation: none; }
}

/* ---------- pricing ---------- */
.plan-name { font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 700; font-size: 1.3rem; letter-spacing: -.02em; }
.plan-price { font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 800; font-size: 2.3rem; letter-spacing: -.045em; margin-top: .75rem; }
.plan-price.is-big { font-size: clamp(2.6rem, 4.4vw, 3.2rem); letter-spacing: -.05em; }
.plan-price span { font-family: 'Plus Jakarta Sans', sans-serif; font-size: .95rem; font-weight: 600; color: var(--faint); letter-spacing: 0; }
.plan-quota { color: var(--accent); font-weight: 700; font-size: .92rem; margin-top: .5rem; }
.plan-list { display: grid; gap: .7rem; font-size: .93rem; color: var(--muted); }
.plan-list li { display: grid; grid-template-columns: 18px 1fr; gap: .65rem; }
.plan-list svg { margin-top: 5px; color: var(--accent); }
.plan-hero {
  border-radius: 30px;
  border: 1px solid var(--accent);
  background: linear-gradient(180deg, var(--accent-wash), transparent 58%), var(--card);
  box-shadow: var(--shadow-deep);
}
.addon {
  margin-top: 1.25rem;
  border: 1px dashed var(--line-strong);
  border-radius: 18px;
  padding: 20px 24px;
  color: var(--muted);
  font-size: .93rem;
}
.addon strong { color: var(--ink); }
/* ---------- comparison table ---------- */
.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;
}
.cmp-wrap {
  /* `relative` is load-bearing, not cosmetic. The table's `.sr-only` cells are
     `position: absolute` with no positioned ancestor, so their containing block
     was the viewport and this scroll container never clipped them: the document
     grew to the table's full 620px and iOS Safari answered by shrinking the
     WHOLE page to fit, which reads as a site that was never made responsive. */
  position: relative;
  overflow-x: auto;
  border-radius: 26px;
  -webkit-overflow-scrolling: touch;
}
/* The table fits the shell above 1080px, so the scroll container is dropped
   there. A scroll container on any axis traps position:sticky inside it, and
   the header then silently stops sticking. */
@media (min-width: 1080px) {
  .cmp-wrap { overflow: visible; }
  /* Only the plan columns follow the reader down. The intro block on the left is
     a one-off piece of copy, not a column header, so pinning it would drag a
     paragraph through the whole table. */
  .cmp thead th.cmp-corner { position: static; }
}
.cmp {
  width: 100%;
  min-width: 940px;
  border-collapse: separate;
  border-spacing: 0;
  text-align: left;
}
.cmp thead th {
  position: sticky;
  top: 78px;
  z-index: 3;
  background: var(--raise);
  vertical-align: bottom;
  padding: 0 0 18px;
}
.cmp-corner { width: 36%; }
.cmp-corner-in { display: block; padding: 0 24px 0 0; max-width: 34ch; }
.cmp-corner-in .eyebrow { display: block; margin-bottom: .55rem; }
.cmp-corner-line {
  display: block;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  font-size: clamp(1.3rem, 2.1vw, 1.75rem);
  letter-spacing: -.035em;
  line-height: 1.08;
  color: var(--ink);
}
.cmp-corner-sub { display: block; margin-top: .55rem; font-size: .86rem; color: var(--muted); line-height: 1.5; }
@media (max-width: 1079px) { .cmp-corner-in { display: none; } }
.cmp-plan {
  width: 16%;
  padding-inline: 16px !important;
  padding-top: 22px !important;
  text-align: center;
  border-top: 1px solid var(--line);
  border-inline: 1px solid var(--line);
  border-radius: 22px 22px 0 0;
  background: linear-gradient(180deg, var(--card), var(--card) 64%, var(--raise)) !important;
}
.cmp-plan {
  transition:
    border-radius 260ms var(--ease),
    box-shadow 260ms var(--ease),
    border-color 260ms var(--ease),
    padding 260ms var(--ease);
}
/* data-stuck is written by app.js from a scroll read, not by an
   IntersectionObserver: the question here is "is this cell currently pinned",
   and an observer answers a different one (has a sentinel left the viewport). */
.cmp[data-stuck='true'] .cmp-plan {
  border-radius: 22px;
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-soft);
  padding-bottom: 20px !important;
  background: var(--card) !important;
}
.cmp[data-stuck='true'] .cmp-plan.is-hero {
  border-bottom-color: var(--accent);
  background: linear-gradient(180deg, var(--accent-wash), transparent 76%), var(--card) !important;
}
.cmp-plan.is-hero {
  border-color: var(--accent);
  background:
    linear-gradient(180deg, var(--accent-wash), transparent 76%),
    linear-gradient(180deg, var(--card), var(--card) 64%, var(--raise)) !important;
}
.cmp-plan > * { display: block; }
.cmp-flag {
  font-size: .64rem;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: .5rem;
}
.cmp-plan .plan-name { font-size: 1.08rem; }
.cmp-was {
  display: block;
  font-size: .68rem;
  font-weight: 600;
  color: var(--faint);
  letter-spacing: .01em;
  margin-top: .35rem;
  white-space: nowrap;
}
.cmp-was s { text-decoration-thickness: 1.5px; }
.cmp-price {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  /* Four plan columns instead of three: at the old size "Rp 199rb" broke after
     the "Rp" and the price read as two lines. nowrap is the guard, the smaller
     clamp is what makes nowrap fit. */
  font-size: clamp(1.25rem, 1.7vw, 1.6rem);
  white-space: nowrap;
  letter-spacing: -.045em;
  margin-top: .3rem;
  color: var(--ink);
}
.cmp-price small {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: .78rem;
  font-weight: 600;
  color: var(--faint);
  letter-spacing: 0;
}
.cmp-note {
  font-size: .76rem;
  color: var(--faint);
  line-height: 1.35;
  margin: .45rem 0 .9rem;
  min-height: 2.1em;
}
.cmp-hint { display: none; }
@media (max-width: 1079px) {
  .cmp-hint {
    display: block;
    margin: 0 0 10px;
    font-size: .78rem;
    font-weight: 600;
    color: var(--faint);
  }
}
.cmp-group td { border-top: 0 !important; }
.cmp-group th {
  padding: 30px 0 10px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--faint);
}
.cmp tbody tr:not(.cmp-group) th,
.cmp tbody td {
  border-top: 1px solid var(--line);
  padding: 13px 16px;
  vertical-align: middle;
}
.cmp tbody tr:not(.cmp-group) th {
  padding-left: 0;
  font-weight: 500;
  font-size: .93rem;
  color: var(--muted);
}
.cmp tbody td {
  text-align: center;
  border-inline: 1px solid transparent;
}
/* Tint only. The two accent rails ran the full height of a 41-row table and
   the header cell above them is a rounded card, so wherever the card's corner
   curved away from the rail the line carried straight on past it — a red line
   outside the box it belongs to, and worst exactly when the header is pinned
   and the card is floating. The tinted column already says which plan is
   highlighted, and it has no edge to escape from. */
.cmp tbody td.is-hero { background: var(--accent-wash); }
.cmp tbody:last-of-type tr:last-child td.is-hero { border-radius: 0 0 22px 22px; }
.cmp .ck { color: var(--accent); }
/* A locked feature reads as a dash, never a red cross: the table sells three
   plans at once, so a cell that shouts "missing" makes the cheap plans look
   broken instead of smaller. sr-only text carries the real meaning. */
.cmp .xx { color: var(--faint); font-weight: 700; opacity: .55; }
.cmp-soon {
  display: inline-block;
  margin-left: 7px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-wash);
  color: var(--accent);
  font-style: normal;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.cmp-val {
  font-size: .86rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.35;
  display: block;
}
/* Narrow screens scroll the plan columns sideways while the feature label stays
   pinned to the left — without that pin the row being compared is off-screen the
   moment the first column scrolls away, which is the whole point of the table. */
@media (max-width: 1079px) {
  .cmp-wrap {
    border: 1px solid var(--line);
    border-radius: 20px;
    background: var(--card);
  }
  .cmp { min-width: 760px; }
  .cmp thead th { background: var(--card); top: 70px; }
  .cmp-plan, .cmp-plan.is-hero { background: var(--card) !important; }
  .cmp-plan.is-hero { background: linear-gradient(180deg, var(--accent-wash), transparent 76%), var(--card) !important; }
  .cmp-corner,
  .cmp-group th,
  .cmp tbody tr:not(.cmp-group) th {
    position: sticky;
    left: 0;
    z-index: 2;
    width: 196px;
    min-width: 196px;
    background: var(--card);
    border-right: 1px solid var(--line);
    padding-left: 14px;
  }
  .cmp thead th.cmp-corner { z-index: 5; }
  .cmp-plan {
    width: 140px;
    min-width: 140px;
    padding-inline: 9px !important;
    padding-top: 16px !important;
  }
  .cmp-plan .plan-name { font-size: .95rem; }
  .cmp-was { font-size: .6rem; margin-top: .25rem; }
  .cmp-price { font-size: 1.18rem; }
  .cmp-price small { font-size: .66rem; }
  .cmp-flag { font-size: .55rem; letter-spacing: .1em; }
  .cmp-note { font-size: .66rem; min-height: 2.6em; }
  .cmp tbody tr:not(.cmp-group) th { font-size: .84rem; }
  .cmp tbody td { padding: 12px 8px; }
  .cmp-val { font-size: .76rem; }
  .cmp-group th { padding: 26px 0 9px 14px; }
}

.chip {
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--card);
  padding: 8px 15px;
  font-size: .85rem;
  font-weight: 600;
  color: var(--muted);
}

/* ---------- steps, faq, footer ---------- */
.step { border-top: 2px solid var(--line-strong); padding-top: 26px; position: relative; }
.step::before { content: ''; position: absolute; top: -2px; left: 0; width: 52px; height: 2px; background: var(--accent); }
.step h3 { font-family: 'Plus Jakarta Sans', sans-serif; font-weight: 700; font-size: 1.2rem; letter-spacing: -.025em; }
.step p { color: var(--muted); margin-top: 10px; font-size: .95rem; }

.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 22px 46px 22px 0;
  font-weight: 700;
  letter-spacing: -.012em;
  position: relative;
  transition: color var(--dur) ease;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent); }
.faq summary::after, .faq summary::before {
  content: '';
  position: absolute;
  right: 10px;
  top: 50%;
  width: 13px;
  height: 2px;
  background: var(--faint);
  transition: transform var(--dur) var(--ease), background-color var(--dur) ease;
}
.faq summary::before { transform: translateY(-50%) rotate(90deg); }
.faq summary::after { transform: translateY(-50%); }
.faq details[open] summary::before { transform: translateY(-50%) rotate(0deg); background: var(--accent); }
.faq details[open] summary::after { background: var(--accent); }
.faq p { color: var(--muted); margin-bottom: 24px; max-width: 66ch; font-size: .95rem; }

.closing-wash { position: absolute; inset: 0; background: radial-gradient(65% 110% at 50% 108%, var(--accent-wash), transparent 62%); }

.foot-col { display: grid; align-content: start; gap: 11px; }
.foot-col h3 { font-weight: 800; font-size: .78rem; letter-spacing: .16em; text-transform: uppercase; color: var(--faint); margin-bottom: 3px; }
.foot-col a { color: var(--muted); font-size: .93rem; transition: color var(--dur) ease; width: fit-content; }
.foot-col a:hover { color: var(--ink); }

/* ---------- modals ---------- */
.modal { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: clamp(12px, 3vw, 32px); }
.modal[hidden] { display: none; }
.modal-scrim { position: absolute; inset: 0; background: rgba(10, 9, 8, .68); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
.modal-panel {
  position: relative;
  width: min(1040px, 100%);
  max-height: min(880px, 92dvh);
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 26px;
  overflow: hidden;
  box-shadow: var(--shadow-deep);
  animation: pop 320ms var(--ease);
}
@keyframes pop { from { opacity: 0; transform: translateY(14px) scale(.985); } }
.modal-head { display: flex; align-items: start; justify-content: space-between; gap: 20px; padding: 22px clamp(20px, 3vw, 30px); border-bottom: 1px solid var(--line); }
.modal-body { display: grid; gap: clamp(20px, 3vw, 36px); padding: clamp(20px, 3vw, 32px); overflow-y: auto; }
@media (min-width: 860px) { .modal-body { grid-template-columns: minmax(0, 366px) minmax(0, 1fr); align-items: start; } }
.icon-btn {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  cursor: pointer;
  transition: background-color var(--dur) ease;
}
.icon-btn:hover { background: var(--wash); }

.zoom-panel { position: relative; max-width: min(1200px, 96vw); max-height: 92dvh; animation: pop 320ms var(--ease); }
.zoom-panel img { max-height: 88dvh; width: auto; border-radius: 16px; border: 1px solid var(--line-strong); box-shadow: var(--shadow-deep); background: #fff; }
.zoom-x { position: absolute; top: -14px; right: -14px; background: var(--paper); }

/* ---------- interactive storefront demo ---------- */
/* A port of the real customer page, not an impression of it. The markup mirrors
   components/storefront/* and every colour is derived by app.js through the same
   three-slot maths as utils/shopTheme.ts, so the token names here (--color-shop,
   --color-shop-ink, ...) are the ones the product itself uses. Changing this to
   look "nicer" than the app is the defect: the whole point of the demo is that
   the visitor is looking at what they will actually get. */
.demo-stage { display: grid; place-items: center; }
.phone-mock {
  position: relative;
  width: 320px;
  max-width: 100%;
  aspect-ratio: 1360 / 2799;
  filter: drop-shadow(0 40px 60px rgba(20, 18, 15, .34));
}
/* Percentages, not pixels: they are read off the frame artwork, so the screen
   stays inside the bezel at any width. Same figures as the HQ preview. */
.phone-mock-screen {
  position: absolute;
  left: 3.16%;
  top: 1.14%;
  width: 94.04%;
  height: 97.68%;
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: 12.2% / 5.7%;
  background: var(--color-shop-surface);
  /* The sticky category nav carries a z-index; without a stacking context here
     it competes with the frame image and paints over the bezel. */
  z-index: 1;
  isolation: isolate;
}
.phone-mock-screen::-webkit-scrollbar { width: 0; }
.phone-mock-frame { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; pointer-events: none; }

.sf {
  --color-shop: #B03A2E;
  --color-shop-on: #FFFFFF;
  --color-shop-tint: #F3E7E4;
  --color-shop-surface: #F7F5F2;
  --color-shop-sunken: #EAE8E5;
  --color-shop-ink: #241C18;
  --color-shop-muted: #7C736E;
  --color-shop-line: rgba(36, 28, 24, .1);
  --color-shop-on-ink: #E0DBD8;
  --color-shop-on-ink-muted: #B7AFAA;
  min-height: 100%;
  border-radius: inherit;
  background: var(--color-shop-surface);
  color: var(--color-shop-ink);
  font-size: 13px;
  line-height: 1.5;
}
.sf-hero { height: 132px; overflow: hidden; background: var(--color-shop-sunken); border-radius: inherit; border-end-start-radius: 0; border-end-end-radius: 0; }
.sf-hero img { width: 100%; height: 100%; object-fit: cover; }

.sf-id { padding: 12px 12px 12px; }
.sf-id-row { display: flex; align-items: flex-start; gap: 9px; }
.sf-logo { width: 34px; height: 34px; flex: none; border-radius: 9px; object-fit: cover; box-shadow: 0 0 0 1px var(--color-shop-line); }
.sf-id-text { min-width: 0; }
.sf-name { font-weight: 700; font-size: 19px; letter-spacing: -.02em; line-height: 1.15; }
.sf-tagline { color: var(--color-shop-muted); font-size: 11.5px; margin-top: 1px; }
.sf-meta { margin-top: 9px; display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; color: var(--color-shop-muted); font-size: 11px; }
.sf-meta b { font-weight: 600; color: var(--color-shop-ink); }

/* Underline tabs, not filled pills — the accent is a 2px rule and the weight
   change carries the state (components/storefront/StorefrontAnchorNav.vue). */
.sf-nav {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  gap: 2px;
  padding-inline: 8px;
  border-bottom: 1px solid var(--color-shop-line);
  background: var(--color-shop-surface);
  overflow-x: auto;
  scrollbar-width: none;
}
.sf-nav::-webkit-scrollbar { height: 0; }
.sf-nav button {
  position: relative;
  flex: none;
  padding: 11px 9px;
  font-size: 12px;
  font-weight: 500;
  color: var(--color-shop-muted);
  cursor: pointer;
  white-space: nowrap;
}
.sf-nav button.is-on { font-weight: 600; color: var(--color-shop-ink); }
.sf-nav button.is-on::after {
  content: '';
  position: absolute;
  left: 9px; right: 9px; bottom: 0;
  height: 2px;
  border-radius: 999px;
  background: var(--color-shop);
}

.sf-banner-sec { padding: 12px 12px 0; }
.sf-banner { position: relative; aspect-ratio: 16 / 9; border-radius: 14px; overflow: hidden; }
.sf-banner img { width: 100%; height: 100%; object-fit: cover; }
.sf-banner::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 66%;
  background: linear-gradient(to top, rgba(0, 0, 0, .85), rgba(0, 0, 0, .35) 45%, transparent);
}
.sf-banner p {
  position: absolute;
  left: 12px; right: 12px; bottom: 9px;
  z-index: 1;
  color: #fff;
  font-weight: 800;
  font-size: 14px;
  letter-spacing: -.01em;
}

.sf-sec { padding: 20px 12px 0; }
.sf-sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.sf-sec-head h4 { font-weight: 600; font-size: 15px; letter-spacing: -.01em; }
.sf-sec-head span { font-size: 11px; color: var(--color-shop-muted); font-variant-numeric: tabular-nums; }
.sf-grid { margin-top: 10px; display: grid; grid-template-columns: 1fr 1fr; gap: 18px 10px; }

/* The whole card is one control — tapping the photo or the name is what people
   actually do, so the + is decorative and the card is the button. */
.sf-card { position: relative; min-width: 0; display: flex; flex-direction: column; text-align: left; cursor: pointer; }
.sf-card-qty[hidden] { display: none; }
.sf-card-media { position: relative; display: block; min-width: 0; }
.sf-card-media > img,
.sf-card-ph { display: grid; place-items: center; width: 100%; aspect-ratio: 4 / 3; border-radius: 11px; background: var(--color-shop-tint); color: var(--color-shop); opacity: .55; }
.sf-card-add {
  position: absolute;
  right: 7px; bottom: -9px;
  width: 27px; height: 27px;
  display: grid; place-items: center;
  border-radius: 999px;
  background: var(--color-shop);
  color: var(--color-shop-on);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  box-shadow: 0 0 0 3px var(--color-shop-surface);
  transition: transform 120ms var(--ease);
}
.sf-card:active .sf-card-add { transform: scale(.92); }
.sf-card-qty {
  position: absolute;
  left: -5px; top: -5px;
  min-width: 18px; height: 18px;
  display: grid; place-items: center;
  padding-inline: 4px;
  border-radius: 999px;
  background: var(--color-shop-ink);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px var(--color-shop-surface);
}
.sf-card h5 { margin-top: 11px; font-weight: 600; font-size: 12.5px; line-height: 1.3; letter-spacing: -.005em; }
.sf-card p { margin-top: 1px; font-size: 11px; color: var(--color-shop-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-card b { display: block; margin-top: 3px; font-weight: 600; font-size: 12.5px; font-variant-numeric: tabular-nums; }

.sf-foot {
  margin-top: 26px;
  padding: 20px 14px 56px;
  background: var(--color-shop-ink);
  color: var(--color-shop-on-ink);
  border-radius: inherit;
  border-start-start-radius: 0;
  border-start-end-radius: 0;
}
.sf-foot-name { color: #fff; font-weight: 600; font-size: 14px; letter-spacing: -.01em; }
.sf-foot-lines { margin-top: 10px; display: grid; gap: 7px; font-size: 11.5px; }
.sf-foot-cred { margin-top: 16px; padding-top: 12px; border-top: 1px solid rgba(255, 255, 255, .12); font-size: 10px; color: var(--color-shop-on-ink-muted); }

/* Docked, not floating: as a free bubble it had no way to avoid whatever it
   happened to overlap. */
.sf-cart {
  position: sticky;
  bottom: 14px;
  z-index: 30;
  margin: -44px 14px 14px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  border-radius: 15px;
  background: var(--color-shop);
  color: var(--color-shop-on);
  box-shadow: 0 18px 34px -18px rgba(0, 0, 0, .55);
}
.sf-cart[hidden] { display: none; }
.sf-cart-n {
  width: 27px; height: 27px; flex: none;
  display: grid; place-items: center;
  border-radius: 9px;
  background: rgba(255, 255, 255, .22);
  font-size: 13px;
  font-weight: 800;
}
.sf-cart-lab { flex: 1; min-width: 0; }
.sf-cart-lab b { display: block; font-size: 12.5px; font-weight: 700; line-height: 1.2; }
.sf-cart-lab small { display: block; font-size: 9.5px; line-height: 1.3; opacity: .8; }
.sf-cart-sum { flex: none; font-size: 12.5px; font-weight: 800; font-variant-numeric: tabular-nums; }

.demo-controls { display: grid; gap: 20px; align-content: start; }
.ctl h4 { font-size: .78rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--faint); margin-bottom: 10px; }
.swatches { display: flex; flex-wrap: wrap; gap: 10px; }
.swatch {
  width: 38px; height: 38px;
  border-radius: 999px;
  border: 2px solid transparent;
  box-shadow: 0 0 0 1px var(--line-strong);
  cursor: pointer;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) ease;
}
.swatch:hover { transform: scale(1.08); }
.swatch[aria-pressed='true'] { box-shadow: 0 0 0 2px var(--ink); transform: scale(1.06); }
.seg { display: inline-flex; padding: 4px; gap: 4px; border-radius: 999px; border: 1px solid var(--line-strong); }
.seg button { border-radius: 999px; padding: 8px 15px; font-size: .85rem; font-weight: 700; color: var(--muted); cursor: pointer; transition: background-color var(--dur) ease, color var(--dur) ease; }
.seg button.is-on { background: var(--inverse); color: var(--inverse-ink); }
.demo-note { font-size: .82rem; color: var(--muted); border-left: 2px solid var(--accent); padding-left: 12px; }

/* ---------- scroll reveal ---------- */
.js .reveal { opacity: 0; transform: translateY(24px); }
.js .reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  transition-delay: var(--d, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .reveal, .js .rise, .js h1 .line-in { opacity: 1; transform: none; }
  .hero-copy, .hero-device, .hero-storefront, .hero-tab-indicator { transition: none; }
  .marquee-track { animation: none; }
  .js .pan-stick { position: static; height: auto; overflow-x: auto; scroll-snap-type: x mandatory; }
  .js .pan-track { transform: none !important; }
  .modal-panel, .zoom-panel, .nav-sheet, .nav-login-menu { animation: none; }
  .cmp-plan { transition: none; }
}

/* ---------- CTA WhatsApp melayang ---------- */
/* Hijau WhatsApp dipakai apa adanya, bukan diterjemahkan ke palet merek: tombol
   ini menjanjikan sebuah kanal, dan warna kanal itu yang dikenali orang dari
   jauh. Ia satu-satunya elemen di halaman ini yang boleh keluar dari palet. */
.wa-float {
  position: fixed;
  right: clamp(14px, 2.4vw, 26px);
  bottom: clamp(14px, 2.4vw, 26px);
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 20px;
  border-radius: 999px;
  /* #0E7A6D, bukan #128C7E milik WhatsApp. Yang asli mengukur 4,14:1 lawan
     teks putih 15px dan itu di bawah ambang AA 4,5 - masih terbaca hijau
     WhatsApp, tapi lolos. Diukur, bukan dikira. */
  background: #0E7A6D;
  color: #fff;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 700;
  font-size: .93rem;
  letter-spacing: -.01em;
  text-decoration: none;
  box-shadow: 0 18px 38px -14px rgba(14, 122, 109, .6), 0 2px 8px rgba(20, 18, 15, .18);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.wa-float:hover {
  transform: translateY(-2px);
  box-shadow: 0 24px 46px -14px rgba(14, 122, 109, .7), 0 2px 8px rgba(20, 18, 15, .2);
}
.wa-float:active { transform: translateY(0) scale(.98); }
.wa-float svg { flex: none; }

/* Di bawah 560px label teksnya dibuang dan tombolnya jadi lingkaran: pada lebar
   itu label mendorong tombol sampai menutupi CTA di dalam halaman. */
@media (max-width: 560px) {
  .wa-float { padding: 0; width: 52px; justify-content: center; }
  .wa-float span { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .wa-float, .wa-float:hover { transition: none; transform: none; }
}

/* ---------- pita bukti sosial ---------- */
/* Ditumpuk, bukan sebaris. Dijajarkan pada baseline, eyebrow dan kalimatnya
   berebut lebar yang sama dan kalimatnya membungkus balik ke bawah eyebrow. */
.trust-head { display: block; }
.trust-head .eyebrow { display: block; margin-bottom: 8px; }
.trust-line {
  margin: 0;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 700;
  letter-spacing: -.025em;
  font-size: clamp(1.05rem, 2.1vw, 1.5rem);
  color: var(--ink);
  max-width: 46ch;
}

/* ---------- mega-menu ---------- */
.nav-mega-wrap { display: inline-flex; }
.nav-mega-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
  transition: color var(--dur) ease;
}
.nav-mega-btn:hover,
.nav-mega-btn[aria-expanded='true'] { color: var(--ink); }
.nav-mega-btn svg { transition: transform var(--dur) var(--ease); }
.nav-mega-btn[aria-expanded='true'] svg { transform: rotate(180deg); }

.nav-mega {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-soft);
}
.nav-mega-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)) minmax(0, .92fr);
  gap: clamp(20px, 2.4vw, 40px);
  padding: clamp(26px, 3vw, 40px) 0 clamp(28px, 3.2vw, 42px);
}
.nav-mega-grid-sm { grid-template-columns: repeat(2, minmax(0, 1fr)) minmax(0, .8fr); }

.nav-mega-h {
  margin: 0 0 14px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: .68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .18em;
  color: var(--faint);
}
.nav-mega-col a {
  display: block;
  padding: 7px 10px;
  margin: 0 -10px;
  border-radius: 12px;
  transition: background-color var(--dur) ease;
}
.nav-mega-col a:hover { background: var(--wash); }
.nav-mega-col strong {
  display: block;
  font-size: .9rem;
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--ink);
}
.nav-mega-col span {
  display: block;
  margin-top: 2px;
  font-size: .8rem;
  line-height: 1.4;
  color: var(--faint);
}

/* Kartu unggulan memakai tinta terbalik supaya ia menang atas empat kolom di
   sebelahnya. Menu yang seluruhnya rata membuat orang membaca dua puluh baris
   sebelum menemukan satu tindakan. */
.nav-mega-feat {
  display: flex;
  flex-direction: column;
  border-radius: 20px;
  padding: clamp(18px, 1.8vw, 24px);
  background: var(--inverse);
  color: var(--inverse-ink);
}
.nav-mega-feat-eyebrow {
  margin: 0;
  font-size: .66rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .18em;
  opacity: .62;
}
.nav-mega-feat-title {
  margin: 10px 0 0;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  letter-spacing: -.03em;
  font-size: 1.18rem;
}
.nav-mega-feat-body {
  margin: 8px 0 0;
  font-size: .84rem;
  line-height: 1.5;
  opacity: .74;
}
.nav-mega-feat-cta {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 16px;
  align-self: flex-start;
  font: inherit;
  font-size: .87rem;
  font-weight: 700;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: gap var(--dur) var(--ease);
}
.nav-mega-feat-cta:hover { gap: 12px; }
.nav-mega-feat-foot {
  margin: auto 0 0;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, .16);
  font-size: .74rem;
  opacity: .56;
}
:root[data-theme='dark'] .nav-mega-feat-foot { border-top-color: rgba(0, 0, 0, .22); }

@media (max-width: 1180px) {
  .nav-mega-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nav-mega-grid-sm { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nav-mega-feat { grid-column: 1 / -1; }
}

/* Bar ikut memadat saat mega-menu terbuka di puncak halaman: panel punya latar
   sendiri, jadi bar yang masih transparan membuat keduanya terbaca terlepas. */
.nav-bar[data-mega-open='true'] {
  background: var(--card);
  border-bottom-color: transparent;
}

/* ---------- fakta paket ---------- */
/* Grid tiga kolom, bukan flex-wrap: dibiarkan membungkus, butir ketiga jatuh
   sendirian ke baris kedua dan ketiganya berhenti terbaca sebagai satu set. */
.trust-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px clamp(16px, 2.5vw, 34px);
  margin: clamp(20px, 2.6vw, 30px) 0 0;
  padding: 0;
  list-style: none;
  max-width: 720px;
}
@media (max-width: 460px) { .trust-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.trust-facts b {
  display: block;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  letter-spacing: -.035em;
  font-size: clamp(1.4rem, 2.4vw, 1.85rem);
  line-height: 1.05;
  color: var(--ink);
}
.trust-facts span {
  display: block;
  margin-top: 4px;
  font-size: .81rem;
  line-height: 1.4;
  color: var(--faint);
}

/* ---------- bukti nyata (kartu testimoni) ---------- */
/* Gayanya ditulis lebih dulu supaya menyalakan bagian itu nanti cuma soal
   membuka komentar di index.html dan menempel kutipan aslinya. Markup-nya masih
   dikomentari - lihat catatan di sana sebelum membukanya. */
.proof-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 290px), 1fr));
  gap: clamp(16px, 2vw, 24px);
}
.proof-card {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: clamp(24px, 2.6vw, 32px);
  border-radius: 24px;
  border: 1px solid var(--line);
  background: var(--card);
}
.proof-card blockquote {
  margin: 0 0 auto;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 700;
  letter-spacing: -.028em;
  line-height: 1.25;
  font-size: clamp(1.12rem, 1.9vw, 1.35rem);
  color: var(--ink);
}
.proof-card figcaption {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: clamp(24px, 3vw, 34px);
  padding-top: clamp(18px, 2vw, 22px);
  border-top: 1px solid var(--line);
}
.proof-card figcaption img {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  background: var(--wash);
}
.proof-card figcaption strong {
  display: block;
  font-size: .92rem;
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--ink);
}
.proof-card figcaption small {
  display: block;
  margin-top: 2px;
  font-size: .79rem;
  color: var(--faint);
}

/* ---------- wordmark footer ---------- */
/* Dipotong dengan sengaja: yang membuat bentuk ini bekerja adalah huruf yang
   keluar dari bingkai, bukan huruf besar. Tingginya dikunci lebih pendek dari
   glifnya lalu overflow disembunyikan, jadi potongannya sama di setiap lebar
   dan tidak pernah menambah ruang gulir. */
.foot-wordmark {
  overflow: hidden;
  /* Diukur, bukan dikira: pada font-size tercekik 304px dengan line-height .78
     kotak barisnya 237px, jadi 168px memotong sepertiga glif dan huruf terakhir
     terbaca rusak alih-alih terpotong sengaja. 82% memperlihatkan bentuk penuh
     tiap huruf dan menyerahkan pemudaran ke gradien. */
  height: clamp(84px, 13.4vw, 196px);
  display: flex;
  justify-content: center;
  align-items: flex-start;
  pointer-events: none;
  user-select: none;
}
.foot-wordmark span {
  display: block;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  letter-spacing: -.055em;
  font-size: clamp(6.2rem, 19.5vw, 19rem);
  line-height: .78;
  white-space: nowrap;
  /* Gradien memudar ke bawah supaya potongannya terbaca sebagai keputusan,
     bukan sebagai teks yang kebetulan tertutup tepi jendela. */
  background: linear-gradient(180deg, var(--line-strong), transparent 88%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
