/* Sunmood homepage v5 */
:root {
  --paper: #F2F3EE; --paper-2: #E9ECE4; --white: #FFFFFF;
  --ink: #10201B; --green: #0F3B2E; --green-2: #0F4A40; --green-mid: #1F5C3E; --amber: #E9A93A;
  --sand: #E8DCC3; --sand-2: #DCCBA8;
  --line: rgba(16,32,27,.12); --line-d: rgba(242,243,238,.14);
  --mute: rgba(16,32,27,.64); --mute-d: rgba(242,243,238,.68);
  /* ROUND-3 R1: measured pixel colours (PIL, 40-px corners / 5% border) of the GPT Image 2 loop/
     still backgrounds - not design colours. process loops and included loops bg, and
     faq-clean.webp corners. The CSS surface takes the image's measured colour, never the reverse. */
  --bg-loop-process: #EEEFE8; --bg-still-faq: #EFEFEB;
  --serif: "Noto Serif HK", "Songti TC", "PMingLiU", serif;
  --sans: "Noto Sans HK", "PingFang HK", "Microsoft JhengHei", system-ui, sans-serif;
  --wrap: 1360px; --pad: clamp(20px, 4vw, 64px); --sec: clamp(68px, 7vw, 104px);
  --r-sec: 40px; --r-card: 24px; --r-sm: 16px; --r-pill: 32px;
  --nav-h: 96px; --screen: 100vh;
  --h1: clamp(40px, 4.6vw, 68px); --h2: clamp(30px, 2.9vw, 42px); --h2-xl: clamp(30px, 3.2vw, 46px); --h3: clamp(22px, 1.8vw, 28px); --stat: clamp(52px, 5.2vw, 84px);
}
@supports (height: 100svh) { :root { --screen: 100svh; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: auto; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--sans); font-size: 16px; line-height: 1.7; overflow-x: clip; }
body.loading { overflow: hidden; }
img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4, p, ul, ol, figure, dl, dd, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
b { font-weight: 600; }
[hidden] { display: none !important; }
.asset-missing { min-width: 48px; min-height: 48px; background: linear-gradient(135deg, rgba(233,169,58,.22), rgba(8,57,52,.18)); color: transparent; }

/* layout and type */
.wrap { width: min(var(--wrap), calc(100% - 2 * var(--pad))); margin-inline: auto; }
.center { text-align: center; }
.center .eyebrow { justify-content: center; }
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px; }
.grid-about, .grid-incl, .incl-card, .slide, .grid-faq, .book-card, .foot-grid, .counters, .steps, .posts, .mega-tiles, .kv { min-width: 0; }
.grid-about > *, .grid-incl > *, .incl-card > *, .slide > *, .grid-faq > *, .book-card > *, .foot-grid > *, .grid-2 > * { min-width: 0; }
.grid-2.tight { gap: 14px; }
.head-row { align-items: end; margin-bottom: 48px; }
.self-end { justify-self: start; }
.row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
section { position: relative; }
.dark { background: var(--green); color: var(--paper); border-radius: var(--r-sec); }
.eyebrow { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 500; letter-spacing: .08em; line-height: 1.4; color: var(--mute); margin-bottom: 18px; }
.eyebrow i { width: 8px; height: 8px; border-radius: 2px; background: var(--green); }
.eyebrow.light, .dark .eyebrow { color: var(--mute-d); }
.eyebrow.light i, .dark .eyebrow i { background: var(--amber); }
h1 { font-family: var(--serif); font-weight: 500; font-size: var(--h1); line-height: 1.16; letter-spacing: -.02em; color: var(--white); }
.h2 { font-family: var(--serif); font-weight: 500; font-size: var(--h2); line-height: 1.28; letter-spacing: -.005em; }
.h2-s { font-family: var(--serif); font-weight: 500; font-size: clamp(24px, 2vw, 30px); line-height: 1.3; }
h3 { font-family: var(--serif); font-weight: 500; font-size: var(--h3); line-height: 1.35; }
.hi { color: var(--green); }
.dark .hi, .light-on .hi { color: var(--amber); }
.lead { font-size: clamp(16px, 1.2vw, 18px); line-height: 1.75; color: var(--mute); max-width: 62ch; }
.dark .lead { color: var(--mute-d); }
.center .lead { margin-inline: auto; }
.h2 + .lead { margin-top: 20px; }
.mask .line { display: block; overflow: clip; }
.mask .line > span { display: block; }
.tag { display: inline-block; font-size: 11px; line-height: 1; padding: 3px 6px; border-radius: 4px; background: var(--amber); color: var(--ink); margin-left: 6px; vertical-align: middle; }

/* buttons and glyphs */
.btn { position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 10px; height: 48px; padding: 0 22px; border-radius: var(--r-pill); font-size: 15px; font-weight: 600; line-height: 1; white-space: nowrap; transition: transform .25s ease, background .25s ease, color .25s ease, border-color .25s ease; }
.btn:hover { transform: translateY(-1px); }
.btn.lg { height: 56px; padding: 0 28px; font-size: 16px; }
.btn.wide { width: 100%; }
.btn-amber { background: var(--amber); color: var(--ink); }
.btn-amber:hover { background: #F0B54E; }
.btn-ink { background: var(--green); color: var(--paper); }
.btn-ink:hover { background: var(--green-mid); }
.btn-ghost { background: rgba(16,32,27,.08); color: var(--ink); }
.btn-glass { background: rgba(255,255,255,.14); color: var(--white); border: 1px solid rgba(255,255,255,.35); backdrop-filter: blur(10px); }
.btn-outline { color: var(--paper); border: 1px solid rgba(242,243,238,.5); }
.arr { width: 14px; height: 14px; flex: none; background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center/contain no-repeat; }
.arr.back { transform: scaleX(-1); }
.chev { width: 10px; height: 10px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-3px) rotate(45deg); transition: transform .25s; }
.has-mega[aria-expanded="true"] .chev { transform: translateY(1px) rotate(225deg); }
i.tel, i.mail, i.wa, i.fb, i.wc { width: 16px; height: 16px; flex: none; background: currentColor; -webkit-mask: center/contain no-repeat; mask: center/contain no-repeat; }
/* Official WhatsApp glyph (bubble + handset), the same path the live sunmood.com.hk buttons use (owner 2026-09-28: "give me the real whatsapp icon"). */
i.wa { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z'/%3E%3C/svg%3E"); }
i.tel { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M6.6 10.8a15.1 15.1 0 0 0 6.6 6.6l2.2-2.2a1 1 0 0 1 1-.25c1.1.37 2.3.57 3.6.57a1 1 0 0 1 1 1V20a1 1 0 0 1-1 1A17 17 0 0 1 3 4a1 1 0 0 1 1-1h3.5a1 1 0 0 1 1 1c0 1.25.2 2.45.57 3.57a1 1 0 0 1-.25 1L6.6 10.8z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M6.6 10.8a15.1 15.1 0 0 0 6.6 6.6l2.2-2.2a1 1 0 0 1 1-.25c1.1.37 2.3.57 3.6.57a1 1 0 0 1 1 1V20a1 1 0 0 1-1 1A17 17 0 0 1 3 4a1 1 0 0 1 1-1h3.5a1 1 0 0 1 1 1c0 1.25.2 2.45.57 3.57a1 1 0 0 1-.25 1L6.6 10.8z'/%3E%3C/svg%3E"); }
i.mail { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Cpath d='M3 7l9 6 9-6'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Cpath d='M3 7l9 6 9-6'/%3E%3C/svg%3E"); }
i.fb { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M15 3h-2c-2.21 0-4 1.79-4 4v3H7v4h2v7h4v-7h2.5l.5-4H13V7c0-.55.45-1 1-1h2V3z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M15 3h-2c-2.21 0-4 1.79-4 4v3H7v4h2v7h4v-7h2.5l.5-4H13V7c0-.55.45-1 1-1h2V3z'/%3E%3C/svg%3E"); }
i.wc { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M8.5 4C4.9 4 2 6.5 2 9.6c0 1.8 1 3.4 2.6 4.5l-.6 2 2.2-1.1c.7.2 1.5.3 2.3.3h.3a5.6 5.6 0 0 1-.2-1.5c0-3.4 3.2-6.1 7.1-6.1h.3C15.2 5.6 12.1 4 8.5 4zm-2.4 3.4a.9.9 0 1 1 0 1.8.9.9 0 0 1 0-1.8zm5 0a.9.9 0 1 1 0 1.8.9.9 0 0 1 0-1.8z'/%3E%3Cpath d='M16.8 9.7c-3.4 0-6.1 2.4-6.1 5.4 0 3 2.7 5.4 6.1 5.4.7 0 1.4-.1 2-.3l1.9.9-.5-1.7c1.3-.9 2.2-2.3 2.2-4.3 0-3-2.7-5.4-6.1-5.4zm-2.2 2.7a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5zm4.3 0a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23000'%3E%3Cpath d='M8.5 4C4.9 4 2 6.5 2 9.6c0 1.8 1 3.4 2.6 4.5l-.6 2 2.2-1.1c.7.2 1.5.3 2.3.3h.3a5.6 5.6 0 0 1-.2-1.5c0-3.4 3.2-6.1 7.1-6.1h.3C15.2 5.6 12.1 4 8.5 4zm-2.4 3.4a.9.9 0 1 1 0 1.8.9.9 0 0 1 0-1.8zm5 0a.9.9 0 1 1 0 1.8.9.9 0 0 1 0-1.8z'/%3E%3Cpath d='M16.8 9.7c-3.4 0-6.1 2.4-6.1 5.4 0 3 2.7 5.4 6.1 5.4.7 0 1.4-.1 2-.3l1.9.9-.5-1.7c1.3-.9 2.2-2.3 2.2-4.3 0-3-2.7-5.4-6.1-5.4zm-2.2 2.7a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5zm4.3 0a.75.75 0 1 1 0 1.5.75.75 0 0 1 0-1.5z'/%3E%3C/svg%3E"); }

/* Focus is always visible for keyboard users; no rule may suppress the default outline without
   providing this instead. Placed late in the cascade so it wins any equal-specificity clash. */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

/* loader */
/* CODE-REVIEW #3: the loader's own box background used to be an ALWAYS-opaque gradient sitting
   behind the canvas AND the split panels, so fading the canvas and sliding the panels away during
   release never actually exposed the hero underneath - only `loader.remove()` at the very end did,
   making the whole A3 split-reveal choreography pure theater on top of a solid colour. The gradient
   now lives only on `.shader-fallback` (still the correct backdrop when WebGL never worked) and is
   explicitly cleared again on `.is-releasing` (specificity/source-order: this rule must come after
   `.shader-fallback` so it wins when both classes are present, which happens whenever a working
   shader releases normally) so the panels' motion reveals the real page, not a colour. */
/* ROUND-3 item 5: base .loader now carries a solid --green fill again (the shader canvas paints
   on top once its first frame is ready; before that, or if the stylesheet itself hasn't parsed
   yet, this is what's visible - never a blank/transparent frame that lets the hero bleed through).
   .is-releasing still clears it to none below, unchanged, so the CODE-REVIEW #3 split-reveal fix
   above is untouched: the panels reveal the real hero, not a colour, exactly as before. */
.loader { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center; overflow: hidden; color: var(--white); background: var(--green); }
.loader.shader-fallback { background: linear-gradient(135deg, #0F3B2E, #1F6B4E); }
.loader-bg { position: absolute; z-index: 0; inset: 0; width: 100%; height: 100%; opacity: 1; transition: opacity .25s ease; }
.loader.shader-fallback .loader-bg { opacity: 0; }
.loader.is-releasing { background: none; }
.loader-in { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; width: min(460px, calc(100% - 48px)); }
.loader-logo { position: relative; width: 200px; overflow: hidden; }
.loader-logo img { width: 100%; height: auto; clip-path: inset(0 100% 0 0); }
.loader-meta { position: relative; isolation: isolate; display: inline-flex; align-items: end; justify-content: center; gap: 20px; margin-top: 40px; padding: 12px 18px; border-radius: 20px; background: rgba(15,59,46,.55); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.loader-meta::before { content: ""; position: absolute; z-index: -1; inset: 0; border-radius: inherit; background: rgba(11,46,35,.35); }
.loader-pct { display: inline-flex; align-items: baseline; font-family: var(--serif); font-size: 64px; line-height: 1; color: #F2E9D3; font-variant-numeric: tabular-nums; }
.loader-pct .unit { font-size: .4em; color: inherit; margin-left: 2px; }
.loader-lbl { padding-bottom: 7px; font-size: 13px; letter-spacing: .08em; color: #F2E9D3; }
.loader-bar { width: 100%; height: 2px; margin-top: 20px; background: #F2E9D3; }
.loader-bar i { display: block; width: 0; height: 100%; background: var(--amber); }
.loader-panel { position: absolute; z-index: 1; left: 0; width: 100%; height: 51%; background: none; }
.loader.is-releasing .loader-panel { background: var(--green); }
.loader-panel.top { top: 0; } .loader-panel.bottom { bottom: 0; }

/* navigation */
.nav { position: fixed; inset: 0 0 auto; z-index: 100; padding: 12px var(--pad); }
.nav-in { display: flex; align-items: center; justify-content: space-between; gap: 24px; height: 72px; padding: 0 10px 0 24px; border-radius: 38px; color: var(--white); transition: background .4s ease, box-shadow .4s ease; max-width: var(--wrap); margin-inline: auto; }
/* Fully opaque (was .94 alpha + blur(16px)): the near-transparent 6% plus a 16px blur let whatever
   heading happened to be scrolled underneath the nav bleed and smear through it - reproduced on
   phone at §10's second heading line (390x844, scrollY ~12000-12500, WORK-ORDER item 2) where the
   amber text rendered as garbled/doubled strokes; hidden nav = clean text, same scroll position,
   same DOM (lab/_fix/book-nav-test.mjs). Solid fill removes the bleed everywhere, not just there. */
.nav.solid .nav-in { background: rgb(8,57,52); box-shadow: 0 12px 36px rgba(8,57,52,.24); }
.brand { display: flex; align-items: center; white-space: nowrap; }
.brand img { height: 40px; width: auto; max-width: 220px; object-fit: contain; }
.brand img.asset-missing { width: 180px; }
.links { display: none; align-items: center; gap: 2px; }
.link { display: inline-flex; align-items: center; gap: 7px; padding: 12px 18px; border-radius: 22px; font-size: 16px; font-weight: 500; line-height: 1; transition: background .2s; }
.link:hover, .has-mega[aria-expanded="true"] { background: rgba(255,255,255,.12); }
.nav-cta { display: none; height: 48px; }
.burger { display: flex; flex-direction: column; justify-content: center; gap: 6px; width: 48px; height: 48px; align-items: center; border-radius: 50%; background: rgba(255,255,255,.14); }
.burger i { display: block; width: 18px; height: 1.6px; background: currentColor; transition: transform .3s; }
.burger[aria-expanded="true"] i:first-child { transform: translateY(3.8px) rotate(45deg); }
.burger[aria-expanded="true"] i:last-child { transform: translateY(-3.8px) rotate(-45deg); }
.mega { position: absolute; left: var(--pad); right: var(--pad); top: var(--nav-h); z-index: 5; }
.mega-in { max-width: var(--wrap); margin-inline: auto; background: var(--white); color: var(--ink); border-radius: 28px; padding: 22px; box-shadow: 0 30px 80px rgba(8,57,52,.28); }
.mega-tiles { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
.tile { display: block; padding: 10px; border-radius: 20px; transition: background .2s; }
.tile:hover { background: var(--paper); }
.tile figure { aspect-ratio: 4/3; border-radius: 16px; overflow: clip; background: var(--paper-2); }
.tile img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s ease; }
.tile:hover img { transform: scale(1.04); }
.tile .tile-h { display: flex; align-items: center; justify-content: space-between; margin: 12px 4px 6px; font-family: var(--serif); font-size: 18px; font-weight: 500; }
.tile ul { padding: 0 4px; font-size: 13px; line-height: 1.9; color: var(--mute); }
/* .tile-split (協議書及證書, sunmood #133): the tile cannot be one <a> because each of the three
   sub-items (婚前協議書 / 分居協議書 / 補領結婚證書) is its own destination, and a link cannot sit
   inside another link. The heading + picture (.tile-main) link to /divorce-agreement/ with a
   stretched ::after (inset:0 relative to the positioned .tile-split) so the whole card stays
   clickable, exactly as the single <a class="tile"> it replaces was. The three .tile-sub links sit
   above that overlay (z-index) and are independently tappable; pointer-events:none on the <ul>
   lets a tap land in the gap BETWEEN two sub links on the stretched card link instead of a dead
   list-item whitespace. One vocabulary from #126 (分居), with #128 (婚前)'s :focus-visible keyboard
   state added so the sub links are reachable without a mouse. inline-flex + min-height sizes the
   tap target directly to the work order's >=24px floor -- an inline <a>'s own border box follows
   its FONT METRICS, not the inherited `line-height: 1.9` on `.tile ul` (measured 19px without this,
   lab/probe-menu-split.mjs RED). */
.tile-split { position: relative; }
.tile-split .tile-main { display: block; color: inherit; }
.tile-split .tile-main::after { content: ""; position: absolute; inset: 0; border-radius: 20px; }
.tile-split ul { position: relative; z-index: 1; pointer-events: none; }
.tile-split .tile-sub { display: inline-flex; align-items: center; min-height: 24px; pointer-events: auto; color: var(--ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.tile-split .tile-sub:hover, .tile-split .tile-sub:focus-visible { color: var(--green-mid); }
.mega-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 28px; margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line); font-size: 14px; }
.mega-strip .eyebrow { margin: 0 6px 0 0; }
.mega-areas, .mega-pages { display: flex; align-items: center; gap: 14px; }
.mega-pages { margin-left: auto; }
/* FIX-2 #22: body.mnav-open{overflow:hidden} lives only in components/mobile-nav.css now. */

/* §1 hero */
.hero { height: calc(var(--screen) * 2); background: var(--green); }
.hero-stage { position: sticky; top: 0; height: var(--screen); overflow: clip; }
.hero-card { position: absolute; inset: 0; overflow: clip; will-change: transform, border-radius; background: var(--green); }
.hero-media, .hero-video, .hero-poster { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero-video { object-fit: cover; background: linear-gradient(135deg, var(--green-2), #102720); }
/* Explicit poster layer above the video: stays visible until the `playing` event actually fires
   (native <video poster> can be cleared by some engines once readyState advances, even before
   playback truly starts, or if autoplay is rejected) so the visitor never sees a blank/black frame. */
.hero-poster { object-fit: cover; transition: opacity .4s ease; }
.hero-media.is-playing .hero-poster { opacity: 0; pointer-events: none; }
.hero-shade { position: absolute; inset: 0; pointer-events: none; }
.hero-shade-x { background: linear-gradient(90deg, rgba(6,20,18,.86) 0%, rgba(6,20,18,.58) 32%, rgba(6,20,18,0) 66%); }
.hero-shade-y { background: linear-gradient(0deg, rgba(6,20,18,.82) 0%, rgba(6,20,18,0) 35%); }
.hero-copy { position: absolute; left: var(--pad); right: var(--pad); top: 50%; transform: translateY(-50%); max-width: 46ch; font-size: var(--h1); color: var(--white); }
.hero-copy h1 { max-width: none; }
.hero-copy .lead { color: rgba(255,255,255,.86); margin-top: 24px; max-width: 50ch; }
.hero-copy .row { margin-top: 30px; }
.hi-amber { color: var(--amber); background: linear-gradient(100deg, #E9A93A 0%, #F6D27A 40%, #E9A93A 60%); background-size: 200% auto; background-position: 100% center; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.loaded .hi-amber { animation: goldSheen 9s ease-in-out infinite; }
/* Owner-approved: loops continuously while visible. Paused (not removed) while the hero is
   scrolled out of view so it costs nothing off-fold; site.js toggles the class via IntersectionObserver. */
.loaded .hi-amber.hero-decor-offscreen { animation-play-state: paused; }
@keyframes goldSheen { 0% { background-position: 100% center; } 44% { background-position: -100% center; } 100% { background-position: -100% center; } }
/* ROUND-3b item 4: bottom-CENTRE of the hero, not space-between - .hero-bar stays absolute (out
   of flow, unaffected). .scrub-hint is the only in-flow child at every viewport that shows it
   (phone hides it outright), so centring here centres it. */
.hero-foot { position: absolute; left: var(--pad); right: var(--pad); bottom: 26px; display: flex; align-items: center; justify-content: center; gap: 20px; color: rgba(255,255,255,.85); font-size: 13px; }
.scrub-hint { display: flex; align-items: center; gap: 12px; }
.scrub-hint span { font-size: 16px; }
/* ROUND-3b item 4: wheel icon enlarged again (was 26x40) - 30 wide, 48 tall, dot unchanged. */
.wheel { width: 30px; height: 48px; border: 1.5px solid rgba(255,255,255,.7); border-radius: 15px; position: relative; }
.wheel::after { content: ""; position: absolute; left: 50%; top: 8px; width: 3px; height: 8px; margin-left: -1.5px; border-radius: 2px; background: var(--amber); animation: wheel 1.6s ease-in-out infinite; }
.wheel.hero-decor-offscreen::after { animation-play-state: paused; }
@keyframes wheel { 0%, 100% { transform: translateY(0); opacity: 1; } 60% { transform: translateY(8px); opacity: .2; } }
.hero-bar { position: absolute; left: 0; right: 0; bottom: -26px; height: 2px; background: rgba(255,255,255,.18); }
.hero-bar i { display: block; height: 100%; width: 0; background: var(--amber); }

/* §2 about */
.about { height: calc(var(--screen) * 2); background: var(--sand); border-radius: var(--r-sec) var(--r-sec) 0 0; overflow: clip; }
.about-pin { position: sticky; top: 0; height: var(--screen); display: flex; align-items: center; padding: var(--nav-h) 0 24px; }
.grid-about { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(36px, 5vw, 72px); align-items: center; }
.about-copy { max-width: 820px; }
.reveal-words { font-size: clamp(27px, 2.55vw, 39px); line-height: 1.55; }
.reveal-words .w { position: relative; color: #A86D18; opacity: 1; filter: none; transition: color .16s linear; }
.reveal-words .w.revealed { color: var(--green); }
.reveal-words .w.active { background-image: linear-gradient(var(--amber), var(--amber)); background-position: 0 100%; background-repeat: no-repeat; background-size: 100% 2px; }
.about-more { opacity: 0; transform: translateY(24px); }
.stats { display: grid; grid-template-columns: repeat(3, auto); gap: 24px 34px; margin: 32px 0; justify-content: start; }
.stats b { display: block; font-family: var(--serif); font-size: clamp(30px, 2.6vw, 38px); font-weight: 500; line-height: 1; color: var(--green); }
.stats b small { font-size: .5em; margin-left: 2px; }
.stats span { display: block; font-size: 13px; color: var(--mute); margin-top: 6px; }
.about-media { position: relative; aspect-ratio: 4/5; max-height: min(72vh, 680px); overflow: clip; border-radius: 24px; background: var(--sand); }
.about-logo { display: grid; place-items: center; }
.about-logo > img { width: 360px; max-width: 72%; height: auto; object-fit: contain; }
.about-logo > img.asset-missing { width: 360px; max-width: 72%; aspect-ratio: 1; }

/* shared paintings */
.paint { position: relative; overflow: clip; border-radius: 20px; background: var(--paper); }
.paint video, .paint > img { width: 100%; height: 100%; object-fit: cover; }
/* ROUND-3 item 11(c): the generic ".paint .blend" radial-fade rule is gone - every light-section
   .blend element (steps/incl) was deleted from the markup, R1 rules out any masks/blends there.
   ".paint-mini .blend" (numbers, dark/green section) is untouched and now carries its own
   position/pointer-events directly, since this shared rule no longer supplies them. */

/* §3 services */
/* Scroll-to-turn runway for ANY [data-carousel][data-carousel-bands] carousel (issue #91 - was .svc/.svc-pin
   only): the section is a tall runway, the pin sticks under the nav while page scroll picks the card
   (public/site.js bands ScrollTrigger). Phone runway + reduced-motion collapse further down. */
[data-carousel-runway] { min-height: calc(var(--screen) * 2.2); }
[data-carousel-pin] { position: sticky; top: calc(var(--nav-h) + 12px); min-height: calc(var(--screen) - var(--nav-h) - 12px); }
.svc { border-radius: var(--r-sec) var(--r-sec) 0 0; margin-top: calc(-1 * var(--r-sec)); overflow: clip; }
.svc-pin { padding: 56px 0 20px; overflow: clip; }
.seg-scroll { margin-top: 36px; overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity; }
.seg-scroll::-webkit-scrollbar, .chip-scroll::-webkit-scrollbar { display: none; }
.seg-track, .chips { position: relative; display: flex; width: max-content; min-width: min(100%, 720px); margin-inline: auto; padding: 5px; border-radius: 30px; background: rgba(255,255,255,.08); }
.seg-ind { position: absolute; z-index: 0; left: 5px; top: 5px; bottom: 5px; width: 100px; border-radius: 24px; background: var(--amber); }
.seg-track button { position: relative; z-index: 1; flex: 1 0 auto; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 8px; height: 46px; padding: 0 14px; border-radius: 24px; scroll-snap-align: center; color: var(--paper); font-size: 15px; font-weight: 600; }
.seg-track button small { font-size: 11px; letter-spacing: .06em; color: var(--mute-d); }
.seg-track button.on { color: var(--ink); }
.seg-track button.on small { color: rgba(16,32,27,.58); }
/* Row B fix (#75): --slide-w used 100vw, which on Windows classic scrollbars is wider than the
   carousel's OWN rendered width (100% in .track's padding-inline below, PR #71) by the scrollbar's
   width -- the slide (width: var(--slide-w)) then overhangs its container and the padding-inline
   calc goes negative (clamped to 0), losing the left gutter that keeps the active card on
   screen. container-type: inline-size turns .carousel into the query container so cqw, unlike vw,
   resolves against THIS box's real content width (scrollbar excluded) at every descendant that
   consumes --slide-w, the same basis .track's own 100% already uses -- one basis, no more drift. */
.carousel { position: relative; margin-top: 20px; overflow: clip; touch-action: pan-y pinch-zoom; --slide-w: min(1240px, calc(100vw - 2 * var(--pad) - 96px)); }
/* cqw needs Safari 16+ / Chrome 105+; older browsers keep the 100vw rule above (a custom property
   holding an unsupported unit would otherwise blank the slide width). */
@supports (width: 1cqw) {
  .carousel { container-type: inline-size; --slide-w: min(1240px, calc(100cqw - 2 * var(--pad) - 96px)); }
}
.track { display: flex; gap: 24px; width: max-content; will-change: transform; padding-inline: calc((100% - var(--slide-w)) / 2); }
.slide { display: grid; grid-template-columns: minmax(0, 44fr) minmax(0, 56fr); gap: 38px; width: var(--slide-w); border-radius: var(--r-card); padding: 26px; background: var(--green-2); transition: opacity .5s ease; }
.slide:not(.on) { opacity: .4; }
/* ROUND-3 item 3: scoped to .svc only - the base .slide(:not(.on)) rules above are shared with
   §6 cases, which this item does not touch. Active slide gets a 1px amber ring + a deep drop
   shadow and full scale/opacity; inactive slides recede (dimmer + slightly smaller), transform
   from the box centre so neighbours don't visibly shift. .svc .carousel below clips horizontally
   (hides off-screen slides, unchanged) but not vertically, so the ring/shadow around the active
   slide is never cut off. */
.svc .carousel { overflow-x: clip; overflow-y: visible; }
.svc .slide { transform-origin: center; transition: opacity .5s ease, transform .5s ease, box-shadow .5s ease; }
.svc .slide.on { opacity: 1; transform: scale(1); box-shadow: 0 0 0 1px rgba(233,169,58,.55), 0 30px 80px rgba(0,0,0,.35); }
.svc .slide:not(.on) { opacity: .28; transform: scale(.96); }
.scene { position: relative; aspect-ratio: 4/3; border-radius: 20px; overflow: clip; background: rgba(242,243,238,.06); }
.svc .scene { aspect-ratio: 4/5; }
.scene img { width: 100%; height: 100%; object-fit: cover; }
.scene figcaption { position: absolute; left: 20px; bottom: 16px; font-size: 13px; color: var(--paper); background: rgba(8,57,52,.64); padding: 6px 12px; border-radius: 20px; backdrop-filter: blur(8px); }
.slide-copy { display: flex; flex-direction: column; justify-content: center; gap: 13px; }
.slide-copy h3 { font-size: 40px; }
.svc .slide-copy h3 { font-size: 48px; }
.slide-copy .sub { color: var(--amber); font-size: 18px; }
.slide-copy > p:not(.sub) { color: var(--mute-d); }
.svc .slide-copy > p:not(.sub) { font-size: 17px; }
.subs { display: flex; flex-wrap: wrap; gap: 8px; }
.subs li { font-size: 13px; line-height: 1; padding: 8px 12px; border: 1px solid var(--line-d); border-radius: 16px; color: var(--mute-d); }
.svc .subs li { font-size: 14px; }
.slide-copy .btn { align-self: flex-start; }
.arrows { display: flex; align-items: center; justify-content: center; gap: 18px; margin-top: 14px; font-size: 13px; color: var(--mute-d); }
.arrows button { width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--line-d); display: grid; place-items: center; }
/* ROUND-3 item 2: the arrows/counter row now lives ONLY below the slide (the tab-row copy is
   deleted, see the removed .svc-arrows-top markup/CSS/JS hook). margin-top:20px (desktop AND
   phone - higher specificity than the plain .arrows rules, including the phone media query's
   generic override; J ruling 2026-09-14 cut this from 28px) is the "20px below the card" gap.
   Arrow buttons are 48px on every viewport now too (J ruling; was 56px desktop) - the phone-only
   48px override lower in this file is now redundant with this but left in place, harmless. */
.svc .arrows { gap: 24px; font-size: 15px; margin-top: 20px; }
.svc .arrows button { width: 48px; height: 48px; }

/* §4 process */
.process { padding: var(--sec) 0; background: var(--white); }
.process .head-row { margin-bottom: 42px; }
/* ROUND-3 item 9: person cut off (image 32) - the fixed 2/1 box forced a cover-crop. No fixed
   aspect at all now; the IMG's own box is sized from its natural aspect (width/height:auto, capped
   by max-height so a portrait still fits the head-row), so getBoundingClientRect on the img
   measures the real content, not a cropping box. align-self:end keeps it sitting on the head-row
   baseline; section/figure stay --white (measured still corners are 254 - no visible box). */
.paint-wide { align-self: end; background: var(--white); }
.paint-wide img { width: auto; height: auto; max-width: 100%; max-height: 560px; object-fit: contain; object-position: bottom; margin-inline: auto; display: block; }
.steps { display: flex; flex-direction: column; gap: 16px; }
.card { background: var(--white); border-radius: var(--r-card); padding: 30px; }
/* ROUND-3 item 11(a): R1 rule - a loop's box must equal its measured bg. All three process cards
   (and the .paint box behind each loop) now share ONE fill, --bg-loop-process, on every viewport;
   01/02/03 are told apart by the amber number only (the green 3rd-card treatment is retired - a
   loop cannot sit on green without a visible second-colour box). */
.steps .card { display: block; background: var(--bg-loop-process); }
.steps .paint { width: min(100%, 260px); max-height: 260px; aspect-ratio: 1; margin: 0 auto 8px; background: var(--bg-loop-process); border-radius: 0; overflow: visible; }
.steps .paint video, .steps .paint > img { object-fit: contain; }
.steps .num { position: relative; display: block; align-self: flex-start; font-family: var(--serif); font-size: 56px; font-weight: 500; line-height: 1; color: var(--amber); margin-bottom: 8px; }
.steps h3 { font-size: 28px; margin-bottom: 8px; }
.steps p { color: var(--mute); font-size: 15px; margin-bottom: 16px; }
.steps .card .btn { align-self: flex-start; }

/* §5 included */
.incl { padding: calc(var(--sec) * 1.15) 0; }
.grid-incl { display: grid; grid-template-columns: 410px minmax(0, 1fr); gap: clamp(44px, 5vw, 76px); align-items: start; }
.sticky-col { position: sticky; top: calc(var(--nav-h) + 28px); min-height: calc(var(--screen) - var(--nav-h) - 56px); }
.incl-list { display: flex; flex-direction: column; gap: 16px; }
.incl-list li { position: relative; display: flex; flex-direction: column; gap: 4px; padding: 12px 0 16px; color: var(--mute); opacity: .45; transition: opacity .35s, color .35s; }
.incl-list li::after { content: ""; position: absolute; left: 0; bottom: 0; width: 0; height: 3px; background: var(--amber); transition: width .45s cubic-bezier(.22,1,.36,1); }
.incl-list li small, .mobile-incl-heading small { color: var(--amber); font-size: 14px; letter-spacing: .08em; }
.incl-list li span { font-family: var(--serif); font-size: var(--h2-xl); line-height: 1.2; }
.incl-list li.on { opacity: 1; color: var(--ink); }
.incl-list li.on::after { width: 100%; }
.sticky-col-cta { margin-top: 24px; }
.incl-cards { display: flex; flex-direction: column; gap: 26px; }
.incl-card { display: grid; grid-template-columns: minmax(0, 45fr) minmax(0, 55fr); gap: 30px; align-items: center; min-height: 390px; box-shadow: 0 18px 60px rgba(8,57,52,.06); }
/* ROUND-3 items 11(b)/13: 1/1 + contain (R2), no crop, no fade (.blend deleted from the markup).
   bg --white matches the card (loops measure 254, R1). Desktop caps the box at 320px, centred in
   its own grid column; the <=899px override below re-centres it at a fixed 220px. */
.incl-card .paint { aspect-ratio: 1; background: var(--white); width: 100%; max-width: 320px; margin-inline: auto; border-radius: 0; overflow: visible; }
.incl-card .paint video, .incl-card .paint > img { object-fit: contain; }
.incl-copy { display: flex; flex-direction: column; gap: 14px; }
.incl-copy p { color: var(--mute); }
.mobile-incl-heading { display: none; }
.callout { background: var(--paper-2); border-radius: var(--r-sm); padding: 14px 16px; font-size: 14px; line-height: 1.6; display: flex; flex-direction: column; gap: 2px; }
.callout b { font-size: 13px; font-weight: 500; color: var(--mute); }

/* §6 cases */
.cases { padding: var(--sec) 0; overflow: clip; }
.cases .slide { background: var(--white); }
.cases .slide-copy > p, .cases blockquote { color: var(--ink); }
.cases .arrows { color: var(--mute); }
.cases .arrows button { border-color: var(--line); background: var(--white); }
blockquote { font-family: var(--serif); font-size: clamp(18px, 1.5vw, 22px); line-height: 1.6; }
.kv { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding: 18px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.kv dt { font-size: 12px; color: var(--mute); }
.kv dd { font-family: var(--serif); font-size: 20px; font-weight: 500; color: var(--green); margin-top: 4px; }

/* §7 numbers and §8 blog */
.block-numbers { padding: var(--sec) 0; border-radius: var(--r-sec) var(--r-sec) 0 0; }
.counters { display: grid; grid-template-columns: repeat(4, 1fr); margin-top: 52px; text-align: left; }
.stat-col { display: flex; flex-direction: column; align-items: flex-start; padding: 0 28px; border-left: 1px solid var(--line-d); }
.stat-col:first-child { border-left: 0; padding-left: 0; }
.stat-col:last-child { padding-right: 0; }
.paint-mini { width: 150px; aspect-ratio: 1; border-radius: 16px; margin-bottom: 16px; background: var(--green); }
/* Codex review: 1:1 loop in a 1:1 box, so contain vs cover is a no-op crop-wise here - but contain
   is the correct/consistent rule per R2 ("every .paint that holds one is 1/1 + object-fit:contain,
   centred, no crop"), so state it explicitly rather than relying on the coincidence. */
.paint-mini video { object-fit: contain; }
.paint-mini .blend { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(closest-side, transparent 60%, var(--green) 100%); }
.stat-col > small { color: var(--amber); font-size: 12px; letter-spacing: .1em; }
.stat-col > b { display: block; margin-top: 10px; font-family: var(--serif); font-size: var(--stat); font-weight: 500; line-height: 1; font-variant-numeric: tabular-nums; }
.stat-col > b small { font-size: .32em; margin-left: 4px; }
.stat-col > span { margin-top: 10px; font-size: 13px; color: var(--mute-d); }
.blog { margin-top: calc(var(--sec) * 1.2); padding-top: var(--sec); border-top: 1px solid var(--line-d); }
.blog-tools { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px 20px; margin-top: 28px; }
.chip-scroll { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.chips { min-width: 0; padding: 4px; }
.chips .seg-ind { left: 4px; top: 4px; bottom: 4px; }
.chips button { position: relative; z-index: 1; height: 38px; padding: 0 16px; border-radius: 19px; font-size: 14px; color: var(--paper); white-space: nowrap; }
.chips button.on { color: var(--ink); }
.search { display: flex; align-items: center; gap: 8px; height: 46px; padding: 0 16px; border-radius: 23px; border: 1px solid var(--line-d); color: var(--mute-d); }
.search i { width: 14px; height: 14px; border: 1.5px solid currentColor; border-radius: 50%; position: relative; }
.search i::after { content: ""; position: absolute; width: 6px; height: 1.5px; background: currentColor; right: -5px; bottom: -2px; transform: rotate(45deg); }
.search input { background: none; border: 0; color: var(--paper); width: 120px; font-size: 14px; }
.search input::placeholder { color: var(--mute-d); }
.posts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin: 38px 0 40px; text-align: left; }
.post a { display: flex; flex-direction: column; gap: 12px; }
.post figure { aspect-ratio: 4/3; border-radius: 20px; overflow: clip; background: var(--green-2); }
.post figure img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s ease; }
.post a:hover img { transform: scale(1.04); }
.post .meta { font-size: 12px; color: var(--mute-d); }
.post h3 { font-size: 19px; line-height: 1.45; }
.empty { color: var(--mute-d); margin: 40px 0; }

/* §9 faq */
/* ROUND-3 item 14: R1 measured faq-clean.webp corners at #EFEFEB - the section now takes that
   colour directly (no blend/mask ever existed on .faq-person; it was always a plain contain image
   sitting on object-position:bottom, per .faq-person img below), so the still's flat background
   reads as one surface with the section instead of a mismatched box. .callout.big keeps its own
   --paper-2 fill, untouched. */
.faq { padding: var(--sec) 0; background: var(--bg-still-faq); }
.grid-faq { display: grid; grid-template-columns: minmax(0, 42fr) minmax(0, 58fr); gap: 5%; }
.faq-left { display: flex; flex-direction: column; gap: 24px; }
/* #44: the filter-pill bar sat directly against the first question card with zero gap between them
   (chip-scroll and ul.acc were plain block-flow siblings, no margin either side) - it read as
   overlapping the list rather than sitting above it. `.faq-right` only exists when Faq.astro is
   given `filters` (the divorce-procedure page); the homepage's own plain `<ul class="acc">` FAQ has
   no filter bar and is unaffected by this rule at any width. */
.faq-right { display: flex; flex-direction: column; gap: 20px; }
.faq-visual { position: relative; min-height: 450px; display: flex; align-items: flex-end; }
.faq-person { position: absolute; inset: auto auto 0 0; width: min(420px, 78%); }
.faq-person img { width: 100%; max-height: 450px; object-fit: contain; object-position: bottom; }
.callout.big { position: relative; z-index: 2; width: min(300px, 64%); margin-left: auto; padding: 24px; gap: 12px; box-shadow: 0 18px 50px rgba(8,57,52,.1); }
.callout.big b { font-size: 18px; font-family: var(--serif); font-weight: 500; color: var(--ink); }
.callout.big p { color: var(--mute); font-size: 15px; }
.callout.big .btn { align-self: flex-start; }
.acc li { background: var(--white); border-radius: 20px; margin-bottom: 10px; overflow: clip; }
.acc button { display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; padding: 22px 24px; text-align: left; font-weight: 600; font-size: 16px; }
.acc button i { flex: none; width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line); position: relative; }
.acc button i::before, .acc button i::after { content: ""; position: absolute; left: 50%; top: 50%; width: 12px; height: 1.6px; background: var(--ink); transform: translate(-50%, -50%); }
.acc button i::after { transform: translate(-50%, -50%) rotate(90deg); transition: transform .3s; }
.acc li.open button i::after { transform: translate(-50%, -50%); }
.acc .ans { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .4s ease; }
.acc li.open .ans { grid-template-rows: 1fr; }
.acc .ans > p { overflow: hidden; padding: 0 24px; color: var(--mute); }
.acc li.open .ans > p { padding-bottom: 22px; }

/* §10 booking */
.book { padding: 0 24px var(--sec); }
.book-card { max-width: calc(var(--wrap) + 48px); margin-inline: auto; background: var(--green); color: var(--paper); border-radius: var(--r-sec); padding: 48px; display: grid; grid-template-columns: minmax(0, 45fr) minmax(0, 55fr); gap: 48px; }
.book-info { display: flex; flex-direction: column; gap: 26px; padding: 12px 8px 0; }
.book-info .hi { color: var(--amber); }
.ticks li { position: relative; padding-left: 30px; margin-bottom: 10px; }
.ticks li::before { content: "✓"; position: absolute; left: 0; top: 1px; color: var(--amber); font-weight: 700; }
.consultant { margin-top: auto; display: flex; align-items: center; gap: 16px; }
.consultant > img { width: 72px; height: 72px; flex: none; border-radius: 50%; object-fit: cover; object-position: top; background: var(--paper); }
.consultant div { display: flex; flex-direction: column; gap: 4px; }
.consultant b { font-family: var(--serif); font-size: 18px; font-weight: 500; }
.consultant span { font-size: 13px; color: var(--mute-d); }
.book-form { background: var(--white); color: var(--ink); border-radius: 28px; padding: 36px; display: flex; flex-direction: column; gap: 14px; }
.book-form label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--mute); }
.book-form input, .book-form select, .book-form textarea { height: 48px; padding: 0 16px; border-radius: 14px; border: 1px solid var(--line); background: var(--paper); color: var(--ink); font-size: 15px; }
.book-form textarea { height: auto; padding: 12px 16px; resize: vertical; }
.book-form input:focus, .book-form select:focus, .book-form textarea:focus { border-color: var(--green); }
.book-form .check { flex-direction: row; align-items: center; gap: 10px; }
.book-form .check input { width: 18px; height: 18px; accent-color: var(--green); }

/* §11 close and §12 footer */
.close { position: relative; overflow: clip; background: var(--green); color: var(--paper); padding: calc(var(--sec) * 1.45) 0 var(--sec); text-align: center; }
.close-bg { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 1; }
.close.shader-fallback .close-bg { opacity: 0; }
.close .hi { color: var(--amber); }
.close-copy { position: relative; z-index: 1; padding-block: 28px; }
.close-copy::before { content: ""; position: absolute; z-index: -1; inset: 0 max(0px, calc(50% - 430px)); border-radius: 32px; background: rgba(255,255,255,.04); border: 1px solid var(--line-d); }
.close .btn { margin-top: 32px; }
.foot { background: var(--green); padding: 0 24px 24px; }
.foot-card { max-width: calc(var(--wrap) + 48px); margin-inline: auto; background: var(--white); border-radius: var(--r-sec); padding: 0 clamp(24px, 4vw, 56px) 28px; overflow: clip; }
.foot-sun { position: relative; width: calc(100% + 2 * clamp(24px, 4vw, 56px)); margin-left: calc(-1 * clamp(24px, 4vw, 56px)); aspect-ratio: 21/9; max-height: 300px; margin-bottom: 44px; overflow: clip; }
.foot-sun img { width: 100%; height: 100%; object-fit: cover; }
.foot-sun i { position: absolute; inset: 0; background: linear-gradient(180deg, var(--white) 0%, transparent 35%); pointer-events: none; }
.foot-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1.4fr; gap: 48px; }
.foot-brand > img { height: 64px; width: auto; max-width: 100%; object-fit: contain; margin-bottom: 22px; }
.foot-brand .btn { margin-top: 24px; }
.foot-col { display: flex; flex-direction: column; gap: 10px; font-size: 15px; }
.foot-col .eyebrow { margin-bottom: 6px; }
.foot-col p { color: var(--mute); font-size: 14px; }
.pill { display: inline-flex; align-items: center; gap: 8px; height: 40px; padding: 0 16px; border-radius: 20px; background: var(--paper); font-size: 14px; align-self: flex-start; }
.foot-bar { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px; margin-top: 48px; padding-top: 20px; border-top: 1px solid var(--line); font-size: 13px; color: var(--mute); }
/* R11 issue #63 (2nd rejection of #55): the DP breadcrumb folds into THIS existing row instead of
   its own band above the footer. Same ink pair the old band used (--mute on the footer card's
   white background measures well past 4.5:1); flex-wrap on the parent row already handles 390px. */
.foot-breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 12px; color: var(--mute); }
.foot-breadcrumb a { color: var(--mute); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.foot-breadcrumb a:hover, .foot-breadcrumb a:focus-visible { color: var(--ink); }
.foot-breadcrumb [aria-current="page"] { color: var(--ink); }
.social { display: flex; gap: 8px; }
.social a { width: 36px; height: 36px; border-radius: 50%; background: var(--paper); display: grid; place-items: center; }

@media (min-width: 900px) {
  .grid-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; }
  .self-end { justify-self: end; }
  .hero-copy, .hero-foot { left: max(var(--pad), calc((100% - var(--wrap)) / 2)); }
  .hero-foot { right: max(var(--pad), calc((100% - var(--wrap)) / 2)); }
  .process { padding-block: 60px; }
  .incl { padding-block: 64px; }
  .incl-card { min-height: 300px; }
  .cases { padding-block: 76px; }
  .block-numbers { padding-block: 64px; }
  .blog { margin-top: 64px; padding-top: 64px; }
  .faq { padding-block: 64px; }
  .book { padding-bottom: 64px; }
  .close { padding-block: 96px 72px; }
  .foot-sun { max-height: 240px; margin-bottom: 28px; }
}
@media (min-width: 1024px) {
  .links, .nav-cta { display: inline-flex; }
  .burger { display: none; }
  .nav.solid .nav-in { width: fit-content; gap: 30px; }
  /* ROUND-3b item 5: logo bigger (was 40px, phone stays 32px) - .nav-in keeps its fixed 72px
     height (unchanged), so a 52px-tall image sits comfortably inside without growing the pill. */
  .brand img { height: 52px; max-width: 280px; }
  .hero-copy h1 .line > span { white-space: nowrap; }

  /* FIX-1 item 11 (J ruling, kept): top-of-pin gap 56->40px, lead paragraph dropped from the
     pinned view (kept for phone, <1024px), H2 forced to one line - all still needed so the pinned
     section fits its own sticky viewport window without the lead's two extra gaps.
     ROUND-3 items 1/2 SUPERSEDE the rest of that ruling: the tab row is its own centred row again
     (no more arrows sharing it - .svc-arrows-top is deleted outright, markup+CSS+JS), and the
     arrows/counter move back below the carousel (the base .carousel > .arrows, now shown instead
     of hidden).
     J RULING (2026-09-14, round 2 on this same conflict): round 2 item 11 was the owner's explicit
     "bigger" ask for the services photo - do NOT shrink .scene to fit the old FIX-1 budget. Instead
     the budget gaps themselves are cut: tabs->slides 40->32px, slide->arrows 28->20px, arrow
     buttons 56->48px on desktop too (see .svc .arrows/.svc .arrows button below). .scene now scales
     WITH viewport height instead of a fixed figure - see the clamp() below. */
  /* J ruling (2026-09-14, 3.86px overflow fix): 34px (was 40). */
  .svc-pin { padding-top: 34px; }
  .svc-head .lead { display: none; }
  .svc-head .h2.mask .line { display: inline-block; }
  /* display:flex (not the block default) matters here: .svc-tabrow's own margin-top:24px would
     otherwise COLLAPSE with its child .seg-scroll's unrelated margin-top:36px (the base rule,
     shared with the phone layout), producing a 36px gap instead of the intended 24px - a flex
     container establishes a new block-formatting context, which blocks that collapse. */
  .svc-tabrow { display: flex; margin-top: 24px; }
  /* flex:1 1 auto so .seg-scroll actually fills the row's width - otherwise a flex item
     shrink-to-fits its content and .seg-track's own margin-inline:auto has no room to centre
     within (R3-1: the tab PILL must centre on the row, not just sit flush at its shrink-to-fit
     size). */
  .svc-tabrow .seg-scroll { flex: 1 1 auto; margin-top: 0; overflow: visible; }
  /* J ruling: tabs->slides gap 32px at >=1024 (was 40px). */
  .svc .carousel { margin-top: 32px; }
  /* J ruling (2026-09-14, round 3 on the pin-budget conflict): the copy column, not the scene, was
     the actual lever - .track's default align-items:stretch makes the carousel row as tall as the
     TALLEST of the 5 slides' .slide-copy content, independent of scene height. Trimmed padding/
     gap/type at >=1024 only to bring the tallest slide-copy to <=440px. */
  .svc .slide { padding: 20px 26px 20px 20px; }
  .svc .slide-copy { gap: 10px; }
  .svc .slide-copy h3 { font-size: 44px; }
  .svc .slide-copy > p:not(.sub) { font-size: 16px; line-height: 1.6; }
  .svc .subs li { font-size: 13px; }
  /* J ruling (2026-09-14, fallback authorized): the row trim alone left the tallest slide-copy at
     440px but the SLIDE's own vertical padding (20+20) still pushed the pin 3.86px over at
     1440x900 - the one authorized further lever is the CTA row's button height. */
  .svc .slide-copy .row .btn { height: 44px; }
  /* J ruling (2026-09-14): the photo scales WITH viewport height instead of a fixed figure - 380px
     floor, 560px ceiling (round 2 item 11's "bigger" ask, never cut below this), 100vh-460px in
     between. 440px measured at 1440x900. Accepted consequence: at 1024x768 the pin overflows by
     ~70px (380px floor + the tighter 32/20px gaps still exceed the 660px sticky window there) -
     1024x768 is outside the official ROUND-3 battery viewports (1440x900/390x844/reduced), so this
     is J-accepted, not a defect. */
  /* J ruling (2026-09-14): 100vh-466 (was 460), shrinking the photo 6px in lockstep with the
     6px padding-top cut above - 434px at 1440x900. */
  /* #91 fix round: min 380px -> 240px so the pinned arrows + counter stay on screen on short
     desktops (1024x768 / 1280x720 / 1366x768 arrows bottom was 823/832/835px). Same formula, so
     1440x900 (434px) and 1920x1080 (560px) are unchanged. */
  .svc .scene { aspect-ratio: auto; height: clamp(240px, calc(100vh - 466px), 560px); }
  /* ROUND-3 item 10: >=1024px the process steps render as a plain 3-up CSS grid, full opacity, NO
     v4 focus-dimming (there's no .focus class in v5 to begin with, and the stack mechanism itself
     is off at this width - see the matchMedia guard in stack-cards.js - so nothing dims/scales
     these cards at all). */
  .steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
  /* stack-cards.css's own >=1024px rule puts the loop BESIDE the copy (grid-template-columns:
     1.1fr 1fr) inside each [data-stack-card] - wrong here, where the loop sits ABOVE the copy.
     Two classes beats stack-cards.css's one class regardless of stylesheet load order, forcing the
     loop-on-top / copy-below layout the DOM order (figure before .stack-card-copy) already gives. */
  .steps .stack-card-in { grid-template-columns: 1fr; }
}

@media (max-width: 899px) {
  :root { --nav-h: 72px; --sec: 56px; }
  .nav { padding: 0 12px; }
  /* ROUND-3b item 3: 12px right padding (was 4px) - the burger circle poked past the pill's own
     right edge at 4px; measured gap now 12px (target >=10). */
  .nav-in { height: 72px; padding: 0 12px 0 12px; }
  .brand img { height: 32px; max-width: 220px; }
  .scrub-hint { display: none; }
  .hero { height: calc(var(--screen) * 1.5); }
  /* ROUND-3b item 1: sits lower (was +28px). */
  .hero-copy { top: calc(var(--nav-h) + 72px); bottom: auto; transform: none; max-width: calc(100% - 2 * var(--pad)); font-size: 16px; }
  .hero-copy h1 { font-size: clamp(38px, 10vw, 54px); }
  .hero-copy h1 .line > span { white-space: nowrap; }
  .hero-copy h1 .line:last-child > span { font-size: clamp(28px, 8.4vw, 46px); }
  .hero-copy .lead-more { display: none; }
  .hero-copy .row { flex-direction: column; align-items: stretch; }
  .hero-copy .row .btn { width: 100%; }
  .hero-shade-x { background: linear-gradient(90deg, rgba(6,20,18,.45), rgba(6,20,18,.08)); }
  .hero-shade-y { background: linear-gradient(180deg, rgba(6,20,18,.9) 0%, rgba(6,20,18,.5) 48%, rgba(6,20,18,0) 72%); }
  .about { height: calc(var(--screen) * 1.5); }
  .about-pin { position: sticky; height: var(--screen); min-height: 0; padding: calc(var(--nav-h) + 12px) 0 24px; align-items: flex-start; }
  .grid-about { height: 100%; grid-template-columns: 1fr; gap: 14px; align-content: center; }
  .about-media { order: -1; width: min(100%, 250px); max-height: 34vh; justify-self: center; }
  /* FIX-2 #20: max-width:90% of the OLD 230px container capped this at 207px, short of the
     specified 220px. Container widened to 250px and the cap relaxed to 100% so 220px is reachable
     while still shrinking gracefully on narrower screens. */
  .about-logo > img, .about-logo > img.asset-missing { width: 220px; max-width: 100%; }
  .reveal-words { font-size: clamp(23px, 6.5vw, 30px); line-height: 1.48; }
  .about-more .stats { margin: 18px 0; gap: 12px 20px; }
  .about-more .stats span { font-size: 11px; }
  [data-carousel-runway] { min-height: calc(var(--screen) * 1.35); }
  .svc-pin { padding: 36px 0 12px; }
  .svc-head .h2 { font-size: 27px; }
  .svc-head .lead { font-size: 14px; line-height: 1.5; }
  /* Row A fix (#75): all five tabs visible, wrapped as their own pills, never a sideways-scrolling
     "cut off"-looking strip. .seg-scroll stops scrolling/fading; .seg-track wraps, centred, no
     min-width and no track-background pill behind the row (each pill carries its own outline). */
  .seg-scroll { width: 100%; margin-left: 0; margin-top: 24px; overflow: visible; scroll-snap-type: none; }
  .seg-track { flex-wrap: wrap; justify-content: center; gap: 8px; margin-inline: auto; min-width: 0; width: 100%; padding: 0; border-radius: 0; background: none; }
  /* No shared sliding indicator on phone: its transform, animated while [data-svc-tabs]'s own
     ancestor scrolls natively, was the suspected cause of the tab labels rendering stacked
     (fix round 2 item 2). The active tab gets its own solid fill instead. */
  [data-svc-tabs] .seg-ind { display: none; }
  [data-svc-tabs] button.on { background: var(--amber); }
  /* display:inline-flex (not the base grid-template-columns: auto 1fr auto) -- the base grid kept
     two empty tracks (for the now-hidden <small>) contributing their own 8px gaps to every pill's
     width, which was enough to wrap 定期付款/保證定期付款/整筆款額 into 2+2+1 instead of 3+2 at 390px
     (measured). flex:0 0 auto (not the base flex:1 0 auto) so a pill sizes to its own label
     instead of stretching to fill the wrapped row, which is what justify-content: center needs to
     actually centre a short last row. */
  .seg-track button { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: 0; height: 44px; padding-inline: 14px; border-radius: 999px; font-size: 14px; border: 1px solid rgba(255,255,255,.22); }
  .seg-track button.on { border-color: transparent; }
  .seg-track button small { display: none; }
  .carousel { --slide-w: calc(100vw - 2 * var(--pad)); margin-top: 12px; }
  @supports (width: 1cqw) { .carousel { --slide-w: calc(100cqw - 2 * var(--pad)); } }
  /* ROUND-3 item 1: gap tab row -> slide row is 24px at phone (32px at >=1024, see that media
     block; J ruling 2026-09-14 cut both from 28/40px). .svc .carousel beats the generic .carousel
     rule above on specificity regardless of source order. */
  .svc .carousel { margin-top: 24px; }
  .slide { grid-template-columns: 1fr; gap: 14px; padding: 16px; }
  .scene { aspect-ratio: 16/10; }
  .svc .scene { aspect-ratio: 16/11; }
  .slide-copy { gap: 8px; }
  .slide-copy h3 { font-size: 28px; }
  .svc .slide-copy h3 { font-size: 30px; }
  .slide-copy .sub { font-size: 16px; }
  .slide-copy > p:not(.sub) { font-size: 13px; line-height: 1.5; }
  .subs { gap: 5px; }
  .subs li { padding: 6px 8px; font-size: 11px; }
  .slide-copy .btn { height: 42px; }
  .arrows { margin-top: 8px; }
  .svc .arrows button { width: 48px; height: 48px; }
  .process .head-row { margin-bottom: 20px; }
  .steps { gap: 16px; }
  .steps .card { padding: 22px; }
  /* ROUND-3 item 12: loop shrinks to a centred 220px square (whole object visible, R2); already
     above the copy in the DOM (item 10's reorder), so no order change needed here. */
  .steps .paint { width: 220px; max-height: 220px; margin: 0 auto 8px; }
  .grid-incl { grid-template-columns: 1fr; gap: 24px; }
  .sticky-col { position: static; min-height: 0; }
  .sticky-col .eyebrow { margin-bottom: 0; }
  .incl-list { display: none; }
  /* FIX-1 (CRITIC-2-phone #2): .incl-list was the only block-level element separating the
     eyebrow from whatever followed; hiding it on phone left the new .sticky-col-cta (item 15, a
     `.btn` = inline-flex) flowing onto the SAME line as the eyebrow text with almost no gap.
     Force it block-level with its own top margin regardless of what precedes it. */
  .sticky-col-cta { display: flex; margin-top: 16px; }
  .incl-cards { gap: 10px; }
  /* Extra bottom padding keeps the fixed WhatsApp fab off the card's last line of text; trimmed
     from 72px (fix round 2 item 5, phone-only, WORK-ORDER: bring the phone total to <=18.0
     screens by tightening §5/§7 padding/gaps, not by touching desktop rules or the fab itself). */
  .incl-card { grid-template-columns: 1fr; gap: 10px; min-height: 0; padding: 12px 12px 44px; }
  /* ROUND-3 item 13: 220px centred square, whole object visible (R2), no crop. */
  .incl-card .paint { width: 220px; max-width: 220px; aspect-ratio: 1; justify-self: center; margin-inline: auto; }
  .mobile-incl-heading { display: block; }
  .mobile-incl-heading h3 { font-size: 28px; margin-top: 3px; }
  .incl-copy > h3 { display: none; }
  .cases .slide { grid-template-columns: 1fr; }
  .counters { grid-template-columns: 1fr 1fr; }
  /* Phone-only trim (fix round 2 item 5): §7 read as padding relative to its content (4 short
     stat tiles running ~3 screens); tightened bottom/top padding and icon margin, same grid. */
  .stat-col { padding: 0 18px 16px; }
  .stat-col:nth-child(odd) { padding-left: 0; border-left: 0; }
  .stat-col:nth-child(n+3) { padding-top: 14px; border-top: 1px solid var(--line-d); }
  .paint-mini { width: 96px; margin-bottom: 10px; }
  .block-numbers { padding: 28px 0; }
  .stat-col > b { margin-top: 6px; }
  .posts { grid-template-columns: 1fr; gap: 20px; }
  .grid-faq { grid-template-columns: 1fr; gap: 34px; }
  .faq-visual { min-height: 420px; }
  .book-card { grid-template-columns: 1fr; padding: 22px; gap: 20px; }
  .book-form { padding: 20px; gap: 10px; }
  .foot-grid { grid-template-columns: 1fr 1fr; gap: 34px 24px; }
}

/* ROUND-3 item 7: mobile headline centred (eyebrow, H1 both lines, lead, buttons). Text-align on
   the container is enough - .hero-copy already spans the full inner width at <=899px (left+right
   both set to --pad, width:auto fills the gap), so nothing needed a width/position change; buttons
   stay full-width via the existing <=899px .hero-copy .row .btn rule. Desktop (>=1024) is
   untouched - .hero-copy keeps its left-aligned absolute position from the base rule. */
@media (max-width: 767px) {
  .hero-copy { text-align: center; margin-inline: auto; }
  /* ROUND-3b item 2: text-align:center on the ancestor only centres INLINE content within a box -
     .lead is a block-level <p> with its own max-width:50ch, so its BOX still sits flush left
     without its own auto margins (image 44's actual bug), regardless of the H1 above it. */
  .hero-copy .lead { margin-inline: auto; text-align: center; }
}

@media (max-width: 699px) {
  /* Force the numbers H2's second line to break at the comma, never inside 新開始. */
  .numbers-h2 .hi .ph { display: block; }
}

@media (max-width: 599px) {
  .loader-pct { font-size: 44px; }
  .loader-logo { width: 150px; }
  .loader-meta { margin-top: 30px; }
  .hero-copy .lead { font-size: 15px; line-height: 1.6; }
  .hero-copy .row .btn { padding-inline: 17px; }
  .about-media { max-height: 34vh; }
  .stats { grid-template-columns: repeat(3, 1fr); }
  .stats b { font-size: 26px; }
  .process { padding-bottom: 42px; }
  .incl { padding: 24px 0; }
  .cases .head-row { margin-bottom: 28px; }
  .cases .slide-copy { gap: 12px; }
  .cases blockquote { font-size: 17px; }
  .blog { margin-top: 56px; padding-top: 56px; }
  .blog-tools { align-items: stretch; }
  .chip-scroll { width: 100%; scroll-snap-type: x proximity; -webkit-mask-image: linear-gradient(to right, black 88%, transparent); mask-image: linear-gradient(to right, black 88%, transparent); }
  .chips { margin-left: 0; }
  .chips button { scroll-snap-align: center; }
  .search { width: 100%; }
  .search input { width: 100%; }
  .faq-visual { min-height: 420px; }
  .faq-person { width: 88%; }
  .callout.big { width: 76%; }
  .book { padding-inline: 12px; }
  .book-info { padding-inline: 0; }
  .book-info .row { align-items: stretch; }
  .book-info .row .btn { flex: 1; }
  .foot { padding-inline: 12px; }
  .foot-grid { grid-template-columns: 1fr 1fr; gap: 28px 18px; }
  .foot-brand { grid-column: 1 / -1; }
  .foot-col:last-child { grid-column: 1 / -1; }
  .foot-col { font-size: 14px; }
  .foot-bar { margin-top: 32px; }
  .foot-sun { aspect-ratio: 16/9; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .wheel::after { animation: none; }
  .hero { height: var(--screen); }
  .about { height: auto; }
  .about-pin { position: relative; height: auto; min-height: var(--screen); }
  [data-carousel-runway] { min-height: auto; }
  [data-carousel-pin] { position: relative; top: 0; }
  .reveal-words .w { opacity: 1; filter: none; color: var(--green); background: none; }
  .about-more { opacity: 1; transform: none; }
  [data-stack-card] { position: static !important; transform: none !important; opacity: 1 !important; top: auto !important; }
}

/* divorce-procedure */
/* --bg-line-step: measured-pixel background for the step-1..5 line-art stills. --dp-charcoal is
   kept as a token even though nothing in THIS file uses it any more (issue #15 ruling: charcoal
   is reserved for the active phase card, owned by Steps/Process's own upcoming CSS file). */
.dp-page { --bg-still-ba-alone: #F7F6F0; --bg-still-ba-together: #EFF0E9; --bg-line-step: #FEFEFE; --dp-charcoal: #151A18;
  /* Motion batch 1 (2026-09-16): CSS linear() spring curves, kora's own Motion-library spring
     generator sampled at .46/.56/.76s - still used by kora-reveal.js's SPRING_TIERS for blocks
     6 (pricing), 7 (process), 8 (consultant) and 9 (cases). */
  --ease46: linear(0,0.0053295,0.02025807,0.04329053,0.07305616,0.10830556,0.1479067,0.19084034,0.23619484,0.28316066,0.3310245,0.37916331,0.42703812,0.47418797,0.52022378,0.56482234,0.60772053,0.64870963,0.68762992,0.72436546,0.75883924,0.79100849,0.82086041,0.84840806,0.87368664,0.89675002,0.91766762,0.93652144,0.95340353,0.96841357,0.9816568,0.99324214,1.00328055,1.01188358,1.01916213,1.02522542,1.03018002,1.03412918,1.03717219,1.03940388,1.04091432,1.04178847,1.04210606,1.04194148,1.04136375,1.04043655,1.03921829,1.03776229,1.03611686,1.03432556,1.03242738,1.03045697,1.0284449,1.02641792,1.02439918,1.02240853,1.02046273,1.01857577,1.01675906,1.01502167,1.0133706,1.01181098,1.01034624,1.00897839,1.00770811,1.006535,1.00545769,1.00447401,1.00358112,1.00277564,1.00205372,1.00141123,1.00084374,1.0003467,0.99991544,0.99954525,0.99923147,0.99896948,0.99875478,0.99858299,0.99844992,0.99835155,0.99828405,0.99824381,0.99822745,0.99823181,0.99825394,0.99829115,0.99834092,0.998401,0.99846933,0.99854403,1);
  --ease56: linear(0,0.00362873,0.01392117,0.03002996,0.05116482,0.07659153,0.10563067,0.13765606,0.17209302,0.2084165,0.24614902,0.28485858,0.32415638,0.36369465,0.40316428,0.44229258,0.48084095,0.51860265,0.55540054,0.59108494,0.62553143,0.6586389,0.69032746,0.72053664,0.74922347,0.77636083,0.80193575,0.82594789,0.84840806,0.86933684,0.88876333,0.9067239,0.92326116,0.93842285,0.95226097,0.96483089,0.97619055,0.98639979,0.99551965,1.00361185,1.01073824,1.01696033,1.02233895,1.02693384,1.03080338,1.03400432,1.03659157,1.03861804,1.04013446,1.0411893,1.0418287,1.04209636,1.04203358,1.04167918,1.04106958,1.04023874,1.03921829,1.03803751,1.03672342,1.03530086,1.03379253,1.03221914,1.03059943,1.0289503,1.02728689,1.02562269,1.02396963,1.02233817,1.0207374,1.01917514,1.01765802,1.01619158,1.01478038,1.01342802,1.01213729,1.0109102,1.00974809,1.00865167,1.00762111,1.00665608,1.00575583,1.00491924,1.00414487,1.00343098,1.00277564,1.00217669,1.00163185,1.0011387,1.00069475,1.00029743,0.99994416,0.99963233,0.99935934,0.99912262,0.99891964,0.99874793,0.99860507,0.99848872,0.99839664,0.99832666,0.99827671,0.99824482,0.99822911,0.99822882,0.99823928,0.99826193,0.99829431,0.99833506,0.99838291,0.9984367,0.99849536,0.99855791,1);
  --ease76: linear(0,0.00199181,0.00772667,0.0168565,0.02905016,0.04399331,0.06138816,0.08095319,0.10242286,0.12554726,0.15009171,0.17583637,0.20257583,0.23011863,0.25828681,0.28691543,0.31585211,0.3449565,0.37409981,0.40316428,0.43204272,0.460638,0.48886252,0.51663779,0.54389388,0.57056901,0.59660901,0.62196697,0.64660269,0.67048232,0.69357792,0.71586707,0.73733243,0.75796144,0.77774588,0.79668159,0.81476808,0.83200825,0.84840806,0.86397625,0.87872406,0.89266498,0.90581449,0.91818983,0.92980977,0.94069442,0.95086503,0.96034379,0.96915369,0.97731833,0.9848618,0.99180854,0.99818317,1.00401046,1.00931515,1.01412187,1.01845507,1.02233895,1.02579734,1.02885368,1.03153095,1.03385162,1.03583759,1.03751019,1.03889011,1.03999739,1.04085141,1.04147083,1.04187364,1.0420771,1.04209774,1.0419514,1.04165316,1.0412174,1.04065781,1.03998735,1.03921829,1.03836223,1.0374301,1.03643216,1.03537806,1.03427682,1.03313686,1.03196602,1.03077159,1.0295603,1.02833837,1.02711153,1.02588501,1.0246636,1.02345164,1.02225308,1.02107145,1.01990991,1.01877127,1.01765802,1.0165723,1.01551599,1.01449068,1.01349768,1.01253809,1.01161277,1.01072236,1.00986733,1.00904795,1.00826433,1.00751645,1.00680412,1.00612705,1.00548483,1.00487695,1.0043028,1.00376172,1.00325293,1.00277564,1.00232896,1.00191201,1.00152381,1.00116341,1.00082978,1.00052192,1.00023879,0.99997935,0.99974256,0.99952737,0.99933276,0.99915769,0.99900116,0.99886216,0.99873971,0.99863286,0.99854067,0.99846223,0.99839664,0.99834305,0.99830063,0.99826856,0.99824608,0.99823243,0.99822691,0.99822882,0.99823752,0.99825238,0.9982728,0.99829823,0.99832812,0.99836197,0.99839931,0.99843968,0.99848266,0.99852786,0.9985749,1);
}

/* H (2026-09-15, WORK-ORDER §H) / Defect 2 (owner, 2026-09-15, OVERRULES H3): kora restyle kept
   only for size/letter-spacing/vertical rhythm; typeface stays the house serif so this page reads
   as one brand with the homepage. */
.dp-kora h1, .dp-kora .h2 { font-family: var(--serif); font-weight: 500; }
.dp-kora h1 { letter-spacing: -.02em; }
.dp-kora .h2 { letter-spacing: -.015em; }
.dp-giant-label { display: block; margin-bottom: 0.5em; font-family: var(--serif); font-weight: 500; font-size: clamp(56px, 8.3vw, 120px); line-height: 1.15; letter-spacing: -.03em; color: inherit; }
.dp-link-arrow { display: inline-flex; align-items: center; gap: 8px; height: auto; padding: 0; background: none; border: none; color: inherit; font-size: 15px; font-weight: 600; line-height: 1; text-decoration: underline; text-underline-offset: 4px; }

.dp-statement { padding: calc(var(--sec) * 1.3) 0; background: var(--paper); color: var(--ink); }
.dp-statement p { max-width: 900px; margin-inline: auto; margin-bottom: 0.5em; font-family: var(--serif); font-size: clamp(30px, 4.2vw, 64px); font-weight: 500; letter-spacing: -.03em; line-height: 1.15; text-align: center; line-break: strict; }
.dp-statement p .clause { display: inline-block; }
/* .dp-before-after: base section styling only (bare wrapper, not the .dp-ba-* card family that
   moves to a new component/CSS file) - BeforeAfter.astro itself is out of this task's scope. */
.dp-before-after { padding: var(--sec) 0; background: var(--paper); color: var(--ink); }

/* .dp-steps: base section styling only (bare wrapper, not the .dp-chapter / .dp-step-art / .dp-object
   family that moves to a new component/CSS file) - Steps.astro itself is out of this task's scope.
   Integrator note (2026-09-17): this comment previously joined ".dp-chapter" and "/.dp-step-art"
   with no space between the star and the slash, which is the two-character comment-close token -
   it closed this comment early, dropping the .dp-steps rule below from the parsed stylesheet
   entirely (measured: absent from document.styleSheets' cssRules) - background was silently
   falling through to transparent. Fixed by spacing the punctuation apart; never join a word ending
   in an asterisk directly to a following slash inside a CSS comment. */
.dp-steps { padding: var(--sec) 0; border-radius: var(--r-sec); overflow: visible; background: var(--paper); color: var(--ink); }
/* R7 issue #32: matches the homepage's own heading->content gap (.process .head-row {
   margin-bottom: 42px }, 20px at <=899px, public/site.css:602) - this section had none, so its
   chart/cards sat flush under the lead paragraph while the wait-chart's own 36/52px margins (below)
   ballooned the gap AFTER the heading instead. */
.dp-steps-head { max-width: 820px; margin-bottom: 42px; }
.dp-steps-head .lead { margin-top: 20px; }
/* R7 issue #32: was 36px/52px - measured against the homepage's .process (--sec-derived, ~42px
   rhythm) this read as excess air above and below a chart that is only 3 rows tall. */
.dp-wait-chart { display: grid; gap: 12px; max-width: 900px; margin: 24px 0 32px; }
.dp-chart-row { display: grid; grid-template-columns: minmax(190px, 1fr) minmax(180px, 2fr) 90px; align-items: center; gap: 18px; font-size: 14px; }
.dp-chart-row > i { height: 12px; overflow: clip; border-radius: var(--r-pill); background: color-mix(in srgb, var(--ink) 10%, transparent); }
.dp-chart-row > i > b { display: block; height: 100%; border-radius: inherit; background: var(--amber); transform-origin: left center; }
.dp-fill-short { width: 36%; }
.dp-fill-mid { width: 79%; }
.dp-fill-full { width: 100%; }

/* #12/#15 (owner, 2026-09-16): pricing is a rounded highlighted card inset from the viewport edges
   like .book-card, on the brand green (the homepage .dark treatment) - never the near-black
   charcoal chapter it used to be. Charcoal is reserved for the active phase card elsewhere. */
.dp-pricing { padding: var(--sec) 0; margin-inline: auto; max-width: calc(var(--wrap) + 48px); }
.dp-pricing-head { display: flex; justify-content: space-between; align-items: end; gap: 24px; }
.dp-trust-pills { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.dp-trust-pills span { padding: 6px 13px; border: 1px solid currentColor; border-radius: var(--r-pill); font-size: 13px; line-height: 1.3; color: var(--white); }
.dp-pricing-grid { display: grid; grid-template-columns: minmax(280px, 2fr) minmax(0, 3fr); gap: 24px; align-items: start; margin-top: 36px; }
.dp-plan-list { display: grid; gap: 8px; padding: 0; border-radius: var(--r-card); background: transparent; color: var(--paper); }
.dp-plan-row { display: grid; grid-template-columns: minmax(0, 1fr) 20px; gap: 12px; align-items: center; width: 100%; padding: 15px; border-radius: var(--r-sm); background: color-mix(in srgb, var(--paper) 6%, transparent); color: var(--paper); text-align: left; }
.dp-plan-row.on { background: color-mix(in srgb, var(--paper) 11%, transparent); box-shadow: inset 0 0 0 2px var(--amber); }
.dp-plan-row > span, .dp-plan-row > span > span { display: block; }
.dp-plan-row > span > span { margin-top: 5px; color: var(--mute-d); font-size: 13px; }
.dp-plan-row b small { display: inline-block; margin-left: 4px; padding: 3px 7px; border-radius: var(--r-pill); background: var(--amber); color: var(--ink); font-size: 11px; }
.dp-plan-row > i { width: 18px; height: 18px; border: 2px solid var(--mute-d); border-radius: 50%; }
.dp-plan-row.on > i { border-color: var(--amber); background: var(--amber); box-shadow: inset 0 0 0 4px var(--green); }
.dp-plan-foot { margin-top: 16px; color: var(--mute-d); font-size: 14px; }
.dp-price-card { padding: clamp(24px, 3vw, 38px); border: 1px solid var(--line-d); border-radius: 30px; background: color-mix(in srgb, var(--paper) 6%, transparent); color: var(--paper); }
.dp-price-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 20px; }
.dp-price-top .eyebrow { margin-bottom: 6px; }
.dp-price-top .price { font-family: var(--serif); font-size: clamp(34px, 4vw, 54px); font-weight: 500; line-height: 1.1; color: var(--amber); }
.dp-price-card > p:not(.dp-price-foot) { margin-top: 18px; color: var(--mute-d); }
.dp-price-ticks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 20px; margin-top: 22px; }
.dp-price-ticks li { position: relative; padding-left: 25px; color: var(--paper); }
.dp-price-ticks li::before { content: "✓"; position: absolute; left: 0; color: var(--amber); font-weight: 700; }
.dp-price-foot { margin-top: 20px; color: var(--mute-d); font-size: 13px; }

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

/* #18: FAQ's "顯示更多問題" button and filter chips reuse the homepage's own .btn-outline and
   .chips/.seg-ind look exactly (not a new style) - scoped to .faq only, so the homepage's own
   dark-ground uses of those same classes (services tabs, blog filters) are untouched. Both are
   tuned for a dark/green ground and unreadable as-is on the FAQ's light paper section; this is a
   contrast/legibility correction, not a redesign. */
.faq .btn-outline { color: var(--ink); border-color: var(--line); }
.faq .chips { background: rgba(16, 32, 27, .06); }
.faq .chips button { color: var(--ink); }

@media (max-width: 899px) {
  .dp-pricing-grid { grid-template-columns: 1fr; }
  .dp-pricing-head { align-items: flex-start; flex-direction: column; }
  .dp-trust-pills { justify-content: flex-start; }
  /* R7 issue #32: same <=899px tightening as the homepage's own .process .head-row (line ~602) -
     placed in THIS later media block (not the earlier one) because the unconditional
     `.dp-steps-head { margin-bottom: 42px }` rule (line ~765) sits between the two in source
     order; a same-specificity override earlier in the file loses that cascade regardless of its
     media condition. */
  .dp-steps-head { margin-bottom: 20px; }
}

@media (max-width: 599px) {
  .dp-statement { padding-block: 72px; }
  .dp-chart-row { grid-template-columns: 1fr 64px; gap: 6px 12px; }
  .dp-chart-row > i { grid-column: 1 / -1; grid-row: 2; }
  .dp-chart-row > strong { grid-column: 2; grid-row: 1; text-align: right; }
  .dp-price-top { align-items: flex-start; }
  .dp-price-top .btn { width: 100%; }
  .dp-price-ticks { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .dp-chart-row > i > b { transform: none !important; }
}
