/* psikotes.fyi: one stylesheet for every page. Premium look (10 Nov 2026, design board "Psikotes tokens — old vs new"):
   refined white ground with answer-sheet (LJK) pink rules, deep teal only for the main action, links and the work line,
   ochre for "perlu dilatih", Inter for headings (weight 740-760, tight) and text, Geist Mono for numbers, 4 px corners, no pills.
   Storybook gouache images (design/art/app-images.sh) at the moments that matter, never inside the timed test. */
@font-face { font-family: "Inter"; src: url("/fonts/inter-latin-wght-normal.woff2") format("woff2-variations"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("/fonts/geist-mono-latin-500-normal.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("/fonts/geist-mono-latin-600-normal.woff2") format("woff2"); font-weight: 600; font-display: swap; }

:root {
	/* 15 colors (10 Nov 2026). One accent, used only for the main action, links and the work line. */
	--ground: #FFFFFF;
	--sunken: #F6F6F7;
	--line: #E4E4E7;
	--field-line: #8A8A93;
	--ink: #111113;
	--body: #3F3F46;
	--muted: #52525B;
	--ljk: #F3C7BD;
	--accent: #0B5F58;
	--accent-dark: #084842;
	--accent-soft: #E3EFED;
	--good: #16794A;
	--ochre: #8A5A00;
	--ochre-soft: #F8EDD3;
	/* Real errors only (payment failed, form errors). A weak score is ochre, not red. */
	--warn: #A8261B;
	--font: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
	--display: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
	--mono: "Geist Mono", ui-monospace, Menlo, monospace;
	--r: 4px;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body { margin: 0; background: var(--ground); color: var(--body); font-family: var(--font); font-size: 16px; line-height: 1.55; letter-spacing: -0.011em; font-kerning: normal; }
img, svg { display: block; max-width: 100%; height: auto; }
a { color: var(--accent); text-underline-offset: 2px; }

h1, h2, h3 { margin: 0; font-family: var(--display); font-weight: 600; line-height: 1.22; letter-spacing: -0.015em; color: var(--ink); text-wrap: balance; }
p { margin: 0; max-width: 65ch; }
p, li, span, .lead, .fine { text-wrap: pretty; }
button { font: inherit; color: inherit; }
/* No grey or blue flash from the phone browser on tap; every control has its own pressed state. */
a, button, summary, [role="button"] { -webkit-tap-highlight-color: transparent; }
.btn:active { transform: scale(0.98); }
.options button:not(:disabled):active, .chip:active, .area:active { background: var(--sunken); }
/* State borders, one system (9 Nov 2026): a border is always 1 px, so a state never shifts or misaligns anything.
   A stronger state (selected, right, wrong, ragu-ragu) adds a 1 px inner line with box-shadow inset. Keyboard focus is
   one dark ring for every control, which shows on white, on soft fills and on the red buttons alike. Hover borders
   only apply on devices with a mouse, so a tap on a phone never leaves a red border behind. */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.mono { font-family: var(--mono); }

/* Columns: an app screen at phone width, a page up to 1080 px. */
.screen { max-width: 460px; margin: 0 auto; min-height: 100dvh; padding: 12px 20px 32px; display: flex; flex-direction: column; gap: 24px; }
.page { max-width: 1080px; margin: 0 auto; padding: 12px 20px 40px; display: flex; flex-direction: column; gap: 48px; }
.stack { display: flex; flex-direction: column; gap: 16px; }
.stack-8 { display: flex; flex-direction: column; gap: 8px; }
.row { display: flex; gap: 12px; align-items: center; }

.bar { display: flex; align-items: center; justify-content: space-between; min-height: 56px; }
.bar { border-bottom: 1px solid var(--ljk); }
.brand { display: inline-flex; align-items: center; gap: 8px; text-decoration: none; color: var(--ink); }
.brand svg { width: 28px; height: 28px; flex: none; }
.brand .wm { font-family: var(--display); font-weight: 650; font-size: 21px; line-height: 1; letter-spacing: -0.02em; }
.brand .wm span { font-family: var(--mono); font-weight: 500; font-size: 16px; color: var(--accent); letter-spacing: 0; }
.bar a.quiet { font-size: 16px; font-weight: 600; text-decoration: none; padding: 12px 4px; letter-spacing: -0.009em; }

/* Type scale: display 42/44, title 30/34, section 24/28, lead 18/28, body 16/26, meta 14/20, label 13/16. */
.h-xl { font-size: clamp(34px, 8.6vw, 48px); line-height: 1.15; letter-spacing: -0.025em; font-weight: 700; }
.h-lg { font-size: clamp(25px, 6.4vw, 32px); line-height: 1.22; letter-spacing: -0.015em; }
.h-md { font-size: 21px; line-height: 1.27; font-weight: 600; letter-spacing: -0.01em; }
.lead { font-size: 18px; line-height: 1.55; letter-spacing: -0.014em; color: var(--body); }
.fine { font-size: 14px; line-height: 1.5; letter-spacing: -0.006em; color: var(--muted); }
.center { text-align: center; }
.num { font-family: var(--mono); font-weight: 600; letter-spacing: -0.02em; }
.mono { letter-spacing: 0; }

/* Buttons and inputs. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 56px; padding: 16px 20px; border-radius: var(--r); border: 1px solid transparent; font-weight: 600; font-size: 16px; line-height: 1.25; letter-spacing: -0.011em; text-decoration: none; cursor: pointer; text-align: center; }
.btn-primary { background: var(--accent); color: #fff; }
@media (hover: hover) { .btn-primary:not(:disabled):hover { background: var(--accent-dark); } }

.btn-primary:disabled { background: var(--field-line); cursor: not-allowed; }
.btn-ghost { background: var(--ground); border-color: var(--ink); color: var(--ink); }

.btn-block { width: 100%; }
.btn .arrow { width: 18px; height: 18px; }
/* Text field (custom, never the browser default): label, a box with a leading icon, a state icon on the right, and a
   help line that turns into the error. The box shows focus with a soft ring, and autofill keeps our colors. */
.field { display: flex; flex-direction: column; gap: 8px; }
.field > label { font-weight: 600; font-size: 16px; letter-spacing: -0.009em; }
.input { display: flex; align-items: center; gap: 10px; height: 56px; padding: 0 12px 0 14px; border: 1px solid var(--field-line); border-radius: var(--r); background: var(--ground); transition: border-color 0.15s, box-shadow 0.15s; }

.input:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(11, 95, 88, 0.2); }
.input > .ic { width: 20px; height: 20px; }
.input input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; outline: 0; background: transparent; font: inherit; font-size: 16px; letter-spacing: -0.013em; color: var(--ink); }
.input input:focus-visible { outline: none; }
.input input::placeholder { color: var(--field-line); opacity: 1; }
.input input:-webkit-autofill { -webkit-box-shadow: 0 0 0 40px var(--ground) inset; -webkit-text-fill-color: var(--ink); caret-color: var(--ink); }
.input .state { width: 20px; height: 20px; flex: none; display: none; }
.input[data-state="ok"] .state-ok, .input[data-state="error"] .state-error { display: block; }
.input[data-state="error"] { border-color: var(--warn); }
.input[data-state="error"]:focus-within { box-shadow: 0 0 0 3px rgba(168, 38, 27, 0.2); }
.field-help { font-size: 13px; line-height: 1.4; color: var(--muted); }
.field-help[data-state="error"] { color: var(--warn); font-weight: 500; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { min-height: 44px; padding: 10px 14px; border-radius: var(--r); border: 1px solid var(--line); background: var(--ground); font-size: 16px; font-weight: 500; cursor: pointer; }
.chip[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: var(--accent-soft); color: var(--accent-dark); font-weight: 600; }

/* Cards and notes. */
.card { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 20px; }
.note { background: var(--sunken); border-radius: var(--r); padding: 14px 16px; font-size: 16px; color: var(--body); }
.receipt { display: flex; flex-direction: column; gap: 4px; font-size: 16px; color: var(--body); }
.back { font-size: 16px; font-weight: 600; text-decoration: none; }
.foot { margin-top: auto; padding-top: 24px; border-top: 1px solid var(--line); font-size: 14px; color: var(--muted); }
.foot a { color: var(--muted); }

/* ---------- Landing ---------- */
.hero { display: grid; gap: 24px; align-items: center; }
.hero-copy { display: flex; flex-direction: column; gap: 16px; }
.hero-art { width: 100%; border-radius: var(--r); }
.trust { display: flex; flex-wrap: wrap; gap: 6px 16px; padding: 0; margin: 0; list-style: none; font-size: 14px; color: var(--muted); }

.section-head { display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.types { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.type { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; display: flex; flex-direction: column; }
.type img { aspect-ratio: 1; object-fit: cover; background: var(--ground); }
.type div { padding: 12px 14px 16px; display: flex; flex-direction: column; gap: 4px; }
.type b { font-size: 16px; }
.type span { font-size: 14px; color: var(--muted); line-height: 1.45; }
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; counter-reset: s; }
.steps li { counter-increment: s; display: flex; gap: 14px; align-items: flex-start; background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 16px; }
.steps li::before { content: counter(s); font-family: var(--mono); font-weight: 600; color: var(--accent); font-size: 18px; min-width: 18px; }
.steps b { display: block; }
.steps span { color: var(--muted); font-size: 16px; }
.offer-box { display: grid; gap: 24px; align-items: center; background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 24px; }
.ticks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.ticks li { display: flex; gap: 10px; align-items: flex-start; font-size: 16px; }
.ticks li::before { content: ""; flex: none; width: 18px; height: 18px; margin-top: 3px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231D4ED8' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / 18px no-repeat; }
.ticks li.guide::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234F5B69' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 5h11a3 3 0 0 1 3 3v11H7a3 3 0 0 1-3-3V5z'/%3E%3Cpath d='M8 9h6M8 13h6'/%3E%3C/svg%3E"); }
.price { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.price .num { font-size: 34px; }
.faq details { border-bottom: 1px solid var(--line); padding: 14px 0; }
.faq summary { cursor: pointer; font-weight: 600; font-size: 16px; list-style: none; display: flex; justify-content: space-between; gap: 12px; }
.faq summary::-webkit-details-marker { display: none; }
.faq p { margin-top: 10px; color: var(--body); }

@media (min-width: 820px) {
	.hero { grid-template-columns: 1fr 1.05fr; gap: 40px; }
	.types { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.offer-box { grid-template-columns: 1.1fr 1fr; padding: 32px; }
	.page { gap: 72px; }
}

/* ---------- Test screens ---------- */
.test-top { display: flex; align-items: center; justify-content: space-between; min-height: 44px; }
.test-top .num { font-size: 22px; }
.meter { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
.meter > i { display: block; height: 100%; width: 0; background: var(--accent); transition: width 0.2s linear; }
.pair { display: flex; flex-direction: column; align-items: center; gap: 2px; font-family: var(--mono); font-weight: 600; user-select: none; }
.pair .dim { font-size: 24px; color: var(--field-line); line-height: 1.3; }
.pair .big { font-size: 64px; line-height: 1.05; }
.pair .flash-ok { color: var(--good); }
.pair .flash-no { color: var(--warn); }
.keypad { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: auto; }
.keypad button { min-height: 62px; border-radius: var(--r); border: 1px solid var(--line); background: var(--ground); font-family: var(--mono); font-size: 24px; font-weight: 600; cursor: pointer; touch-action: manipulation; }
.keypad button:active { background: var(--accent-soft); border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.hint { font-size: 16px; color: var(--muted); text-align: center; }
.example { display: flex; align-items: center; justify-content: center; gap: 14px; font-family: var(--mono); font-weight: 600; font-size: 28px; }
.example .ans { color: var(--accent); }
.count-in { font-family: var(--mono); font-weight: 600; font-size: 96px; text-align: center; color: var(--accent); margin: auto 0; }

/* ---------- Result ---------- */
.type-hero { display: grid; grid-template-columns: 112px 1fr; gap: 16px; align-items: center; }
.type-hero img { border-radius: var(--r); background: var(--ground); border: 1px solid var(--line); }
.stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.stat { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 14px; display: flex; flex-direction: column; gap: 2px; }
.stat .label { font-size: 14px; color: var(--muted); }
.stat .num { font-size: 24px; line-height: 1.2; }
.stat .band { font-size: 13px; font-weight: 600; }
.band-low { color: var(--ochre); }
.band-mid { color: var(--muted); }
.band-high { color: var(--good); }
.chart { display: grid; gap: 8px; align-items: end; height: 150px; }
.chart .col { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 6px; height: 100%; }
.chart .col i { display: block; width: 100%; background: var(--accent-soft); border-radius: 2px; }
.chart .col.low i { background: var(--accent); }
.chart .col span { font-family: var(--mono); font-size: 13px; color: var(--muted); }
.chart-x { display: grid; gap: 8px; text-align: center; font-size: 13px; color: var(--muted); }
.tips { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.divider { border: 0; border-top: 1px solid var(--line); margin: 8px 0; }

/* ---------- Practice ---------- */
.today { background: var(--ink); color: #fff; border-radius: var(--r); padding: 20px; display: flex; flex-direction: column; gap: 12px; }
.today .fine { color: var(--line); }
.today .btn-primary { background: #fff; color: var(--ink); }

.plan-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.plan-list li { display: grid; grid-template-columns: 64px 1fr auto; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 16px; align-items: center; }
.plan-list li.now { font-weight: 600; }
.plan-list .day { font-family: var(--mono); color: var(--muted); font-size: 14px; }
.plan-list .done { color: var(--good); font-size: 14px; font-weight: 600; }
.areas { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.area { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 14px; display: flex; flex-direction: column; gap: 8px; text-decoration: none; color: var(--ink); }

.area b { font-size: 16px; }
.options { display: grid; gap: 8px; }
.options button { min-height: 52px; padding: 12px 16px; border-radius: var(--r); border: 1px solid var(--line); background: var(--ground); font-size: 16px; text-align: left; cursor: pointer; display: flex; gap: 12px; align-items: center; }
.options button .k { font-family: var(--mono); font-weight: 600; color: var(--muted); min-width: 18px; }
.options button[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: var(--accent-soft); }
.options.pics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.options.pics button { flex-direction: column; padding: 10px; align-items: stretch; }
.options.pics svg { width: 100%; max-width: 120px; margin: 0 auto; }
.matrix { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 10px; }
.matrix > div { aspect-ratio: 1; border: 1px solid var(--line); border-radius: 2px; display: flex; align-items: center; justify-content: center; }
.target { width: 140px; margin: 0 auto; background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 8px; }
.stem { font-family: var(--mono); font-weight: 600; font-size: 22px; text-align: center; text-wrap: balance; padding: 18px 8px; background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); word-break: break-word; }
/* Logika: a few sentences per question, read top to bottom. */
.stem.stem-text { text-wrap: pretty; font-family: inherit; font-weight: 400; font-size: 16px; line-height: 1.6; text-align: left; padding: 14px 16px; white-space: pre-line; word-break: normal; }
.review-text { white-space: pre-line; }
.qnav { display: flex; gap: 8px; }
.qnav .btn { flex: 1; }

/* ---------- Rendered pages ---------- */
.prose { display: flex; flex-direction: column; gap: 14px; max-width: 680px; }
.prose h1 { font-size: 30px; line-height: 1.2; }
.prose h2 { font-size: 22px; margin-top: 18px; }
.prose h3 { font-size: 16px; margin-top: 10px; }
.prose ul { margin: 0; padding-left: 22px; display: flex; flex-direction: column; gap: 6px; }
.prose p, .prose li { color: var(--body); }
.guide-art, .pay-art { border-radius: var(--r); border: 1px solid var(--line); background: var(--ground); }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }
.run { display: flex; flex-direction: column; gap: 20px; flex: 1; }
.row-split { justify-content: space-between; }
.legend { display: flex; gap: 14px; font-size: 13px; color: var(--muted); }
.legend span { display: flex; align-items: center; gap: 6px; }
.legend .lg-line { width: 16px; height: 3px; background: var(--accent); border-radius: 2px; }
.legend .lg-avg { width: 16px; border-top: 1px solid var(--field-line); }
.trust-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; font-size: 14px; color: var(--muted); }
.trust-list li { display: flex; gap: 8px; }
.trust-list li::before { content: ""; flex: none; width: 6px; height: 6px; margin-top: 8px; border-radius: 50%; background: var(--accent); }
.sticky { position: fixed; left: 0; right: 0; bottom: 0; z-index: 10; background: var(--ground); border-top: 1px solid var(--line); padding: 12px 20px calc(14px + env(safe-area-inset-bottom)); display: flex; align-items: center; justify-content: space-between; gap: 12px; max-width: 460px; margin: 0 auto; }
.sticky b { font-size: 16px; }
.sticky .num { font-size: 16px; }
.sticky .btn { min-height: 48px; }
.sample { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.sample-top { display: flex; justify-content: space-between; gap: 8px; font-size: 13px; color: var(--muted); }
.sample-top span:first-child { font-weight: 600; }
.sample-type { display: flex; gap: 12px; align-items: center; }

.sample-type div { display: flex; flex-direction: column; gap: 2px; }
.sample-type b { font-size: 22px; }
.sample-type span { font-size: 16px; color: var(--muted); }
.sample-nums { display: flex; gap: 16px; font-family: var(--mono); font-size: 14px; font-weight: 600; }
.strong { font-weight: 600; }
.dots { display: flex; gap: 6px; }
.dots i { flex: 1; height: 4px; border-radius: 2px; background: var(--line); }
.dots i.on { background: var(--accent); }
.feedback { border-radius: var(--r); padding: 12px 14px; text-align: center; color: var(--muted); font-size: 16px; }
.feedback.ok { background: var(--sunken); color: var(--good); font-weight: 600; }
.feedback.no { background: var(--sunken); color: var(--warn); font-weight: 600; }
.facts { display: flex; justify-content: space-around; text-align: center; }
.facts div { display: flex; flex-direction: column; }
.facts .num { font-size: 28px; }
.btn-ragu[aria-pressed="true"] { border-color: var(--ochre); box-shadow: inset 0 0 0 1px var(--ochre); background: var(--ochre-soft); color: var(--ochre); }
.qgrid { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 12px 6px; padding-bottom: 6px; }
.qcell { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; font-family: var(--mono); font-size: 13px; font-weight: 600; border-radius: var(--r); border: 1px solid var(--field-line); background: var(--ground); color: var(--muted); cursor: pointer; padding: 0; min-height: 30px; }
.qcell { position: relative; }
.qcell.done { background: var(--accent); border-color: var(--accent); color: #fff; }
.qcell.ragu { background: var(--ochre-soft); border-color: var(--ochre); box-shadow: inset 0 0 0 1px var(--ochre); color: var(--ochre); }
/* The current question: a bar under the cell, never an outline around it (that clashed with the red and ochre fills). */
.qcell.now::after { content: ""; position: absolute; left: 20%; right: 20%; bottom: -6px; height: 3px; border-radius: 2px; background: var(--ink); }
.legend .lg-done { width: 12px; height: 12px; background: var(--accent); border-radius: 3px; }
.legend .lg-ragu { width: 12px; height: 12px; background: var(--ochre-soft); border: 1px solid var(--ochre); box-shadow: inset 0 0 0 1px var(--ochre); border-radius: 3px; }
.legend .lg-empty { width: 12px; height: 12px; background: var(--ground); border: 1px solid var(--field-line); border-radius: 3px; }
.options button.is-right { border-color: var(--good); box-shadow: inset 0 0 0 1px var(--good); background: var(--sunken); }
.options button.is-wrong { border-color: var(--warn); box-shadow: inset 0 0 0 1px var(--warn); background: var(--sunken); }
.options button:disabled { cursor: default; color: var(--ink); opacity: 1; }
.feedback-box { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 14px 16px; display: flex; flex-direction: column; gap: 6px; }
.feedback-box.ok b { color: var(--good); }
.feedback-box.no b { color: var(--warn); }
.review-pics { display: flex; gap: 12px; }
.review-pics figure { margin: 0; width: 96px; display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--muted); }
.sample-note { font-size: 13px; color: var(--muted); }
.qnav .btn { flex: 1; min-width: 0; padding: 12px 8px; font-size: 16px; }
.examples { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.examples .card { padding: 12px; display: flex; flex-direction: column; gap: 4px; font-size: 14px; }

/* ---------- D2 ringkas components (9 Nov 2026) ---------- */
.ic { width: 24px; height: 24px; flex: none; }
.r-tag { font-size: 14px; font-weight: 500; letter-spacing: -0.006em; color: var(--muted); }
.r-cues { display: flex; flex-wrap: wrap; gap: 8px 16px; list-style: none; margin: 0; padding: 0; }
.r-cues li { display: flex; align-items: center; gap: 6px; font-size: 14px; color: var(--body); }
.r-cues .ic { width: 18px; height: 18px; }
.r-pill { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font); font-size: 13px; font-weight: 600; line-height: 16px; letter-spacing: 0; white-space: nowrap; }
.r-pill.high { color: var(--good); }
.r-pill.high::before { content: ""; 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='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%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='black' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat; }
.r-pill.mid { color: var(--muted); }
.r-pill.low, .r-pill.red { padding: 4px 8px; border-radius: var(--r); background: var(--ochre-soft); color: var(--ochre); }
.r-pill img { width: 28px; height: 16px; border-radius: 2px; }
.sample-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.r-nums { display: flex; gap: 20px; font-family: var(--mono); font-weight: 600; font-size: 16px; letter-spacing: 0; }
.r-nums small { display: block; font-family: var(--font); font-weight: 400; font-size: 13px; color: var(--muted); }
section > h2.h-lg.ruled { padding-top: 14px; border-top: 2px solid var(--ljk); }
.types .type img { aspect-ratio: 8 / 5; object-fit: cover; }
.type b { line-height: 1.3; letter-spacing: -0.013em; }
.r-gains { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.r-gains li { display: flex; gap: 14px; align-items: center; background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 14px 16px; }
.r-gains .ic { width: 28px; height: 28px; }
.r-gains div { display: flex; flex-direction: column; gap: 2px; }
.r-gains b { font-size: 16px; line-height: 1.3; }
.r-gains span { font-size: 14px; color: var(--muted); line-height: 1.4; }
.r-pack { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.r-pack li { display: flex; flex-direction: column; gap: 8px; background: var(--sunken); border-radius: var(--r); padding: 12px; font-size: 14px; font-weight: 600; line-height: 1.3; }
.r-pack li small { font-weight: 400; color: var(--muted); font-size: 13px; line-height: 1.35; }
.r-price { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.r-price .num { font-size: clamp(44px, 13vw, 56px); line-height: 1; font-weight: 500; letter-spacing: -0.04em; color: var(--ink); }
.r-price span:not(.num) { font-size: 14px; color: var(--muted); }
.r-hero-type { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.r-hero-type img { width: 100%; height: auto; border-radius: var(--r); }
.r-meters { display: flex; flex-direction: column; gap: 14px; }
.r-meter { display: grid; grid-template-columns: 1fr auto; gap: 6px 12px; align-items: center; }
.r-meter .k { font-size: 16px; font-weight: 600; }
.r-meter .v { display: flex; align-items: center; gap: 8px; font-family: var(--mono); font-weight: 600; font-size: 16px; letter-spacing: 0; }
.r-meter .track { grid-column: 1 / -1; height: 8px; border-radius: 4px; background: var(--line); overflow: hidden; }
.r-meter .track i { display: block; height: 100%; width: 0; border-radius: 4px; }
.r-meter .track i.high { background: var(--good); }
.r-meter .track i.mid { background: var(--muted); }
.r-meter .track i.low { background: var(--ochre); }
.r-meter .hint { grid-column: 1 / -1; font-size: 13px; line-height: 1.4; color: var(--ochre); text-align: left; }
.r-ex { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.r-ex div { background: var(--sunken); border-radius: var(--r); padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; }
.r-ex b { font-family: var(--mono); font-size: 13px; font-weight: 600; letter-spacing: 0; }
.r-demo { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 20px; display: grid; grid-template-columns: auto 1fr; gap: 20px; align-items: center; }
.r-pair { display: flex; flex-direction: column; align-items: center; font-family: var(--mono); font-weight: 600; line-height: 1.05; }
.r-pair span { font-size: 40px; }
.r-pair hr { width: 100%; border: 0; border-top: 2px dashed var(--ljk); margin: 4px 0; }
.r-sum { display: flex; flex-direction: column; gap: 8px; }
.r-sum .eq { font-family: var(--mono); font-size: 18px; font-weight: 600; color: var(--muted); letter-spacing: 0; }
.r-sum .eq s { text-decoration: none; opacity: .45; }
.r-key { display: inline-flex; align-items: center; justify-content: center; width: 52px; height: 52px; border-radius: var(--r); background: var(--accent); color: #FFF; font-family: var(--mono); font-weight: 600; font-size: 24px; }
.chart-tip { font-size: 13px; color: var(--muted); min-height: 1.4em; }
@media (min-width: 820px) {
	.r-pack { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.r-gains { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (hover: hover) {
	a:hover { color: var(--accent-dark); }
	.btn-primary:hover { background: var(--accent-dark); color: #fff; }
	.btn-ghost:hover { border-color: var(--muted); }
	.input:hover:not(:focus-within) { border-color: var(--muted); }
	.today .btn-primary:hover { background: var(--accent-soft); color: var(--ink); }
	.area:hover, .options button:not(:disabled):hover, .chip:hover { border-color: var(--muted); }
	.options button[aria-pressed="true"]:hover, .chip[aria-pressed="true"]:hover { border-color: var(--accent); }
}
/* Controls inside the dark "today" card get a light focus ring. */
.today :focus-visible { outline-color: #FFFFFF; }
/* Mouse and touch clicks do not draw the focus ring; the keyboard does (:focus-visible). */
:focus:not(:focus-visible) { outline: none; }

/* ---------- Date picker (public/js/tanggal.js): a field that opens a bottom sheet with a calendar ---------- */
.field-label { font-weight: 600; font-size: 16px; letter-spacing: -0.009em; }
button.input.picker { width: 100%; font: inherit; font-size: 16px; letter-spacing: -0.013em; color: var(--ink); text-align: left; cursor: pointer; }
.picker-v { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker-v.ph { color: var(--field-line); }
.picker .chev { width: 18px; height: 18px; fill: none; stroke: var(--muted); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; flex: none; }
/* The picker is a button: the text field's focus-within ring applies to it only for keyboard focus. */
button.input.picker:focus:not(:focus-visible) { border-color: var(--field-line); box-shadow: none; }
button.input.picker:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(11, 95, 88, 0.2); }
body.sheet-open { overflow: hidden; }
.sheet-wrap { position: fixed; inset: 0; z-index: 50; display: flex; flex-direction: column; justify-content: flex-end; }
.sheet-back { position: absolute; inset: 0; background: rgba(24, 24, 27, 0.4); }
.sheet { position: relative; width: 100%; max-width: 460px; margin: 0 auto; max-height: 92dvh; overflow-y: auto; background: var(--ground); border-radius: 16px 16px 0 0; box-shadow: 0 -12px 32px rgba(24, 24, 27, 0.12); padding: 10px 16px calc(18px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: 14px; }
.grab { width: 36px; height: 4px; border-radius: 2px; background: var(--line); margin: 0 auto; }
.sheet-top { display: flex; align-items: center; justify-content: space-between; }
.sheet-top b { font-size: 16px; }
.sheet-x { width: 40px; height: 40px; border: 0; background: none; font-size: 24px; line-height: 1; color: var(--muted); cursor: pointer; border-radius: var(--r); }
.quick { display: flex; gap: 8px; flex-wrap: wrap; }
.quick .chip { border-radius: var(--r); min-height: 40px; padding: 8px 14px; }
.cal-head { display: flex; align-items: center; justify-content: space-between; }
.cal-month { font-family: var(--display); font-weight: 600; font-size: 22px; letter-spacing: -0.004em; }
.cal-nav { display: flex; gap: 6px; }
.cal-nav button { width: 40px; height: 40px; border: 1px solid var(--line); border-radius: var(--r); background: var(--ground); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.cal-nav button:disabled { opacity: 0.35; cursor: default; }
.cal-nav svg { width: 20px; height: 20px; fill: none; stroke: var(--ink); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; text-align: center; }
.cal .dow { font-size: 13px; font-weight: 600; color: var(--muted); padding: 4px 0; }
.cal .dow.sun { color: var(--warn); }
.cal .d { position: relative; height: 44px; border: 0; border-radius: var(--r); background: none; font-family: var(--mono); font-weight: 500; font-size: 16px; letter-spacing: 0; color: var(--ink); cursor: pointer; padding: 0; }
.cal .d.sun { color: var(--warn); }
.cal .d.past, .cal .d:disabled { color: #C4C4CC; cursor: default; }
.cal .d.past.sun { color: #E5B3AD; }
.cal .d.today { font-weight: 600; }
.cal .d.today::after { content: ""; position: absolute; left: 50%; bottom: 6px; width: 5px; height: 5px; margin-left: -2.5px; border-radius: 50%; background: var(--ink); }
.cal .d.range { background: var(--sunken); }
.cal .d.sel { background: var(--accent); color: #FFFFFF; font-weight: 600; }
.cal-sum { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--body); }
.cal-sum b { font-family: var(--mono); letter-spacing: 0; }
@media (hover: hover) {
	.cal .d:not(:disabled):not(.sel):hover { background: var(--sunken); }
	.cal-nav button:not(:disabled):hover { border-color: var(--muted); }
}

/* ---------- Component pass (9 Nov 2026): nothing left in its browser-default or unfinished look ---------- */
/* Small buttons, for headers and secondary actions. */
.btn-sm { min-height: 40px; padding: 8px 14px; font-size: 16px; gap: 6px; }
.btn-sm .ic { width: 18px; height: 18px; }

/* Back link with a chevron. */
.back { display: inline-flex; align-items: center; gap: 4px; min-height: 44px; }
.back::before { content: ""; width: 18px; height: 18px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230F766E' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 6l-6 6 6 6'/%3E%3C/svg%3E") center / 18px no-repeat; }

/* Errors: an alert box with an icon, not a red sentence. */
.error { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-radius: var(--r); background: var(--sunken); color: var(--warn); font-size: 14px; line-height: 1.45; font-weight: 500; }
.error::before { content: ""; flex: none; width: 18px; height: 18px; margin-top: 1px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9' fill='%23A8261B'/%3E%3Cpath d='M10 5.5v5.5' stroke='%23fff' stroke-width='2' stroke-linecap='round'/%3E%3Ccircle cx='10' cy='14.3' r='1.2' fill='%23fff'/%3E%3C/svg%3E") center / 18px no-repeat; }
.error a { color: var(--warn); font-weight: 600; }

/* Toast: a short confirmation that fades out by itself. */
.toast { position: fixed; left: 50%; bottom: calc(96px + env(safe-area-inset-bottom)); z-index: 60; transform: translate(-50%, 8px); width: max-content; max-width: min(420px, calc(100vw - 32px)); box-sizing: border-box; display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-radius: var(--r); background: var(--ink); color: #FFFFFF; font-size: 14px; line-height: 1.4; box-shadow: 0 8px 24px rgba(24, 24, 27, 0.2); opacity: 0; pointer-events: none; transition: opacity 0.2s, transform 0.2s; }
.toast.on { opacity: 1; transform: translate(-50%, 0); }
.toast::before { content: ""; flex: none; width: 18px; height: 18px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9' fill='%2316794A'/%3E%3Cpath d='M6 10.2l2.6 2.6L14 7.4' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 18px no-repeat; }

/* Loading: a skeleton of the page instead of a "Memuat..." sentence. */
.skel { display: flex; flex-direction: column; gap: 12px; }
.skel i { display: block; border-radius: var(--r); background: linear-gradient(90deg, var(--line) 0%, #FAFAFB 50%, var(--line) 100%) 0 0 / 200% 100%; animation: skel 1.2s ease-in-out infinite; }
.skel .s-hero { height: 190px; }
.skel .s-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.skel .s-row i { height: 150px; }
.skel .s-line { height: 18px; width: 40%; }
@keyframes skel { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* Answer options: the letter is a badge that fills for selected, right and wrong. */
.options button .k { flex: none; width: 30px; height: 30px; min-width: 30px; border-radius: var(--r); border: 1px solid var(--field-line); display: inline-flex; align-items: center; justify-content: center; font-family: var(--mono); font-size: 14px; font-weight: 600; color: var(--muted); background: var(--ground); }
.options button[aria-pressed="true"] .k { background: var(--accent); border-color: var(--accent); color: #FFFFFF; }
.options button.is-right .k { background: var(--good); border-color: var(--good); color: #FFFFFF; }
.options button.is-wrong .k { background: var(--warn); border-color: var(--warn); color: #FFFFFF; }
.options.pics button .k { margin-bottom: 4px; }
/* Mode cards (Simulasi / Latihan) are a choice of one: a radio mark on the right. */
/* Koran durations: the column count reads as a badge. */

/* Feedback after an answer: an icon with the verdict. */
.feedback-box b { display: flex; align-items: center; gap: 8px; }
.feedback-box.ok b::before, .feedback-box.no b::before { content: ""; width: 18px; height: 18px; background: center / 18px no-repeat; }
.feedback-box.ok b::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9' fill='%2316794A'/%3E%3Cpath d='M6 10.2l2.6 2.6L14 7.4' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.feedback-box.no b::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9' fill='%23A8261B'/%3E%3Cpath d='M7 7l6 6M13 7l-6 6' stroke='%23fff' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E"); }

/* The plan as a timeline: a line with a dot per day; today is a red dot, past days a small tick. */
.plan-list li { position: relative; grid-template-columns: 56px 1fr auto; padding-left: 26px; border-bottom: 0; }
.plan-list li::before { content: ""; position: absolute; left: 7px; top: 0; bottom: 0; width: 2px; background: var(--line); }
.plan-list li:first-child::before { top: 50%; }
.plan-list li:last-child::before { bottom: 50%; }
.plan-list li::after { content: ""; position: absolute; left: 2px; top: 50%; width: 12px; height: 12px; margin-top: -6px; border-radius: 50%; background: var(--ground); border: 2px solid var(--field-line); box-sizing: border-box; }
.plan-list li.now::after { border: 0; background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.plan-list li.past { color: var(--muted); }
.plan-list li.past::after { border: 0; background: var(--muted) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 6.2l2 2L9 4' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 12px no-repeat; }
.plan-list li.test-day b { color: var(--accent); }
.plan-list .done { font-size: 13px; font-weight: 600; padding: 3px 8px; border-radius: var(--r); background: var(--accent-soft); color: var(--accent-dark); }

/* FAQ: a chevron that turns, and a smooth open where the browser supports it. */
.faq summary::after { content: ""; flex: none; width: 20px; height: 20px; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230F766E' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / 20px no-repeat; transition: transform 0.2s; }
.faq details[open] summary::after { content: ""; transform: rotate(180deg); }
.faq summary { padding: 4px 0; min-height: 44px; align-items: center; }
@supports (interpolate-size: allow-keywords) {
	.faq { interpolate-size: allow-keywords; }
	.faq details::details-content { height: 0; overflow: clip; transition: height 0.25s ease, content-visibility 0.25s allow-discrete; }
	.faq details[open]::details-content { height: auto; }
}

/* Keypad: a little key feel, pressed keys sink by a pixel. */
.keypad button { box-shadow: inset 0 -2px 0 var(--line); transition: transform 0.05s; }
.keypad button:active { transform: translateY(1px); box-shadow: inset 0 0 0 1px var(--accent); }
@media (prefers-reduced-motion: reduce) { .skel i { animation: none; } .toast { transition: none; } }

/* ---------- Explanatory images (9 Nov 2026): only where a picture explains faster than words ---------- */
figure.photo { margin: 0; display: flex; flex-direction: column; gap: 8px; }
figure.photo img { width: 100%; height: auto; border-radius: var(--r); border: 1px solid var(--line); background: var(--sunken); }
figure.photo figcaption { font-size: 13px; line-height: 1.45; color: var(--muted); }
figure.photo.tall img { max-width: 260px; margin: 0 auto; }
figure.photo.tall figcaption { text-align: center; }
figure.photo.desk-only { display: none; }
@media (min-width: 820px) { figure.photo.desk-only { display: flex; } }

/* ---------- Landing variant B, /tes-koran/ (A/B test, 9 Nov 2026; design: canvas "Landing: masalah dan solusi", ronde 2) ---------- */
body.lp { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
.lp-h1 { font-size: clamp(30px, 6vw, 44px); }
.lead b { color: var(--ink); }
.lp-product { margin: 0; border: 1px solid var(--line); border-radius: var(--r); padding: 12px 12px 10px; display: flex; flex-direction: column; gap: 6px; }
.lp-res { font-size: 16px; font-weight: 700; margin: 0; }
.lp-ex { font-size: 13px; color: var(--muted); margin: 0; }
.lp-sheet { display: flex; gap: 10px; align-items: center; margin: 0; font-size: 13px; color: var(--muted); }
.lp-sheet img { width: 72px; height: 48px; object-fit: cover; border-radius: var(--r); border: 1px solid var(--line); flex: none; }
.lp-fast { margin: 0; font-size: 14px; line-height: 1.5; color: var(--body); padding-left: 12px; border-left: 3px solid var(--ljk); }
.lp-fast a { font-weight: 600; }
.lp-rows { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.lp-rows li { display: grid; grid-template-columns: 72px 1fr; gap: 12px; align-items: center; }
.lp-rows img { width: 72px; height: 72px; object-fit: cover; border-radius: var(--r); }
.lp-rows b { display: block; font-size: 16px; line-height: 1.3; }
.lp-rows span { font-size: 14px; line-height: 1.4; color: var(--body); }
.lp-get { border: 1px solid var(--line); border-radius: var(--r); padding: 14px; display: flex; flex-direction: column; gap: 6px; }
.lp-get h3 { margin: 0; font-family: var(--font); font-size: 16px; font-weight: 700; letter-spacing: -0.012em; display: flex; gap: 8px; align-items: center; }
.lp-get h3::before { content: ""; width: 20px; height: 20px; flex: none; border-radius: 50%; background: var(--accent) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M6 10.2l2.6 2.6L14 7.4' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 20px no-repeat; }
.lp-get p { margin: 0; font-size: 14px; line-height: 1.45; color: var(--body); }
.lp-sticky { position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; padding: 12px 20px calc(14px + env(safe-area-inset-bottom)); background: rgba(255, 255, 255, 0.96); border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 6px; max-width: 460px; margin: 0 auto; }
.lp-sticky span { text-align: center; font-size: 13px; color: var(--muted); }
/* Motion: the example line draws itself, then the result and the drop marker appear. */
.lp-product polyline { stroke-dasharray: 900; stroke-dashoffset: 900; animation: lp-draw 1.8s 0.3s ease-out forwards; }
.lp-product circle, .lp-product line[stroke="#8A5A00"], .lp-product text { animation: lp-fade 0.4s 1.9s both; }
.lp-product rect[fill="#8A5A00"] { animation: lp-wash 0.4s 1.9s both; }
.lp-res { animation: lp-fade 0.4s 2.1s both; }
@keyframes lp-draw { to { stroke-dashoffset: 0; } }
@keyframes lp-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes lp-wash { from { opacity: 0; } to { opacity: 0.1; } }
@media (prefers-reduced-motion: reduce) {
	.lp-product polyline { animation: none; stroke-dashoffset: 0; }
	.lp-product rect[fill="#8A5A00"] { animation: none; opacity: 0.1; }
	.lp-product circle, .lp-product line[stroke="#8A5A00"], .lp-product text, .lp-res { animation: none; }
}

/* ---------- UI refine: landing ---------- */
/* Both landings (A: body.lp-a on /, B: body.lp on /tes-koran/). Section rhythm: 16 px inside a section, 44 px between
   sections, and the header sits close to the first section. */
body.lp-a main.screen, body.lp main.screen { gap: 44px; }
body.lp-a main.screen > .bar, body.lp main.screen > .bar { margin-bottom: -24px; }
/* Footer links as 44 px tap targets without changing the line rhythm. */
body.lp-a .foot a, body.lp .foot a { display: inline-block; padding: 12px 2px; margin: -12px 0; }
/* A: a wide crop of the sheet photo, so the example result starts on the first screen. */
body.lp-a figure.photo img { aspect-ratio: 2 / 1; object-fit: cover; object-position: 50% 35%; }
/* A: the four line-shape tiles line up: short one-line descriptions and an equal text block. */
body.lp-a .types .type div { min-height: 62px; }
/* Both: the "tes koran" chip sits close to the headline. */
/* B: the sheet thumbnail is large enough to read as a sheet; the "tes besok" link stays on one line. */
body.lp .lp-sheet img { width: 96px; height: 64px; }
body.lp .lp-fast a { white-space: nowrap; }
/* B: the chart card, the "tes besok" line and the sheet thumbnail sit 24 px apart. */
body.lp .lp-product, body.lp .lp-fast { margin-bottom: 8px; }
/* A: the pay note under the offer button. */
body.lp-a .pay-note { margin: 0; font-size: 14px; line-height: 1.5; color: var(--muted); text-align: center; }
/* B: the sticky button stays hidden while the hero button is on screen, then slides in. Browsers without scroll-driven
   animations keep it visible, as before. */
@supports (animation-timeline: scroll()) {
	body.lp .lp-sticky, body.v3 .lp-sticky { animation: lp-sticky-in linear both; animation-timeline: scroll(root); animation-range: 300px 380px; }
	@keyframes lp-sticky-in { from { transform: translateY(100%); visibility: hidden; } to { transform: none; visibility: visible; } }
}
/* B: the problem scenes are 3:2 landscape illustrations (A2 direction), so each row is a card with the full scene on
   top, two per row, on the peach ground the art is painted on. */
body.lp .lp-rows { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 12px; }
body.lp .lp-rows li { grid-template-columns: 1fr; align-items: start; align-content: start; gap: 8px; }
body.lp .lp-rows img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; object-position: 50% 50%; background: var(--sunken); }
body.lp .lp-rows span { display: block; line-height: 1.45; }

/* ---------- UI refine: hasil ---------- */
/* Result: the type name and the reader's own numbers sit on the first screen; the glyph is a small badge, not a banner. */
.hs-hero { display: flex; flex-direction: column; gap: 14px; }
.hs-head { display: flex; align-items: center; gap: 14px; }
.hs-head img { width: 112px; height: 112px; flex: none; border-radius: var(--r); background: #FFFFFF; object-fit: cover; }
.hs-head .h-xl { margin: 2px 0 0; }
.hs-context { margin: 0; padding: 12px 0; border-top: 1px solid var(--ljk); border-bottom: 1px solid var(--ljk); font-size: 16px; line-height: 1.5; color: var(--body); }
.hs-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hs-card-head .h-md { margin: 0; font-size: 22px; }
.hs-bridge { margin: 4px 0 0; font-size: 16px; line-height: 1.5; color: var(--muted); }
.hs-price-line { margin: 0; display: flex; flex-direction: column; gap: 6px; font-size: 14px; color: var(--muted); }
.hs-price-line b { font-family: var(--mono); font-size: clamp(44px, 13vw, 56px); line-height: 1; font-weight: 500; letter-spacing: -0.04em; color: var(--ink); }
.hs-total { display: flex; align-items: baseline; justify-content: space-between; padding: 12px 0; border-top: 1px solid var(--line); font-size: 16px; color: var(--muted); }
.hs-total .num { font-family: var(--mono); font-size: 22px; font-weight: 600; color: var(--ink); }
.hs-state { padding-top: 24px; }
/* A date picked is required: the picker shows the same error border as the email field. */
button.input.picker[data-state="error"], button.input.picker[data-state="error"]:focus:not(:focus-visible) { border-color: var(--warn); box-shadow: inset 0 0 0 1px var(--warn); }
button.input.picker[data-state="error"]:focus-visible { border-color: var(--warn); box-shadow: 0 0 0 3px rgba(168, 38, 27, 0.2); }

/* Payment: a status chip says where the order stands before any other text. */
.pay-chip { align-self: flex-start; display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: var(--r); font-size: 14px; font-weight: 600; }
.pay-chip .ic { width: 18px; height: 18px; }
.pay-chip.ok { background: var(--sunken); color: var(--good); }
.pay-chip.wait { background: var(--accent-soft); color: var(--accent-dark); }
.pay-chip.off { background: var(--sunken); color: var(--muted); }
.pay-chip i { width: 8px; height: 8px; border-radius: 50%; background: currentColor; animation: pay-pulse 1.6s ease-in-out infinite; }
@keyframes pay-pulse { 50% { opacity: 0.3; } }
@media (prefers-reduced-motion: reduce) { .pay-chip i { animation: none; } }
.pay-amount { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 4px 12px; padding: 16px; border: 1px solid var(--line); border-radius: var(--r); }
.pay-amount span { font-size: 16px; color: var(--muted); }
.pay-amount b { font-family: var(--mono); font-size: 24px; color: var(--ink); }
.pay-amount small { grid-column: 1 / -1; font-size: 13px; color: var(--muted); }
.pay-receipt { margin: 0; padding: 16px; border: 1px solid var(--line); border-radius: var(--r); display: flex; flex-direction: column; gap: 10px; font-size: 16px; }
.pay-receipt > b { font-size: 16px; }
.pay-receipt div { display: flex; justify-content: space-between; gap: 16px; }
.pay-receipt dt { color: var(--muted); flex: none; }
.pay-receipt dd { margin: 0; text-align: right; color: var(--ink); font-weight: 500; overflow-wrap: anywhere; }

/* Sign-in */
.ms-alt { margin: 0; text-align: center; font-size: 16px; color: var(--muted); }
.ms-alt a { font-weight: 600; }
.ms-tips { margin: 0; padding: 14px 14px 14px 32px; border-radius: var(--r); background: var(--sunken); display: flex; flex-direction: column; gap: 6px; font-size: 16px; line-height: 1.45; color: var(--body); }
#sent-to { overflow-wrap: anywhere; }
/* The A2 illustration sits on its warm peach ground, laptop only. */
.pay-scan img { aspect-ratio: 3 / 2; object-fit: cover; background: var(--sunken); border-color: var(--sunken); }
.hs-why { margin: 0; font-size: 16px; line-height: 1.5; color: var(--ink); }
.hs-pack { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--ljk); }
.hs-pack li { display: flex; flex-direction: column; gap: 2px; padding: 12px 0; border-bottom: 1px solid var(--ljk); }
.hs-pack b { font-size: 16px; color: var(--ink); }
.hs-pack span { font-size: 14px; line-height: 1.45; color: var(--muted); }
.hs-terms { margin: -4px 0 0; text-align: center; font-size: 13px; }
.pay-amount small b { font-family: inherit; font-size: inherit; font-weight: 600; color: var(--ink); }
.pay-where { margin: -4px 0 0; text-align: center; font-size: 14px; color: var(--muted); }
.hs-soon { margin: -4px 0 0; }
.pay .fine .num { white-space: nowrap; }

/* ---------- UI refine: tes ---------- */
/* The 5-minute test (/tes/), scoped to .tes-flow so the paid practice keeps its own look. The timed screens fill the
   phone's height and size the digits and keys by it, so the keypad never drops below the screen (360x640 phones). */
.tes-flow { padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
.tes-flow .run { min-height: calc(100dvh - 28px - env(safe-area-inset-bottom)); gap: clamp(8px, 1.8dvh, 18px); touch-action: manipulation; -webkit-user-select: none; user-select: none; }
.tes-flow .pair { flex: 1; justify-content: center; gap: 0; min-height: 0; }
.tes-flow .pair .big { font-size: clamp(44px, 8.5dvh, 66px); line-height: 1.04; }
/* Only the pair is shown: the digits before and after keep their slots (so nothing moves) but are hidden, since a
   third, unlabelled digit was read as the answer or as part of the sum. */
.tes-flow .pair .dim { font-size: clamp(16px, 3dvh, 22px); line-height: 1.4; visibility: hidden; }
.tes-flow .keypad { gap: 10px; margin-top: 0; }
.tes-flow .keypad button { min-height: clamp(50px, 8.2dvh, 66px); font-size: clamp(22px, 3.6dvh, 28px); }
/* An exact press: a 90 ms mark set by the script, never the browser's :active, which sticks on some touch phones. */
.tes-flow .keypad button:active { transform: none; background: var(--ground); border-color: var(--line); box-shadow: inset 0 -2px 0 var(--line); }
/* After a warm-up miss: the typed key gets an ochre ring, the right key a teal ring on a teal tint. */
.tes-flow .keypad button.answer { background: var(--accent-soft); border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); color: var(--accent); }
.tes-flow .keypad button.typed { border-color: var(--ochre); box-shadow: inset 0 0 0 1px var(--ochre); color: var(--ochre); }
/* A press: the key dips and flashes teal, then springs back (keyframes in "Tap feedback" below). */
.tes-flow .keypad button.hit { animation: key-press 0.18s ease-out; }
.tes-flow .hint, .tes-flow #warm-feedback { font-size: 16px; min-height: 1.5em; }
.tes-flow .hint { color: var(--body); }
/* The total time stays visible but quiet: small grey digits, not a big black countdown. */
.tes-time { font-family: var(--mono); font-weight: 500; font-size: 14px; color: var(--muted); letter-spacing: 0; font-variant-numeric: tabular-nums; }
/* The pair to add: the two big digits with the answer sheet's pink dashed line between them, as on the intro. */
.tes-flow .pair .big + .big { position: relative; }
.tes-flow .pair .big + .big::before { content: ""; position: absolute; left: 50%; top: 0; width: 1.1em; margin-left: -0.55em; border-top: 2px dashed var(--ljk); }
/* One teal bar for the whole test, so "Kolom 10 dari 20" sits at half; a new column gives it one short pulse. */
.tes-meter { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.tes-meter b { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 3px; }
.tes-meter.pindah { animation: tes-pindah 0.6s ease-out; }
@keyframes tes-pindah { 0% { transform: scaleY(1); } 40% { transform: scaleY(1.8); } 100% { transform: scaleY(1); } }
.tes-flow .feedback.almost { background: var(--ochre-soft); color: var(--ochre); font-weight: 600; }
.tes-tip { margin: 0; font-size: 16px; line-height: 1.5; color: var(--body); padding: 12px 14px; border-radius: var(--r); border: 1px solid var(--line); }
.tes-tip b { color: var(--ink); }
.tes-busy { height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; }
.tes-busy i { display: block; height: 100%; width: 40%; background: var(--accent); border-radius: 2px; animation: tes-busy 1.1s ease-in-out infinite; }
@keyframes tes-busy { 0% { transform: translateX(-40%); } 100% { transform: translateX(250%); } }
/* Count-in and saving fill the phone with their message in the middle, so neither looks half loaded. */
.tes-full { min-height: calc(100dvh - 44px - env(safe-area-inset-bottom)); }
.tes-center { justify-content: center; text-align: center; }
.tes-center .count-in { margin: 0; font-size: 120px; line-height: 1; }
.tes-rule { margin: 0; font-size: 18px; font-weight: 600; color: var(--ink); }
.tes-mid { margin: auto 0; display: flex; flex-direction: column; gap: 16px; padding-bottom: 12dvh; }
@media (prefers-reduced-motion: reduce) {
	.tes-meter.pindah { animation: none; }
	.tes-busy i { animation: none; width: 100%; }
}

/* ---------- UI refine: latihan ---------- */
/* Home: today's card in the canvas look (white, LJK rule, teal button), one segment per plan day, the test date. */
.today { background: var(--ground); color: var(--ink); border: 1px solid var(--line); border-top: 3px solid var(--ljk); }
.today .fine { color: var(--muted); }
.today .fine.strong { color: var(--ink); }
.today .btn-primary { background: var(--accent); color: #FFFFFF; }
.today :focus-visible { outline-color: var(--accent); }
@media (hover: hover) { .today .btn-primary:hover { background: var(--accent-dark); color: #FFFFFF; } }
.today-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.today-chip { font-size: 13px; font-weight: 600; padding: 3px 9px; border-radius: var(--r); background: var(--accent-soft); color: var(--accent-dark); white-space: nowrap; }
.today-days { display: flex; gap: 4px; margin-top: -2px; }
.today-days i { flex: 1; height: 6px; border-radius: 3px; background: var(--line); }
.today-days i.done { background: var(--accent); }
.today-days i.now { background: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.today-done { margin-top: -4px; font-size: 13px; font-weight: 600; color: var(--accent-dark); }
.today-eve { border-top: 1px solid var(--ljk); padding-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.today-eve ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; font-size: 16px; }
/* Area cards: the last score large, the change since last time in words, a small line of past scores. */
.plan-list .done.soon { background: var(--sunken); color: var(--muted); }
.plan-list.plan-short li.past { display: none; }
#koran-list:not(.open) li:nth-child(n + 2) { display: none; }
#koran-more { align-self: flex-start; }
/* Question practice: timer, answered count and the folded number grid on top; the buttons on the bottom edge. */
.q-top { position: sticky; top: 0; z-index: 2; background: var(--bg, #FFFFFF); display: flex; flex-direction: column; gap: 6px; padding-bottom: 8px; }
.q-gridbtn { display: flex; align-items: center; justify-content: space-between; min-height: 36px; padding: 0; border: 0; background: none; font: inherit; font-size: 14px; color: var(--muted); cursor: pointer; }
.q-gridlink { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; color: var(--accent); }
.q-gridlink::after { content: ""; width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: translateY(-2px) rotate(45deg); }
.q-gridbtn[aria-expanded="true"] .q-gridlink::after { transform: translateY(2px) rotate(-135deg); }
.q-grid { display: flex; flex-direction: column; gap: 10px; padding: 4px 0 8px; }
.q-grid .qcell { min-height: 40px; font-size: 14px; }
.q-dock { position: sticky; bottom: 0; z-index: 2; margin-top: auto; background: var(--bg, #FFFFFF); border-top: 1px solid var(--line); margin-left: -20px; margin-right: -20px; padding: 12px 20px calc(12px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; gap: 10px; }
.q-check { display: flex; flex-direction: column; gap: 10px; font-size: 16px; font-weight: 500; color: var(--ink); }
#nav-sim { display: grid; grid-template-columns: auto auto 1fr; }
#nav-sim .btn { white-space: nowrap; padding-left: 14px; padding-right: 14px; }
#nav-sim .q-prev { width: 52px; padding: 0; }
.q-prev svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
html:has(.q-dock) { scroll-padding: 120px 0 140px; }
/* Picture options fit four on one screen above the bar. */
.run .options.pics svg { max-width: 72px; }
.run .options.pics button { padding: 8px; gap: 2px; }
.run .matrix { max-width: 280px; margin: 0 auto; width: 100%; }
/* "Ragu-ragu" is a flag to check again, not "weak", so it is ink, not ochre. */
.qcell.ragu { background: var(--sunken); border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); color: var(--ink); }
.legend .lg-ragu { background: var(--sunken); border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
.btn-ragu[aria-pressed="true"] { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); background: var(--sunken); color: var(--ink); }
/* Canvas palette B: a wrong practice answer means "practise this" (ochre); red is only for real errors. */
.options button.is-wrong, .options button.is-wrong[aria-pressed="true"] { border-color: var(--ochre); box-shadow: inset 0 0 0 1px var(--ochre); background: var(--ochre-soft); }
.options button.is-wrong .k { background: var(--ochre); border-color: var(--ochre); color: #FFFFFF; }
.feedback-box.no b, .review .no { color: var(--ochre); }
.feedback-box.no b::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Ccircle cx='10' cy='10' r='9' fill='%238A5A00'/%3E%3Cpath d='M10 5.5v5.5' stroke='%23fff' stroke-width='2' stroke-linecap='round'/%3E%3Ccircle cx='10' cy='14.2' r='1.2' fill='%23fff'/%3E%3C/svg%3E"); }
/* Latihan: the result line and "Penjelasan" sit in the bottom bar, right above "Soal berikutnya". */
.q-dock .feedback-box { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; max-height: 38dvh; overflow-y: auto; border: 0; padding: 4px 2px 0; background: transparent; }
.q-dock .feedback-box .fb-text { flex-basis: 100%; font-size: 16px; line-height: 1.5; white-space: pre-line; }
.fb-why { min-height: 36px; padding: 0; border: 0; background: none; font: inherit; font-size: 14px; font-weight: 600; color: var(--accent); cursor: pointer; }
/* Score summary: the score first, then the mix of right, wrong and blank, what to look at, one next step. */
.score-card { display: flex; flex-direction: column; gap: 10px; }
.score-big { display: flex; align-items: baseline; gap: 12px; }
.score-big .num { font-size: 48px; line-height: 1; font-weight: 600; }
.score-big .num::after { content: "/100"; font-size: 16px; font-weight: 500; color: var(--muted); margin-left: 4px; }
.score-bar { display: flex; gap: 2px; height: 8px; border-radius: 4px; overflow: hidden; background: var(--line); }
.score-bar i { display: block; flex: 1 1 0; min-width: 4px; }
.score-bar .ok, .score-chips i.ok { background: var(--good); }
.score-bar .no, .score-chips i.no { background: var(--ochre); }
.score-bar .blank, .score-chips i.blank { background: var(--field-line); }
.score-chips { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 14px; color: var(--muted); }
.score-chips span { display: inline-flex; align-items: center; gap: 6px; }
.score-chips i { width: 10px; height: 10px; border-radius: 3px; }
.score-chips .time { margin-left: auto; font-family: var(--mono); }
.score-focus { margin: 0; font-size: 16px; padding: 12px 14px; border-radius: var(--r); background: var(--ochre-soft); color: var(--ink); }
.score-focus b { color: var(--ochre); }
/* Review: two-way filter; your answer and the right answer on their own lines. */
.seg { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; border-radius: var(--r); background: var(--sunken); border: 1px solid var(--line); }
.seg button { min-height: 40px; border: 1px solid transparent; border-radius: var(--r); background: transparent; font: inherit; font-size: 14px; font-weight: 500; color: var(--muted); cursor: pointer; }
.seg button[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: var(--accent-soft); color: var(--accent-dark); font-weight: 600; }
.review-why { font-size: 16px; line-height: 1.5; color: var(--body); white-space: pre-line; }
/* Tes koran practice: minutes per mode, today's planned mode, a checklist before the run, meters on the result. */
.k-plan { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--accent-dark); }
.k-plan::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.k-meters { gap: 18px; }
.r-meter .track i.speed { background: var(--accent); }
.k-nochart { margin: 0; padding: 18px 0; font-size: 16px; color: var(--muted); text-align: center; }
/* Guides and the method page: a contents list at the top, and headings that land below the top edge. */
.toc { background: var(--sunken); border: 1px solid var(--line); border-radius: var(--r); padding: 14px 16px; margin: 4px 0 8px; display: flex; flex-direction: column; gap: 8px; }
.toc b { font-size: 14px; color: var(--muted); }
.toc ol { margin: 0; padding-left: 22px; display: flex; flex-direction: column; gap: 2px; }
.toc li { font-size: 16px; padding-left: 2px; }
.toc a { display: block; padding: 6px 0; color: var(--accent); font-weight: 500; text-decoration: none; }
.prose h2[id] { scroll-margin-top: 16px; }
html:has(.toc) { scroll-behavior: smooth; }

/* ---------- Landing v3 (9 Nov 2026): value shown as our own screens; C is image-led ---------- */
body.v3 main.screen { padding-bottom: 120px; }
.v3-result { border: 1px solid var(--line); border-radius: var(--r); padding: 14px; display: flex; flex-direction: column; gap: 14px; }
.v3-tip { margin: 0; display: flex; gap: 10px; align-items: flex-start; padding: 2px 0 2px 12px; border-left: 2px solid var(--ochre); font-size: 16px; line-height: 1.5; color: var(--body); }
.v3-tip .ic { width: 22px; height: 22px; flex: none; }
.v3-prev { display: flex; flex-direction: column; gap: 10px; }
.v3-pv { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }
.v3-pv p { margin: 0; font-size: 14px; line-height: 1.45; color: var(--body); }
.v3-timer { display: flex; gap: 8px; }
.v3-timer span { font-family: var(--mono); font-weight: 600; font-size: 22px; padding: 6px 12px; border-radius: var(--r); background: var(--accent-soft); color: var(--accent-dark); }
.v3-q { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.v3-qs { font-family: var(--mono); font-weight: 600; font-size: 18px; margin-right: 4px; }
.v3-qa { font-family: var(--mono); font-weight: 600; font-size: 16px; padding: 5px 12px; border-radius: var(--r); border: 1px solid var(--line); }
.v3-qa.no { color: var(--muted); text-decoration: line-through; }
.v3-qa.yes { border-color: var(--good); box-shadow: inset 0 0 0 1px var(--good); color: var(--good); background: var(--sunken); }
.v3-plan { list-style: none; margin: 0; padding: 0 0 0 4px; display: flex; flex-direction: column; }
.v3-plan li { position: relative; display: grid; grid-template-columns: 84px 1fr; padding: 5px 0 5px 18px; font-size: 14px; }
.v3-plan li::before { content: ""; position: absolute; left: 0; top: 50%; width: 9px; height: 9px; margin-top: -5px; border-radius: 50%; border: 1px solid var(--field-line); box-shadow: inset 0 0 0 1px var(--field-line); }
.v3-plan li.now::before { background: var(--accent); border-color: var(--accent); box-shadow: none; }
.v3-plan li.day { color: var(--accent-dark); font-weight: 600; }
.v3-plan li b { font-family: var(--mono); font-weight: 500; font-size: 13px; color: var(--muted); }
/* C: the illustrations carry the page. */
.v3-c-hero { gap: 14px; }
.v3-c-art { width: calc(100% + 40px); max-width: none; margin: -4px -20px 4px; height: auto; aspect-ratio: 3 / 2; object-fit: cover; background: var(--sunken); display: block; }
.v3-scenes { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.v3-scenes li { display: flex; flex-direction: column; gap: 6px; font-size: 14px; font-weight: 600; line-height: 1.3; }
.v3-scenes img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--r); background: var(--sunken); }
.v3-after { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 22px; counter-reset: v3; }
.v3-after li { display: flex; flex-direction: column; gap: 4px; }
.v3-after li > b { font-size: 18px; line-height: 1.3; margin-top: 6px; }
.v3-after li > span { font-size: 16px; line-height: 1.45; color: var(--body); }
.v3-after img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; border-radius: var(--r); background: var(--sunken); }
.v3-buy { border-top: 1px solid var(--line); padding-top: 20px; display: flex; flex-direction: column; gap: 16px; }
.v3-nobill { margin: 0; display: flex; gap: 8px; align-items: flex-start; font-size: 14px; line-height: 1.45; color: var(--accent-dark); }
.v3-nobill .ic { width: 18px; height: 18px; flex: none; margin-top: 1px; }
body.v3 .lp-rows li > div { display: flex; flex-direction: column; gap: 2px; }
.v3-after li > b { margin-top: 2px; }
.v3-incl { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 14px; line-height: 1.4; color: var(--ink); }
.v3-incl li { display: flex; gap: 8px; } .v3-incl li::before { content: ""; flex: none; width: 6px; height: 6px; margin-top: 7px; border-radius: 50%; background: var(--accent); }
/* B: the fix line reads as an answer, not a link. */
/* B (v3): problem -> fix rows with icons, no illustrations. */

/* ---------- Tap feedback and app feel (9 Nov 2026) ---------- */
/* Every tap answers back: the key dips, the phone ticks (haptic.js), the column moves up one digit and the typed digit
   stays in pencil beside it for a moment. None of it says right or wrong during the timed test. */
html:has(.tes-flow), html:has(.tes-flow) body { overscroll-behavior: none; }
.haptic { position: fixed; left: -200px; top: 0; width: 1px; height: 1px; overflow: hidden; opacity: 0; pointer-events: none; }
.btn { transition: transform 0.1s ease-out, background-color 0.15s; }
@keyframes key-press { 0% { transform: scale(0.92); background: var(--accent-soft); border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); } 100% { transform: none; } }

/* The column moves up: the bottom digit rises to the top slot and a new one rises under it. */
.tes-flow .pair .dim + .big { position: relative; }
.pair.step .big { animation: pair-step 0.14s ease-out; }
@keyframes pair-step { from { transform: translateY(0.45em); opacity: 0.35; } to { transform: none; opacity: 1; } }
/* The digit just typed, small and in teal pencil, where it is written on a paper sheet: beside the pair it answers. */
.pair .ink { position: absolute; left: 100%; top: -0.32em; margin-left: 0.35em; font-size: 0.42em; line-height: 1; color: var(--accent); animation: ink 0.7s ease-out forwards; }
@keyframes ink { 0% { opacity: 1; transform: scale(1.2); } 55% { opacity: 1; transform: none; } 100% { opacity: 0; } }
/* "Pindah": the next column slides in from the right, like moving the pencil to the next column on paper. */
.pair.pindah .big { animation: pair-pindah 0.32s cubic-bezier(0.2, 0.8, 0.2, 1); }
@keyframes pair-pindah { from { transform: translateX(45%); opacity: 0; color: var(--accent); } to { transform: none; opacity: 1; } }
[data-col].flash { animation: col-flash 1s ease-out; }
@keyframes col-flash { 0%, 50% { color: var(--accent); } }
.tes-flow .hint.on { color: var(--accent); font-weight: 600; animation: soft-pop 0.22s ease-out; }

/* Answers in this column: counts up with each tap and starts at 0 on each new column. */
.tes-tally { display: inline-block; font-family: var(--mono); font-weight: 600; font-size: 14px; color: var(--ink); font-variant-numeric: tabular-nums; }
.tes-tally.pop { animation: tally-pop 0.18s ease-out; }
@keyframes tally-pop { from { transform: scale(1.2); color: var(--accent); } to { transform: none; } }

/* Count-in: each number pops in. */
.count-in.pop { animation: count-pop 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.3); }
@keyframes count-pop { from { transform: scale(0.5); opacity: 0; } 60% { opacity: 1; } to { transform: none; } }
.feedback.pop, .feedback-box.pop { animation: soft-pop 0.22s ease-out; }
@keyframes soft-pop { from { transform: scale(0.96); opacity: 0.4; } to { transform: none; opacity: 1; } }

/* Screens in a flow (intro, warm-up, count-in, test, result) come in with a short rise instead of a hard cut. */
.flow > section:not([hidden]) { animation: screen-in 0.24s ease-out; }
@keyframes screen-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Practice questions: an option dips under the finger; the chosen letter and a checked answer pop. */
.options button { transition: transform 0.1s ease-out, background-color 0.15s, border-color 0.15s; }
.options button:not(:disabled):active { transform: scale(0.98); }
.options button.picked .k, .options button.is-right .k { animation: k-pop 0.26s cubic-bezier(0.2, 0.9, 0.3, 1.4); }
@keyframes k-pop { from { transform: scale(0.6); } to { transform: none; } }

/* Result page: the sample questions and the package part that fits this person's weakest score. */
.hs-ask { margin: 0; font-size: 16px; font-weight: 600; color: var(--ink); }
#samples .matrix { max-width: 280px; margin: 0 auto; width: 100%; }
#samples .feedback-box .fb-text { font-size: 16px; line-height: 1.5; white-space: pre-line; }
.hs-pack li.is-focus::before { content: "Paling pas untukmu"; align-self: flex-start; margin-bottom: 4px; padding: 2px 8px; border-radius: var(--r); font-size: 13px; font-weight: 600; color: var(--accent); background: var(--accent-soft); }
/* ---------- Test flow (10 Nov 2026) ---------- */
/* End of the warm-up: "Siap!" in the pair's place, the start button at the bottom where the keypad was. */
.warm-ok { font-family: var(--display); font-weight: 700; font-size: clamp(40px, 7dvh, 56px); color: var(--accent); }
.pair.pop .warm-ok { display: inline-block; animation: count-pop 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.3); }
.warm-ready { margin-top: auto; }
/* Pause and leave: the question in the middle, the resume count-in under it. */
#paused .tes-mid { width: 100%; }
#paused .count-in { margin: 0; font-size: 96px; line-height: 1; }
/* "Selesai!": a teal check that draws itself. */

/* Practice questions: the next question slides in from the right, the previous one from the left (buttons or swipe);
   a swipe with nowhere to go gives a small bump. */
.run.q-next #question, .run.q-next #options { animation: q-in-next 0.22s ease-out; }
.run.q-prev #question, .run.q-prev #options { animation: q-in-prev 0.22s ease-out; }
@keyframes q-in-next { from { transform: translateX(28px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes q-in-prev { from { transform: translateX(-28px); opacity: 0; } to { transform: none; opacity: 1; } }
#question.q-bump { animation: q-bump 0.28s ease-out; }
@keyframes q-bump { 30% { transform: translateX(-8px); } 60% { transform: translateX(5px); } }

/* ---------- Storybook images (10 Nov 2026, design/art/app-images.sh) ----------
   .art-wide runs edge to edge in the phone column; .art-spot is a centered vignette on the paper ground. Images sit at
   decisions and feelings (landing, start, warm-up, done, result, sign-in, payment, empty and error states), never inside
   the timed test. */
.art-wide { display: block; width: calc(100% + 40px); max-width: none; height: auto; aspect-ratio: 3 / 2; object-fit: cover; margin: 0 -20px; background: var(--sunken); }
.art-spot { display: block; width: min(240px, 64%); height: auto; aspect-ratio: 1; margin: 0 auto; }
.art-spot.art-sm { width: min(168px, 46%); }
.pv-art { display: block; width: calc(100% + 28px); max-width: none; height: auto; aspect-ratio: 3 / 2; object-fit: cover; margin: -12px -14px 4px; border-radius: var(--r) var(--r) 0 0; background: var(--sunken); }
body.lp-a main.screen > .art-wide, body.lp main.screen > .art-wide { margin-bottom: -20px; }
.pay > .art-spot { margin-bottom: -8px; }

/* Tes koran variants (Phase 2). */
/* Kraepelin versi kertas: a stretch of the printed column, added from the bottom up, answers in pencil between digits. */
.pair.sheet { gap: 0; padding: 6px 0; background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); width: 132px; margin: 0 auto; }
.sheet .sh-d { display: block; height: clamp(20px, 3.3dvh, 28px); font-size: clamp(19px, 2.9dvh, 24px); line-height: clamp(20px, 3.3dvh, 28px); color: var(--muted); width: 36px; text-align: center; border-radius: 3px; }
.sheet .sh-d.now { color: var(--ink, #18181B); background: var(--accent-soft); font-weight: 700; }
.sheet .sh-g { display: block; height: clamp(14px, 2.1dvh, 18px); width: 22px; font-size: clamp(12px, 1.7dvh, 14px); line-height: clamp(14px, 2.1dvh, 18px); text-align: center; color: var(--accent); transform: translateX(30px); font-weight: 500; }
.sheet .sh-g.now { border: 2px dashed var(--accent); border-radius: 3px; }
.pair.sheet.step { animation: sheet-step 0.14s ease-out; }
@keyframes sheet-step { from { transform: translateY(-6px); } to { transform: none; } }
/* Kecermatan: the key with its letters, then the row with one character missing. */
.pair.kc { gap: 14px; }
.kc-key { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; width: 100%; max-width: 340px; }
.kc-key span { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 0; border: 1px solid var(--line); border-radius: var(--r); background: var(--ground); }
.kc-key b { font-size: 24px; line-height: 1.1; }
.kc-key small { font-size: 13px; color: var(--muted); font-family: var(--mono); }
.kc-row { display: flex; gap: 14px; font-size: 40px; line-height: 1.1; }
.pair.kc.step .kc-row { animation: pair-step 0.14s ease-out; }
.keypad.keypad-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.keypad.keypad-2 button { font-family: inherit; font-size: 22px; min-height: 96px; }
.keypad.keypad-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
/* Numerik data questions: a small table or bar chart, then the question. */
.q-data { margin: 0; padding: 12px; background: var(--ground); border: 1px solid var(--line); border-radius: var(--r); }
.q-data figcaption { font-size: 14px; font-weight: 600; margin-bottom: 8px; }
.q-data table { width: 100%; border-collapse: collapse; font-size: 16px; font-variant-numeric: tabular-nums; }
.q-data th, .q-data td { padding: 6px 4px; text-align: right; border-bottom: 1px solid var(--line); }
.q-data th[scope="row"], .q-data thead th:first-child { text-align: left; }
.q-data thead th { font-weight: 600; color: var(--muted); }
.q-data svg { width: 100%; height: auto; display: block; color: var(--body); }
.q-ask { font-size: 16px; font-weight: 600; margin: 12px 0 0; }
/* Personality practice: the two-statement and four-word choices. */
#options .kp-tag { display: block; margin-top: 2px; font-size: 13px; font-weight: 600; color: var(--accent); }
/* The consistency percent is not a score out of 100. */
.score-big .num.kp-pct::after { content: none; }
/* Hafalan: the word list to memorise, one group per line. */
.memo-group { display: flex; flex-direction: column; gap: 2px; padding: 6px 0; border-bottom: 1px solid var(--line); }
.memo-group:last-child { border-bottom: 0; }
.memo-group b { font-size: 13px; letter-spacing: 0.06em; color: var(--accent); }
.memo-group span { font-size: 18px; line-height: 1.4; }
/* Tryout: the steps as a short list with their status. */
.try-steps li { flex-direction: row; justify-content: space-between; align-items: center; }

/* ---------- Sample result card (10 Nov 2026 board): the drop column as one big figure, hairline metrics ---------- */
.v3-result { gap: 16px; padding: 20px; }
.sample-big { display: flex; align-items: flex-end; gap: 12px; }
.sample-big .num { font-size: 56px; line-height: 0.86; font-weight: 500; letter-spacing: -0.04em; }
.sample-big span:not(.num) { font-size: 14px; line-height: 20px; color: var(--muted); }
.metrics { margin: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--line); padding-top: 16px; }
.metrics > div { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.metrics > div + div { padding-left: 12px; border-left: 1px solid var(--line); }
.metrics dt { font-size: 13px; line-height: 16px; font-weight: 600; color: var(--muted); }
.metrics dd { margin: 0; }
.metrics dd.num { font-size: 22px; line-height: 28px; font-weight: 500; letter-spacing: -0.03em; }
.metrics .r-pill.low { align-self: flex-start; }
/* Result offer: an open section under a pink rule, like the other sections. */
.hs-offer { padding-top: 8px; }
/* A full-width button with an arrow reads label first, arrow at the end. */
.btn-block:has(> .arrow) { justify-content: space-between; text-align: left; }
/* Inside a question flow the way back is quiet: a hairline, so it never competes with the answer options. */
.run .btn-ghost, .q-dock .btn-ghost { border-color: var(--line); }

/* ---------- Plain test screens (10 Nov 2026) ----------
   A choice of test or mode is one list split by hairlines: name and detail on the left, length on the right. It is not
   the A/B/C answer-option look, so picking a test never looks like answering a question. Tips are plain text under the
   list, not a card. */
.pick { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.pick > button { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 16px; row-gap: 2px; align-items: baseline; width: 100%; margin: 0; padding: 14px 12px; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; background: transparent; font: inherit; color: var(--ink); text-align: left; cursor: pointer; }
.pick > button[hidden] { display: none; }
.pick > button > * { grid-column: 1; }
.pick > button b { font-size: 16px; font-weight: 600; }
.pick > button .fine { font-size: 14px; line-height: 1.45; }
.pick > button .len { grid-column: 2; grid-row: 1; font-family: var(--mono); font-size: 14px; font-weight: 500; color: var(--muted); white-space: nowrap; }
.pick > button .k-plan { justify-self: start; }
.pick > button[aria-pressed="true"] { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.pick > button[aria-pressed="true"] b, .pick > button[aria-pressed="true"] .len { color: var(--accent-dark); }
@media (hover: hover) { .pick > button:not([aria-pressed="true"]):hover { background: var(--sunken); } }
.pick-label { margin: 8px 0 0; font-family: var(--font); font-size: 14px; font-weight: 600; color: var(--muted); letter-spacing: 0; }
.tips { margin: 0; padding: 0 0 0 18px; display: flex; flex-direction: column; gap: 4px; font-size: 14px; line-height: 1.5; color: var(--body); }
.tips:empty { display: none; }
.facts { margin: 0; font-size: 14px; line-height: 1.5; color: var(--muted); }
.try-steps { gap: 0; border-top: 1px solid var(--line); }
.try-steps li { border: 0; border-bottom: 1px solid var(--line); border-radius: 0; padding: 12px 0; background: transparent; }

/* Tips inside the practice (10 Nov 2026): the card before a run, the cards after it, and the first-tap pointer. */
.tips-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.tips-title { display: flex; align-items: center; gap: 8px; font-size: 16px; }
.tip-ic { width: 20px; height: 20px; flex: none; color: var(--accent); }
.tips-toggle { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0; background: none; border: 0; font: inherit; font-size: 15px; font-weight: 600; color: var(--accent); cursor: pointer; }
.tips-after { display: flex; flex-direction: column; gap: 12px; }
.tip-head { display: flex; align-items: center; gap: 10px; font-size: 16px; }
.tip-link { align-self: flex-start; min-height: 44px; display: inline-flex; align-items: center; font-size: 15px; font-weight: 700; color: var(--accent); text-decoration: none; }
.ptr { position: absolute; z-index: 30; width: 44px; height: 44px; border-radius: 22px; background: var(--accent); opacity: .55; box-shadow: 0 0 0 4px rgba(255,255,255,.9), 0 6px 16px rgba(0,0,0,.25); pointer-events: none; animation: ptr-move 3.2s ease-in-out infinite; }
.ptr-ring { position: absolute; z-index: 29; width: 56px; height: 56px; border-radius: 28px; border: 3px solid var(--accent); box-sizing: border-box; pointer-events: none; animation: ptr-ring 3.2s ease-out infinite; }
.keypad button.ptr-key { animation: ptr-key 3.2s ease-in-out infinite; }
@keyframes ptr-move { 0% { transform: translate(90px, 140px); opacity: 0; } 12% { opacity: .55; } 40% { transform: none; } 48% { transform: scale(.8); } 56% { transform: none; } 82% { opacity: .55; } 100% { transform: none; opacity: 0; } }
@keyframes ptr-ring { 0%, 46% { transform: scale(.5); opacity: 0; } 50% { transform: scale(.7); opacity: .55; } 78%, 100% { transform: scale(1.9); opacity: 0; } }
@keyframes ptr-key { 0%, 45% { background: var(--ground); border-color: var(--line); } 50%, 70% { background: var(--accent-soft); border-color: var(--accent); } 85%, 100% { background: var(--ground); border-color: var(--line); } }
@media (prefers-reduced-motion: reduce) {
	.ptr, .ptr-ring, .keypad button.ptr-key { animation: none; }
	.ptr-ring { opacity: 0; }
}

/* Lighter Inter (10 Nov 2026): text is body grey, and only titles, numbers and controls stay in ink, so a screen has one
   dark mass (the main button) instead of three. :where() keeps this at zero specificity, so any class color still wins. */
:where(button, input, select, textarea, label, dt, .num, .mono, .stem, .pair, .keypad, .pick b) { color: var(--ink); }
.stack > h1 + p, .stack > h2 + p { margin-top: 4px; }

/* Chart tooltip (10 Nov 2026): a small floating card over the work-line chart, like a Recharts tooltip. garis.js places
   it with element.style (allowed by the content policy; only style attributes in markup are blocked). */
.chart-host { position: relative; }
.chart-card { position: absolute; z-index: 2; pointer-events: none; display: flex; flex-direction: column; gap: 0; padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--r); background: var(--ground); box-shadow: 0 4px 16px rgba(17, 17, 19, 0.08); font-size: 13px; line-height: 18px; white-space: nowrap; }
.chart-card span { color: var(--muted); }
.chart-card b { font-family: var(--mono); font-weight: 500; color: var(--ink); }
.chart-card[hidden] { display: none; }

/* Practice home cards (10 Nov 2026): a small storybook illustration (design/art/app-icons.sh), the name and one status
   line. The descriptions moved into each practice page; the whole card is the tap target. */
.area { padding: 16px; gap: 10px; }
.area-ill { display: block; width: 48px; height: 48px; }
.area > b, .area-text > b { font-size: 16px; line-height: 22px; font-weight: 600; color: var(--ink); }
.area-status { font-family: var(--mono); font-size: 13px; line-height: 18px; font-weight: 500; color: var(--muted); }
.area-status.up { color: var(--good); }
.area-status.weak { color: var(--ochre); }
.area-wide { flex-direction: row; align-items: center; gap: 14px; }
.area-text { display: flex; flex-direction: column; gap: 2px; }
.areas-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.area-weak { font-size: 13px; font-weight: 600; color: var(--ochre); }

/* Result page without boxes (10 Nov 2026): the three facts as one hairline row, the plan as a numbered list, the
   payment safety notes as one short paragraph, the steps after paying as a plain numbered list, the doubt poll as an
   open section. */
.hs-facts { list-style: none; margin: 0; padding: 16px 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.hs-facts li { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.hs-facts li + li { padding-left: 12px; border-left: 1px solid var(--line); }
.hs-facts b { font-family: var(--mono); font-size: 22px; line-height: 28px; font-weight: 500; letter-spacing: -0.03em; color: var(--ink); }
.hs-facts span { font-size: 13px; line-height: 1.35; color: var(--muted); }
.r-tips { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); counter-reset: tip; }
.r-tips li { counter-increment: tip; display: grid; grid-template-columns: 24px 1fr; gap: 8px; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 16px; line-height: 1.5; color: var(--ink); }
.r-tips li::before { content: counter(tip); font-family: var(--mono); font-size: 14px; color: var(--muted); }
.hs-safe { margin: 0; font-size: 14px; line-height: 1.5; color: var(--muted); }
.hs-next { padding-top: 12px; border-top: 1px solid var(--line); font-size: 14px; color: var(--body); }
.hs-next b { display: block; margin-bottom: 8px; font-size: 14px; font-weight: 600; color: var(--muted); }
.hs-next ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; line-height: 1.45; counter-reset: nx; }
.hs-next li { counter-increment: nx; display: grid; grid-template-columns: 20px 1fr; gap: 6px; }
.hs-next li::before { content: counter(nx); font-family: var(--mono); color: var(--muted); }
.hs-doubt { padding-top: 20px; border-top: 1px solid var(--line); }

/* Landing proof sections without icons or check marks (10 Nov 2026): the problems as hairline rows with the fix in
   teal text, and the trust points as five labelled facts. */
.v3-pairs { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.v3-pairs li { display: flex; flex-direction: column; gap: 4px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.v3-pairs b { font-size: 16px; font-weight: 600; color: var(--ink); }
.v3-pairs span { font-size: 14px; line-height: 1.45; color: var(--muted); }
.v3-pairs .v3-fix { color: var(--accent-dark); }
.lp-facts { margin: 0; border-top: 1px solid var(--line); }
.lp-facts div { display: grid; grid-template-columns: 88px 1fr; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 14px; line-height: 1.45; }
.lp-facts dt { color: var(--muted); }
.lp-facts dd { margin: 0; color: var(--ink); }

/* Lists without cards (10 Nov 2026): payment steps, practice review and tips are hairline rows with plain numbers; a
   weak-run tip keeps one colored rule on its left instead of a filled card. "Salah" is ochre (a weak point), not red. */
.pay-steps { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); counter-reset: s; }
.pay-steps li { counter-increment: s; display: grid; grid-template-columns: 28px 1fr; gap: 2px 8px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.pay-steps li::before { content: counter(s); grid-row: span 2; font-family: var(--mono); font-size: 16px; color: var(--accent); }
.pay-steps b { font-size: 16px; font-weight: 600; color: var(--ink); }
.pay-steps span { font-size: 14px; color: var(--muted); line-height: 1.45; }
.review { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.review li { display: flex; flex-direction: column; gap: 6px; padding: 16px 0; border-bottom: 1px solid var(--line); font-size: 16px; color: var(--ink); }
.review .ok { font-size: 13px; font-weight: 600; color: var(--good); }
.review .no { font-size: 13px; font-weight: 600; color: var(--ochre); }
.review-pair { font-size: 14px; color: var(--muted); }
.review-pair b { font-weight: 600; color: var(--ink); }
.tips-before { padding-top: 12px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 10px; }
.tips-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.tips-list li { display: grid; grid-template-columns: 20px 1fr; gap: 6px; font-size: 14px; line-height: 1.5; color: var(--body); }
.tips-list b { color: var(--ink); }
.tips-n { font-family: var(--mono); font-size: 14px; color: var(--muted); }
.tip-card { padding: 2px 0 2px 14px; border-left: 2px solid var(--accent); display: flex; flex-direction: column; gap: 6px; }
.tip-card.tip-clock, .tip-card.tip-bolt { border-left-color: var(--ochre); }
.tip-card.tip-clock .tip-ic, .tip-card.tip-bolt .tip-ic { color: var(--ochre); }
.tip-card p { margin: 0; font-size: 15px; line-height: 1.5; color: var(--body); }
.tip-card ul { margin: 0; padding-left: 18px; font-size: 15px; line-height: 1.5; color: var(--body); display: flex; flex-direction: column; gap: 4px; }
.tips-before.folded { padding: 0; border: 0; }
