/* FormsPal PDF Chat UI. Implements docs/DESIGN.md + docs/CRAFT.md.
   Brand tokens + header/footer chrome match the live FormsPal fleet
   (ocr.formspal.com / ai.formspal.com / extension.formspal.com). Theme is
   fleet-standard: html[data-theme] set pre-paint, toggled and persisted to
   localStorage 'fpTheme'. Two typographic voices: Source Serif 4 for the
   answer reading body, system sans for all UI chrome. */

/* The reading face carries text in the DOCUMENT's language (LANGUAGE_RULE in
   anthropic.js), so it must actually cover the languages served. The old
   subsets were 20KB of Basic Latin + Latin-1 and almost nothing else: 3 glyphs
   of Latin Extended-A, ZERO Vietnamese, Cyrillic or Greek. With no
   unicode-range they were claimed for every script and fell back PER GLYPH, so
   a Polish, Turkish, Vietnamese, Russian or Greek answer was drawn in two faces
   on one line, with different ascent and descent, colliding against a
   Latin-tuned line-height. Rebuilt from upstream Source Serif 4.005 (OFL, see
   assets/SourceSerif4-OFL.txt) with Latin Extended A/B, Vietnamese, Cyrillic
   and Greek: 231 -> 778 glyphs, 20KB -> 48KB. One face now draws the whole run.
   Fraunces is display only (h1/h2 and UI labels, never document text), so it
   stays a Latin subset and keeps its narrow range. */
@font-face {
  font-family: "Fraunces";
  font-style: normal; font-weight: 300 900; font-display: swap;
  src: url("assets/fraunces-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Serif 4";
  font-style: normal; font-weight: 400; font-display: swap;
  src: url("assets/sourceserif-400.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0100-024F, U+0259, U+02BB-02BC, U+0370-03FF, U+0400-04FF, U+1E00-1EFF, U+2000-206F, U+20A0-20BF, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Serif 4";
  font-style: normal; font-weight: 600; font-display: swap;
  src: url("assets/sourceserif-600.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0100-024F, U+0259, U+02BB-02BC, U+0370-03FF, U+0400-04FF, U+1E00-1EFF, U+2000-206F, U+20A0-20BF, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --bg: #f7f9fb;
  --card: #ffffff;
  --raised: #ffffff;
  --white: #ffffff;
  --ink: #1c2530;
  --ink-soft: #51606f;
  --faint: #64707e;
  --line: #8d97a3;
  --hairline: rgba(28, 37, 48, 0.10);
  --primary: #0e8a5f;
  --primary-dark: #0b6e4c;
  --btn: #0b6e4c;
  --primary-light: #e6f4ee;
  --warm-bg: #fff7e8;
  --warm-ink: #9a6700;
  --danger: #b91c1c;
  --danger-strong: #991b1b;
  --danger-bg: #fdf1f1;
  --danger-line: #f0c7c7;
  --hl: rgba(255, 210, 48, 0.55);
  --hl-blend: multiply;
  --dc-btn: #c2410c;
  --dc-btn-hover: #9a3412;
  --radius: 12px;
  --gutter: 16px;
  --shadow: 0 1px 2px rgba(16, 38, 30, 0.05), 0 4px 10px rgba(16, 38, 30, 0.05), 0 12px 28px rgba(16, 38, 30, 0.06);
  --page-shadow: 0 0 0 1px rgba(16,38,30,.07), 0 1px 1px rgba(16,38,30,.04), 0 4px 8px rgba(16,38,30,.06), 0 12px 24px rgba(16,38,30,.08);
  --serif: "Source Serif 4", Charter, "Iowan Old Style", Georgia, serif;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --section-y: clamp(56px, 8vw, 96px);
  --wrap: 1120px;
  --shadow-pop: 0 8px 28px rgba(16, 38, 30, 0.18);
  --shadow-overlay: 0 24px 64px rgba(16, 38, 30, 0.28);
  --scrim: rgba(16, 38, 30, 0.28);
  --btn-hover: #0a5c40;
  --focus: 3px solid var(--primary);
  --focus-offset: 2px;
  color-scheme: light;
}

@media (max-width: 560px) { :root { --gutter: 14px; } }
@media (max-width: 430px) { :root { --gutter: 10px; } }

html[data-theme="dark"] {
  --bg: #15181b;
  --card: #21262d;
  --raised: #262c34;
  --white: #1e2329;
  --ink: #f2f5f7;
  --ink-soft: #aab5bf;
  --faint: #8e99a4;
  --line: #59626c;
  --hairline: #2a3036;
  --primary: #16a571;
  --primary-dark: #34c188;
  --btn: #0c7a54;
  --primary-light: #143323;
  --warm-bg: #2c2310;
  --warm-ink: #e9c46a;
  --danger: #f87171;
  --danger-strong: #7f1d1d;
  --danger-bg: #34201f;
  --danger-line: #5c302e;
  --hl: rgba(255, 214, 92, 0.30);
  --hl-blend: screen;
  --dc-btn: #ea580c;
  --dc-btn-hover: #f97316;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  --page-shadow: 0 0 0 1px rgba(255,255,255,.12), 0 8px 24px rgba(0,0,0,.5);
  --shadow-pop: 0 8px 30px rgba(0, 0, 0, 0.55);
  --shadow-overlay: 0 24px 64px rgba(0, 0, 0, 0.6);
  --scrim: rgba(0, 0, 0, 0.6);
  --btn-hover: #0a6547;
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; }
[hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: absolute; left: -9999px; top: 0; z-index: 200; }
.skip-link:focus { left: 8px; top: 8px; width: auto; height: auto; min-height: 44px; display: inline-flex; align-items: center; padding: 10px 16px; background: var(--card); color: var(--ink); font-family: var(--sans); font-size: 14px; font-weight: 600; border-radius: 8px; box-shadow: var(--shadow-pop); outline: var(--focus); outline-offset: var(--focus-offset); }
html { height: 100%; }
body { min-height: 100%; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  -webkit-tap-highlight-color: transparent;
}

h1, h2 {
  font-family: "Fraunces", Georgia, serif;
  font-weight: 640; letter-spacing: -0.02em; line-height: 1.15;
  font-optical-sizing: auto; text-wrap: balance;
}

::selection { background: rgba(14, 138, 95, 0.24); }
html[data-theme="dark"] ::selection { background: rgba(52, 193, 136, 0.36); }

a { color: var(--primary-dark); }
button, textarea { font: inherit; color: inherit; }
button:focus-visible, textarea:focus-visible, input:focus-visible, a:focus-visible,
#dropzone:focus-visible, .chip:focus-visible, summary:focus-visible {
  outline: var(--focus); outline-offset: var(--focus-offset);
}

* { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--faint) 45%, transparent) transparent; }
#viewer, #messages { scrollbar-gutter: stable; }

/* ---------- fleet header ---------- */

.site-head.scrolled { box-shadow: 0 6px 22px -12px rgba(16, 38, 30, 0.35); }
html[data-theme="dark"] .site-head.scrolled { box-shadow: 0 6px 22px -12px rgba(0, 0, 0, 0.6); }
.site-brand { transition: opacity 120ms var(--ease); }
.site-brand:hover { opacity: 0.9; }
.site-brand:hover .app { color: var(--primary-dark); }
.site-theme-toggle {
  width: 38px; height: 38px; border-radius: 50%; flex: none; padding: 0; cursor: pointer;
  background: var(--white); border: 1.5px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color 120ms var(--ease);
}
.site-theme-toggle:hover { border-color: var(--primary); background: var(--primary-light); color: var(--primary-dark); }
.site-theme-toggle svg { width: 17px; height: 17px; }
.site-theme-toggle .sun { display: none; stroke: #e8a32b; }
.site-theme-toggle .moon { display: block; stroke: var(--primary); }
html[data-theme="dark"] .site-theme-toggle .sun { display: block; }
html[data-theme="dark"] .site-theme-toggle .moon { display: none; }
.site-theme-toggle.small { width: 34px; height: 34px; background: transparent; border-color: var(--line); }
.site-cta {
  position: relative; overflow: hidden; text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--dc-btn); color: #fff; font-weight: 700; font-size: 14.5px;
  padding: 9px 16px; border-radius: 9px; white-space: nowrap;
  box-shadow: 0 1px 2px rgba(154, 52, 18, 0.25);
  transition: background-color 180ms var(--ease), box-shadow 180ms var(--ease), transform 120ms var(--ease);
}
.site-cta:hover { background: var(--dc-btn-hover); box-shadow: 0 4px 12px rgba(154, 52, 18, 0.35); }
.site-cta:active { transform: scale(0.97); transition-duration: 80ms; }
@media (prefers-reduced-motion: no-preference) {
  .site-cta:hover { transform: translateY(-1px); }
  .site-cta:active { transform: translateY(0) scale(0.97); }
}
.site-cta.big { font-size: 17px; padding: 14px 30px; border-radius: 11px; }

/* ---------- landing / marketing ---------- */

#landing { position: relative; isolation: isolate; }
/* Ambient page glow (brand green + a warm accent), matching the fleet's rich
   hero treatment. Fades in on load. */
#landing::before { content: ""; position: absolute; inset: 0 0 auto; height: 860px; z-index: -1; pointer-events: none; background: radial-gradient(56% 80% at 12% -10%, color-mix(in srgb, var(--primary) 15%, transparent), transparent 64%), radial-gradient(46% 66% at 96% -4%, color-mix(in srgb, #ea580c 11%, transparent), transparent 60%); animation: fp-glow-in 1.6s var(--ease) both; }
html[data-theme="dark"] #landing::before { background: radial-gradient(56% 80% at 12% -10%, color-mix(in srgb, var(--primary) 24%, transparent), transparent 64%), radial-gradient(46% 66% at 96% -4%, color-mix(in srgb, #ea580c 14%, transparent), transparent 60%); }
@keyframes fp-glow-in { from { opacity: 0; } to { opacity: 1; } }
/* Scroll progress bar (interactive). */
.scroll-progress { position: fixed; top: 0; left: 0; right: 0; height: 2.5px; z-index: 60; transform: scaleX(0); transform-origin: 0 50%; pointer-events: none; background: linear-gradient(90deg, var(--primary-dark), var(--primary)); }
/* Reveal-on-scroll. Only hides once JS confirms it can reveal (progressive
   enhancement): without js-anim, content is visible by default. */
.reveal { transition: opacity 640ms var(--ease), transform 640ms var(--ease); }
.js-anim .reveal { opacity: 0; transform: translateY(18px); }
.js-anim .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js-anim .reveal { opacity: 1; transform: none; } }
.hero-wrap { max-width: var(--wrap); margin: 0 auto; padding: clamp(18px, 3vw, 38px) var(--gutter) clamp(40px, 5vw, 64px); }
.hero-panel {
  position: relative; overflow: hidden; border-radius: 26px; isolation: isolate;
  background:
    radial-gradient(90% 130% at 0% 0%, rgba(52, 193, 136, 0.26), transparent 56%),
    radial-gradient(64% 90% at 100% 0%, rgba(234, 88, 12, 0.14), transparent 58%),
    radial-gradient(120% 150% at 50% 118%, rgba(22, 165, 113, 0.16), transparent 62%),
    linear-gradient(152deg, #0d4130 0%, #0a2f22 52%, #072118 100%);
  box-shadow: 0 28px 70px -30px rgba(7, 33, 24, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.09);
  padding: clamp(28px, 4.6vw, 56px);
  display: grid; grid-template-columns: 1.04fr 0.96fr; gap: clamp(26px, 4vw, 52px); align-items: center;
}
.hero-panel::before { content: ""; position: absolute; left: 76%; top: 44%; width: 56%; aspect-ratio: 1; transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none; z-index: -1; background: conic-gradient(from 0deg, #34c188, #14b8a6, #7be3b6, #eab308, #34c188); filter: blur(54px) saturate(1.15); opacity: 0.4; }
@media (prefers-reduced-motion: no-preference) { .hero-panel::before { animation: fp-aurora 26s linear infinite; } }
@keyframes fp-aurora { to { transform: translate(-50%, -50%) rotate(360deg); } }
html[data-theme="light"] .hero-panel {
  background:
    radial-gradient(90% 130% at 0% 0%, rgba(22, 165, 113, 0.14), transparent 56%),
    radial-gradient(64% 90% at 100% 0%, rgba(234, 88, 12, 0.06), transparent 58%),
    radial-gradient(120% 150% at 50% 118%, rgba(14, 138, 95, 0.10), transparent 62%),
    linear-gradient(152deg, #eef9f3 0%, #e3f4ec 52%, #edf6f1 100%);
  box-shadow: 0 26px 64px -34px rgba(14, 90, 62, 0.26), inset 0 1px 0 rgba(255, 255, 255, 0.7); border: 1px solid rgba(14, 138, 95, 0.12);
}
html[data-theme="light"] .hero-panel::before { opacity: 0.22; filter: blur(60px) saturate(1.05); }
.hero-copy { position: relative; z-index: 1; color: #eef7f2; max-width: none; text-align: left; }
html[data-theme="light"] .hero-copy { color: var(--ink); }
.eyebrow { display: inline-flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 1.4px; color: #8fe3c0; margin: 0 0 12px; }
.eyebrow::before { content: ""; width: 26px; height: 2px; border-radius: 2px; background: linear-gradient(90deg, #5fd2a4, transparent); flex: none; }
html[data-theme="light"] .eyebrow { color: var(--primary-dark); }
html[data-theme="light"] .eyebrow::before { background: linear-gradient(90deg, var(--primary), transparent); }
.hero-copy h1 { font-size: clamp(34px, 4.4vw, 50px); line-height: 1.08; letter-spacing: -0.022em; font-weight: 600; margin: 0 0 15px; color: #fff; }
html[data-theme="light"] .hero-copy h1 { color: var(--ink); }
.grad { background: linear-gradient(92deg, #7be3b6, #b7f4d9, #7be3b6); background-size: 220% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; white-space: nowrap; }
@media (prefers-reduced-motion: no-preference) { .grad { animation: fp-sheen 9s ease-in-out infinite; } }
@keyframes fp-sheen { 0%, 100% { background-position: 0 0; } 50% { background-position: 100% 0; } }
html[data-theme="light"] .grad { background-image: linear-gradient(92deg, #0e8a5f, #16a571, #0e8a5f); }
.hero-copy .sub { font-size: 18px; line-height: 1.6; color: rgba(236, 247, 242, 0.85); margin: 0 0 24px; max-width: 30em; }
.hero-copy .sub b { color: #fff; font-weight: 650; }
html[data-theme="light"] .hero-copy .sub { color: var(--ink-soft); }
html[data-theme="light"] .hero-copy .sub b { color: var(--ink); }
.hero-trust { display: grid; grid-template-columns: max-content max-content; gap: 10px 26px; justify-content: start; margin: 0; padding: 0; list-style: none; font-size: 12.5px; letter-spacing: 0.04em; text-transform: uppercase; color: rgba(236, 247, 242, 0.80); font-weight: 600; }
.hero-trust li { display: inline-flex; align-items: center; gap: 7px; }
.hero-trust li::before { content: ""; width: 4px; height: 4px; border-radius: 50%; background: #5fd2a4; }
html[data-theme="light"] .hero-trust { color: var(--faint); }
.tool-card { position: relative; z-index: 1; background: #14191d; border: 1px solid rgba(255, 255, 255, 0.13); border-radius: 18px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35), 0 24px 64px rgba(0, 0, 0, 0.45), 0 24px 72px rgba(52, 193, 136, 0.18); padding: 20px; }
html[data-theme="light"] .tool-card { background: #ffffff; border-color: rgba(16, 44, 32, 0.12); box-shadow: 0 1px 2px rgba(16, 60, 42, 0.05), 0 16px 40px -14px rgba(14, 90, 62, 0.22); }
#dropzone { position: relative; min-height: 210px; justify-content: center; border: 1.6px dashed rgba(255, 255, 255, 0.45); border-radius: 13px; padding: clamp(26px, 4vw, 40px) 20px; text-align: center; cursor: pointer; background: rgba(255, 255, 255, 0.02); display: flex; flex-direction: column; align-items: center; gap: 8px; transition: border-color 160ms var(--ease), background 160ms var(--ease), transform 160ms var(--ease); }
html[data-theme="light"] #dropzone { border-color: rgba(16, 44, 32, 0.48); background: rgba(16, 44, 32, 0.015); }
/* .over is set by the dragover handler, so it must not sit behind hover: hover
   or drag feedback disappears on touch devices with an attached pointer. */
@media (hover: hover) { #dropzone:hover { border-color: #34c188; background: rgba(52, 193, 136, 0.08); transform: translateY(-1px); } }
#dropzone.over { border-color: #34c188; background: rgba(52, 193, 136, 0.08); }
html[data-theme="light"] #dropzone:hover, html[data-theme="light"] #dropzone.over { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 8%, transparent); }
#dropzone:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
html[data-theme="light"] #dropzone:focus-visible { outline-color: var(--primary); }
.dz-idle { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.dz-ico { width: 50px; height: 50px; border-radius: 14px; display: grid; place-items: center; background: rgba(52, 193, 136, 0.14); color: #7be3b6; box-shadow: inset 0 0 0 1px rgba(52, 193, 136, 0.28); margin-bottom: 2px; animation: fp-dzbob 3.2s ease-in-out infinite; }
html[data-theme="light"] .dz-ico { background: var(--primary-light); color: var(--primary-dark); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.dz-ico svg { width: 25px; height: 25px; }
@keyframes fp-dzbob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
.dz-idle strong { font-size: 18px; font-weight: 700; letter-spacing: -0.01em; color: #eef3f4; }
html[data-theme="light"] .dz-idle strong { color: var(--ink); }
.dz-sub { font-size: 13.5px; color: #a9b6bd; }
html[data-theme="light"] .dz-sub { color: var(--ink-soft); }
.dz-btn { position: relative; overflow: hidden; margin-top: 10px; display: inline-flex; align-items: center; gap: 7px; background: var(--btn); color: #fff; font-weight: 700; font-size: 15px; padding: 11px 22px; border-radius: 11px; box-shadow: 0 2px 12px -2px color-mix(in srgb, var(--primary) 60%, transparent); transition: background-color 150ms var(--ease), transform 120ms var(--ease); }
.dz-btn-arrow { width: 17px; height: 17px; transition: transform 160ms var(--ease); }
.dz-btn::after { content: ""; position: absolute; top: 0; left: -75%; width: 45%; height: 100%; background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.35), transparent); transform: skewX(-18deg); transition: left 620ms var(--ease); }
#dropzone:hover .dz-btn { background: var(--btn-hover); }
#dropzone:hover .dz-btn::after { left: 130%; }
#dropzone:hover .dz-btn-arrow { transform: translateX(3px); }
.tool-formats { margin: 14px 0 2px; text-align: center; font-size: 12px; letter-spacing: 0.03em; color: #7d8a92; }
html[data-theme="light"] .tool-formats { color: var(--faint); }
.tool-note { margin: 6px 0 0; text-align: center; font-size: 12px; color: #9aa7ad; }
html[data-theme="light"] .tool-note { color: var(--ink-soft); }
#dropzone.uploading { cursor: default; pointer-events: none; }
#dropzone.uploading .dz-idle { display: none; }
.dz-progress { display: none; width: min(340px, 92%); }
#dropzone.uploading .dz-progress { display: block; }
#dropzone.uploading .dz-ico { display: none; }
.dz-label { font-size: 15px; font-weight: 600; margin-bottom: 12px; color: #eef3f4; }
html[data-theme="light"] .dz-label { color: var(--ink); }
.dz-label::after { content: "\2026"; }
.dz-bar { height: 6px; border-radius: 999px; background: rgba(255, 255, 255, 0.12); overflow: hidden; }
html[data-theme="light"] .dz-bar { background: var(--primary-light); }
.dz-bar span { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--primary); transition: width 200ms var(--ease); }
#dropzone.busy { opacity: 0.55; pointer-events: none; }
#landing-error { margin-top: 12px; }
/* minmax(0, 1fr), not 1fr: the track must be allowed to shrink below its
   content's min-content width, or any wide child (the two-column trust list)
   blows the whole hero out past the phone viewport and overflow:hidden clips
   the headline and CTA. */
@media (max-width: 900px) { .hero-panel { grid-template-columns: minmax(0, 1fr); padding: clamp(24px, 6vw, 40px); } .hero-panel::before { left: 50%; top: 26%; width: 92%; } }
@media (max-width: 560px) { .hero-trust { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .hero-panel::before, .grad, .dz-ico, #landing::before { animation: none; } }

.band { max-width: var(--wrap); margin: 0 auto; padding: var(--section-y) var(--gutter); }
.band-alt { max-width: none; background: var(--card); border-top: 1px solid var(--hairline); border-bottom: 1px solid var(--hairline); }
.band-alt > * { max-width: calc(var(--wrap) - var(--gutter) * 2); margin-left: auto; margin-right: auto; }
.band-title { font-size: clamp(1.75rem, 3.6vw, 2.25rem); text-align: center; margin: 0 0 clamp(28px, 4vw, 44px); }
.band-title:has(+ .band-lead) { margin-bottom: 14px; }
.band-lead { text-align: center; color: var(--ink-soft); font-size: 17px; max-width: 52ch; margin: 0 auto clamp(28px, 4vw, 40px); text-wrap: pretty; }

/* Steps: single column, numeral hanging beside each heading (not a 3-up card row). */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; max-width: none; }
.step { position: relative; background: var(--card); border: 1px solid var(--hairline); border-radius: 16px; padding: 26px 24px; }
html[data-theme="dark"] .step { background: var(--raised); }
.step-n { display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: 12px; background: var(--primary-light); color: var(--primary-dark); font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 21px; line-height: 1; font-variant-numeric: lining-nums; margin-bottom: 16px; }
.step h3 { font-size: 18px; letter-spacing: -0.01em; margin: 0 0 8px; }
.step p { color: var(--ink-soft); font-size: 15px; line-height: 1.6; margin: 0; }

/* Features: one wide lead card + a three-up row, icon inline with the heading (no filled tile). */
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }

/* use-case chips */
.usecases { list-style: none; display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; padding: 0; margin: 0 auto; max-width: 800px; }
.usecases li { font-family: var(--sans); font-size: 15px; font-weight: 600; color: var(--ink-soft); background: var(--card); border: 1px solid var(--hairline); border-radius: 999px; padding: 10px 20px; transition: border-color 160ms var(--ease), transform 160ms var(--ease); }
html[data-theme="dark"] .usecases li { background: var(--raised); }
@media (hover: hover) { .usecases li:hover { border-color: color-mix(in srgb, var(--primary) 40%, var(--hairline)); transform: translateY(-2px); } }

/* security / trust grid */
.trust-grid { list-style: none; display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px 34px; padding: 0; margin: 0 auto; max-width: 840px; }
.trust-grid li { display: grid; grid-template-columns: auto 1fr; column-gap: 14px; row-gap: 5px; align-items: start; }
.trust-grid svg { grid-row: 1 / span 2; width: 24px; height: 24px; color: var(--primary); margin-top: 3px; }
.trust-grid h3 { grid-column: 2; grid-row: 1; align-self: center; font-size: 16.5px; letter-spacing: -0.01em; margin: 0; }
.trust-grid p { grid-column: 2; grid-row: 2; color: var(--ink-soft); font-size: 14.5px; line-height: 1.55; margin: 0; }
@media (max-width: 640px) { .trust-grid { grid-template-columns: 1fr; gap: 20px; } }
.feat { display: grid; grid-template-columns: auto 1fr; column-gap: 13px; row-gap: 9px; align-items: baseline; background: var(--bg); border: 1px solid var(--hairline); border-radius: 16px; padding: 24px; transition: border-color 160ms var(--ease), box-shadow 160ms var(--ease), transform 160ms var(--ease); }
.feat:first-child { grid-column: 1 / -1; }
@media (hover: hover) { .feat:hover { border-color: color-mix(in srgb, var(--primary) 40%, var(--hairline)); box-shadow: var(--shadow); transform: translateY(-2px); } }
html[data-theme="dark"] .feat { background: var(--raised); }

/* honest comparison table */
.compare-wrap { max-width: 880px; margin: 0 auto; overflow-x: auto; border: 1px solid var(--hairline); border-radius: 18px; box-shadow: var(--shadow); background: var(--card); }
.compare { width: 100%; min-width: 560px; border-collapse: collapse; font-size: 15px; }
.compare th, .compare td { text-align: left; padding: 15px 18px; border-bottom: 1px solid var(--hairline); vertical-align: top; }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }
.compare thead th { font-size: 13.5px; font-weight: 700; color: var(--ink); border-bottom: 1px solid var(--line); }
.compare tbody th { width: 42%; font-weight: 600; color: var(--ink); }
.compare-us { background: var(--primary-light); }
.compare thead th.compare-us { color: var(--primary-dark); }
.c-yes, .c-no { display: flex; gap: 8px; align-items: flex-start; line-height: 1.4; }
.c-yes { color: var(--ink); font-weight: 600; }
.c-yes::before { content: "\2713"; color: var(--primary); font-weight: 800; }
.c-no { color: var(--faint); }
.c-no::before { content: "\00d7"; color: var(--faint); font-weight: 800; }

/* Below 640px a 560px-min table can only scroll sideways, which cut every value
   mid-word and hid the third column entirely. Stack each row into a card and
   label the two values with the column headings. */
@media (max-width: 640px) {
  .compare-wrap { border: 0; border-radius: 0; box-shadow: none; background: none; overflow-x: visible; }
  .compare { min-width: 0; display: block; font-size: 15px; }
  .compare thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .compare tbody, .compare tr, .compare th, .compare td { display: block; width: auto; }
  .compare tr {
    background: var(--card); border: 1px solid var(--hairline); border-radius: 14px;
    box-shadow: var(--shadow); padding: 4px 0; margin: 0 0 12px;
  }
  .compare tr:last-child { margin-bottom: 0; }
  .compare tbody th { width: auto; padding: 14px 16px 10px; font-size: 15.5px; border-bottom: 1px solid var(--hairline); }
  .compare td { padding: 11px 16px; border-bottom: 0; }
  .compare td::before {
    display: block; margin-bottom: 4px;
    font-family: var(--sans); font-size: 11.5px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.08em; color: var(--faint);
  }
  .compare td.compare-us { background: none; }
  .compare td.compare-us::before { content: "FormsPal PDF Chat"; color: var(--primary-dark); }
  .compare td:not(.compare-us)::before { content: "Typical tool"; }
  .compare tbody tr:last-child td { border-bottom: 0; }
}
.feat-ico { grid-column: 1; grid-row: 1; align-self: center; color: var(--primary); display: grid; place-items: center; margin: 0; }
.feat-ico svg { width: 22px; height: 22px; }
.feat h3 { grid-column: 2; grid-row: 1; align-self: center; font-size: 18px; letter-spacing: -0.01em; margin: 0; }
.feat p { grid-column: 1 / -1; grid-row: 2; color: var(--ink-soft); font-size: 15px; line-height: 1.6; margin: 0; max-width: 66ch; }

.faq { max-width: 760px; margin: 0 auto; }
.faq details { border-bottom: 1px solid var(--hairline); }
.faq summary { cursor: pointer; list-style: none; padding: 18px 2px; font-size: 16.5px; font-weight: 600; display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--primary); font-size: 22px; font-weight: 400; transition: transform 180ms var(--ease); }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details p { color: var(--ink-soft); font-size: 15px; line-height: 1.65; margin: 0 2px 18px; max-width: 62ch; }

/* pointer spotlight (fleet effect): a soft glow that follows the cursor across
   the bento cards, the numbered steps, and the FAQ rows. Positioned via the
   --mx/--my custom props set on pointermove in app.js (motion-gated). */
.feat { position: relative; }
.faq details { position: relative; }
.feat > *, .step > *, .faq details > * { position: relative; z-index: 1; }
.feat::before, .step::before, .faq details::before {
  content: ""; position: absolute; inset: 0; z-index: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(320px 240px at var(--mx, 50%) var(--my, -20%), rgba(14, 138, 95, 0.16), transparent 66%);
  opacity: 0; transition: opacity 240ms var(--ease);
}
html[data-theme="dark"] .feat::before, html[data-theme="dark"] .step::before, html[data-theme="dark"] .faq details::before {
  background: radial-gradient(320px 240px at var(--mx, 50%) var(--my, -20%), rgba(52, 211, 130, 0.22), transparent 66%);
}
.feat:hover::before, .step:hover::before, .faq details:hover::before { opacity: 1; }

.cta-band { max-width: var(--wrap); margin: 0 auto; padding: var(--section-y) var(--gutter); }
.cta-band-inner { position: relative; overflow: hidden; isolation: isolate; text-align: center; border-radius: 26px; padding: clamp(48px, 6vw, 72px) clamp(28px, 5vw, 60px); background: radial-gradient(90% 140% at 0% 0%, rgba(52, 193, 136, 0.24), transparent 56%), radial-gradient(70% 100% at 100% 0%, rgba(234, 88, 12, 0.14), transparent 58%), linear-gradient(152deg, #0d4130 0%, #0a2f22 55%, #072118 100%); box-shadow: 0 28px 70px -30px rgba(7, 33, 24, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.09); }
.cta-band-inner::before { content: ""; position: absolute; left: 50%; top: -18%; width: 68%; aspect-ratio: 1; transform: translateX(-50%); border-radius: 50%; z-index: -1; pointer-events: none; filter: blur(60px); opacity: 0.34; background: conic-gradient(from 0deg, #34c188, #14b8a6, #7be3b6, #34c188); animation: fp-aurora 30s linear infinite; }
.cta-band h2 { color: #fff; font-size: clamp(1.9rem, 4vw, 2.5rem); margin: 0 auto 12px; max-width: 20ch; }
.cta-band p { color: rgba(236, 247, 242, 0.82); font-size: 17px; margin: 0 0 28px; }
.cta-fine { color: rgba(236, 247, 242, 0.6) !important; font-size: 13.5px; margin: 18px 0 0 !important; }
@media (prefers-reduced-motion: reduce) { .cta-band-inner::before { animation: none; } }
/* Gate 26: disabled state for the interactive controls that lacked one. */
.tool-btn:disabled, .ghost-btn:disabled, .action:disabled, #ask-btn:disabled, .suggestion:disabled { opacity: 0.55; cursor: not-allowed; }

/* Two-column tier: 1 -> 3 columns used to jump straight across at 821px, which
   left iPad-portrait widths with ~250px cards and three-line headings. */
@media (max-width: 1040px) and (min-width: 601px) {
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .steps { grid-template-columns: 1fr; gap: 28px; }
  .cards { grid-template-columns: 1fr; }
}

/* ---------- fleet footer ---------- */


/* ---------- app shell (full-screen workspace) ---------- */

#app { display: flex; flex-direction: column; height: 100vh; height: 100dvh; } /* dvh: composer stays above the mobile URL bar */

/* min-height, not height: a fixed 52px clipped its own contents at 200% text zoom.
   position/z-index keeps the topbar and its export menu above #panes, which
   otherwise painted the find bar over the open menu on stacked layouts. */
/* Safe areas: inside a native WebView the page can be laid out edge to edge,
   which puts this bar under the status bar / notch and the composer under the
   home indicator, so their text collides with the OS chrome. env() resolves to
   0 in an ordinary browser, so these are inert there and only pay out where the
   host actually hands us insets. */
#topbar { position: relative; z-index: 20; display: flex; align-items: center; gap: 10px; min-height: 52px; padding: env(safe-area-inset-top, 0px) calc(16px + env(safe-area-inset-right, 0px)) 0 calc(16px + env(safe-area-inset-left, 0px)); background: var(--card); border-bottom: 1px solid var(--hairline); flex: none; }
.brand { font-family: "Fraunces", Georgia, serif; font-weight: 640; font-size: 16px; color: var(--primary-dark); white-space: nowrap; }
.dot { width: 4px; height: 4px; border-radius: 50%; background: var(--line); flex: none; }
#doc-name { font-size: 13.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
#page-count { font-size: 13.5px; color: var(--faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
.spacer { flex: 1; }
#mode-badge { background: var(--warm-bg); color: var(--warm-ink); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; padding: 3px 9px; border-radius: 10px; flex: none; }
#tier-badge { background: var(--primary-light); color: var(--primary-dark); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; padding: 3px 9px; border-radius: 10px; flex: none; }
#pane-tabs { display: none; gap: 2px; padding: 2px; background: var(--bg); border: 1px solid var(--hairline); border-radius: 9px; }
#viewer-tools { display: flex; gap: 2px; padding: 2px; background: var(--bg); border: 1px solid var(--hairline); border-radius: 9px; }
.tool-btn { background: transparent; border: 0; border-radius: 7px; padding: 4px 10px; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); cursor: pointer; transition: background 120ms var(--ease), color 120ms var(--ease), box-shadow 120ms var(--ease); }
.tool-btn:hover { color: var(--primary-dark); background: var(--primary-light); }
.tool-btn.active { background: var(--card); color: var(--primary-dark); box-shadow: 0 0 0 1.5px var(--primary), 0 1px 2px rgba(16,38,30,.10); }
.ghost-btn { background: var(--card); color: var(--ink); border: 1.5px solid var(--line); border-radius: 10px; padding: 6px 13px; font-size: 13.5px; font-weight: 600; cursor: pointer; white-space: nowrap; transition: border-color 120ms var(--ease), background 120ms var(--ease), color 120ms var(--ease); }
.ghost-btn:hover { border-color: var(--primary); color: var(--primary-dark); background: var(--primary-light); }

#panes { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(400px, 1fr); }
@media (min-width: 1500px) { #panes { grid-template-columns: minmax(0, 1fr) minmax(400px, 720px); } }

#viewer-pane { overflow: hidden; background: var(--bg); position: relative; }
/* align-items: safe center, not center. Plain centering on an overflowing flex
   item pushes the overflow past the scroll origin: at 2x zoom on a phone the
   page's left edge sat at -430px with scrollLeft already 0, so the start of
   every line was unreachable. "safe" falls back to flex-start once the item
   stops fitting, which keeps the whole page pannable.
   touch-action keeps one-finger pan native while handing the two-finger
   gesture to the pinch handler in viewer-zoom.js. */
#viewer { height: 100%; overflow: auto; overscroll-behavior: contain; touch-action: pan-x pan-y; padding: 24px; display: flex; flex-direction: column; align-items: safe center; gap: 20px; }
/* Reclaim gutter for the page itself where width is scarcest. */
@media (max-width: 560px) { #viewer { padding: 12px; gap: 12px; } }
.page { position: relative; background: #fff; border-radius: 3px; box-shadow: var(--page-shadow); flex: none; }
.page.flash::after { content: ""; position: absolute; inset: 0; border-radius: 3px; box-shadow: 0 0 0 3px var(--hl); animation: flashfade 1.6s var(--ease) forwards; }
@keyframes flashfade { 0% { opacity: 1; } 100% { opacity: 0; } }
/* pdf.js selectable text layer: transparent glyphs positioned over the canvas */
.textLayer { position: absolute; inset: 0; overflow: clip; line-height: 1; -webkit-text-size-adjust: none; text-size-adjust: none; forced-color-adjust: none; transform-origin: 0 0; z-index: 1; caret-color: CanvasText; }
.textLayer span, .textLayer br { color: transparent; position: absolute; white-space: pre; cursor: text; transform-origin: 0 0; }
.textLayer ::selection { background: rgba(14, 138, 95, 0.30); }
html[data-theme="dark"] .textLayer ::selection { background: rgba(52, 193, 136, 0.40); }
.textLayer .endOfContent { position: absolute; inset: 100% 0 0; z-index: -1; cursor: default; user-select: none; }

.hl { position: absolute; background: var(--hl); mix-blend-mode: var(--hl-blend); pointer-events: none; border-radius: 3px; z-index: 2; }
.hl.pulse { animation: hlpulse 800ms var(--ease); }
@keyframes hlpulse { 0% { transform: scale(1.04); filter: brightness(1.3); } 100% { transform: scale(1); filter: brightness(1); } }

#chat-pane { display: flex; flex-direction: column; min-width: 0; background: var(--card); border-left: 1px solid var(--hairline); position: relative; }
/* BLOCK, not a flex column, and that is load-bearing: iOS WebKit (Safari and
   every WKWebView, so the FormsPal mobile app too) freezes a flex item's height
   at its first layout when its content then grows through streamed DOM
   mutations. The streaming answer kept painting BELOW its stale box, and the
   next question bubble was flex-positioned over the spilled text - two answers
   double-layered on top of each other on every second message on iPhone.
   Verified 2026-08-18 in a minimal harness on the iOS 18.5 simulator: gap,
   :has(), the caret ::after, scrollbar-gutter and the auto-scroll were each
   stripped alone with no effect; only block flow lays the streamed message out
   correctly. Blink was never affected. Do not "modernise" this back to flex. */
#messages { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 22px 20px; display: block; background: var(--bg); }
#messages > .msg + .msg { margin-top: 22px; }
/* 22px base rhythm (the old flex gap) + the extra 12px a user turn always had. */
#messages > .msg.user:not(:first-child) { margin-top: 34px; }
/* The empty state centres with margin:auto, which needs a flex parent. Only
   #empty-state is ever in #messages then (app.js removes it before the first
   .msg lands), so the streaming bug above cannot bite in this state. */
#messages:has(#empty-state) { display: flex; flex-direction: column; }
#empty-state { margin: auto; width: min(100%, 380px); display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
.empty-badge { width: 46px; height: 46px; margin: 0 auto 2px; display: grid; place-items: center; border-radius: 13px; background: var(--primary-light); color: var(--primary-dark); }
.empty-badge svg { width: 24px; height: 24px; }
.empty-title { font-family: "Fraunces", Georgia, serif; font-weight: 600; font-size: 21px; letter-spacing: -0.01em; color: var(--ink); text-align: center; margin: 4px 0 0; }
.empty-sub { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); text-align: center; margin: 2px 0 10px; text-wrap: pretty; }
.suggest-label { font-family: var(--sans); font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--faint); text-align: center; margin: 2px 0 0; }
#suggestions { display: flex; flex-direction: column; gap: 8px; }
.suggestion { position: relative; background: var(--card); color: var(--ink); border: 1.5px solid var(--line); border-radius: 10px; padding: 11px 34px 11px 14px; font-size: 14px; font-weight: 600; text-align: left; cursor: pointer; transition: border-color 120ms var(--ease), background 120ms var(--ease), color 120ms var(--ease); animation: rise 260ms var(--ease) backwards; animation-delay: calc(var(--i) * 45ms); }
.suggestion::after { content: "\2192"; position: absolute; right: 13px; top: 50%; transform: translateY(-50%) translateX(-4px); opacity: 0; color: var(--primary); font-weight: 700; transition: opacity 120ms var(--ease), transform 120ms var(--ease); }
.suggestion:hover { border-color: var(--primary); color: var(--primary-dark); background: var(--primary-light); }
.suggestion:hover::after { opacity: 1; transform: translateY(-50%) translateX(0); }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Key Facts panel */
/* Persistent, dismissible document-level notice (e.g. a scan too large to
   index, where citations still carry page numbers but cannot highlight).
   Not a toast: the user needs it to stay put while they read the answers. */
.doc-notice {
  margin: 12px 20px 0; padding: 10px 12px;
  background: var(--warm-bg); border: 1px solid color-mix(in srgb, var(--warm-ink) 35%, transparent);
  border-radius: 10px; color: var(--warm-ink);
  font-family: var(--sans); font-size: 13px; line-height: 1.5;
}
.nd-short { display: none; }
@media (max-width: 430px) {
  .nd-full { display: none; }
  .nd-short { display: inline; }
}
.doc-notice[hidden] { display: none; }
.error-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 9px; }
.doc-notice.is-error {
  background: var(--danger-bg);
  border-color: var(--danger-line);
  color: var(--danger);
  font-weight: 600;
}
#facts-panel { margin: 12px 20px; border: 1.5px solid var(--line); border-radius: 12px; background: var(--card); overflow: hidden; animation: rise 260ms var(--ease) backwards; }
#facts-panel[hidden] { display: none; }
#facts-panel > summary { display: flex; align-items: center; gap: 9px; padding: 11px 14px; font-family: var(--sans); font-size: 13.5px; font-weight: 700; color: var(--ink); cursor: pointer; list-style: none; user-select: none; transition: background 120ms var(--ease); }
#facts-panel > summary::-webkit-details-marker { display: none; }
#facts-panel > summary:hover { background: var(--primary-light); }
.facts-icon { width: 17px; height: 17px; color: var(--primary); flex: none; }
.facts-count { font-size: 11px; font-weight: 700; color: var(--primary-dark); background: var(--primary-light); border-radius: 999px; padding: 1px 8px; min-width: 18px; text-align: center; }
.facts-count:empty { display: none; }
.facts-caret { width: 16px; height: 16px; margin-left: auto; color: var(--faint); transition: transform 180ms var(--ease); }
#facts-panel[open] .facts-caret { transform: rotate(180deg); }
#facts-list { padding: 2px 14px 12px; max-height: min(244px, 28dvh); overflow-y: auto; overscroll-behavior: contain; }
.fact { display: grid; grid-template-columns: minmax(84px, 32%) 1fr auto; align-items: baseline; gap: 10px; padding: 8px 0; border-top: 1px solid var(--hairline); animation: rise 240ms var(--ease) backwards; animation-delay: calc(var(--i) * 22ms); }
.fact:first-child { border-top: none; }
.fact-label { font-family: var(--sans); font-size: 12px; font-weight: 600; color: var(--faint); }
.fact-value { font-family: var(--serif); font-size: 14.5px; line-height: 1.4; color: var(--ink); overflow-wrap: anywhere; }
.fact-cite { align-self: center; flex: none; }
.facts-empty { font-size: 13px; color: var(--ink-soft); padding: 8px 0 2px; margin: 0; }
.fact-skeleton { height: 26px; border-radius: 7px; margin: 8px 0; background: linear-gradient(90deg, var(--line) 25%, var(--hairline) 50%, var(--line) 75%); background-size: 200% 100%; animation: factshimmer 1.4s linear infinite; animation-delay: calc(var(--i) * 90ms); }
@keyframes factshimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { #facts-panel, .fact, .fact-skeleton { animation: none; } .facts-caret { transition: none; } }

.msg { max-width: 100%; }
/* width:fit-content + margin-inline-start:auto is the block-flow spelling of the
   old align-self:flex-end (and stays on the correct side in RTL). */
.msg.user { width: fit-content; margin-inline-start: auto; max-width: min(82%, 560px); background: var(--primary-light); border: 1px solid rgba(14, 138, 95, 0.18); border-radius: 14px 14px 5px 14px; padding: 10px 15px; white-space: pre-wrap; overflow-wrap: break-word; }
.msg.assistant { min-height: 1.5em; }
.msg.assistant:has(.answer)::before { content: "Answer"; display: block; font-family: var(--sans); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--primary-dark); margin-bottom: 7px; }
#messages > .msg:last-child .actions { opacity: 1; }

/* overflow-wrap: model output carries URLs, filenames and long compounds that
   otherwise forced a horizontal scrollbar inside the message list. */
.answer { font-family: var(--serif); font-size: 16.5px; line-height: 1.75; color: var(--ink); max-width: 68ch; overflow-wrap: anywhere; }
.answer > :first-child { margin-top: 0; }
.answer > :last-child { margin-bottom: 0; }
.answer p { margin: 0 0 0.85em; }
.answer h2, .answer h3, .answer h4, .answer h5 { font-family: var(--sans); font-weight: 600; line-height: 1.3; margin: 1.1em 0 0.5em; }
.answer h2 { font-size: 1.15em; }
.answer h3 { font-size: 1.05em; }
.answer h4, .answer h5 { font-size: 1em; }
.answer ul, .answer ol { margin: 0 0 0.85em; padding-left: 1.4em; }
.answer li { margin: 0.2em 0; }
.answer blockquote { margin: 0 0 0.85em; padding-left: 0.9em; border-left: 3px solid var(--line); color: var(--ink-soft); }
.answer code { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 0.88em; background: var(--bg); padding: 1px 5px; border-radius: 5px; }
.answer pre { background: var(--bg); border: 1px solid var(--hairline); border-radius: 10px; padding: 12px 14px; overflow-x: auto; margin: 0 0 0.85em; }
.answer pre code { background: none; padding: 0; }
.answer a { color: var(--primary-dark); }
/* A link the model authored to a non-FormsPal destination is rendered as text,
   not an anchor (see linkNode in markdown.js). Style it so it never reads as a
   broken or dead link, and show the real destination in a quieter tone. */
.md-link-inert { color: var(--ink); }
.md-link-dest { color: var(--faint); font-family: var(--sans); font-size: 0.86em; overflow-wrap: anywhere; }
.md-table { overflow-x: auto; margin: 0 0 0.85em; }
.answer table { border-collapse: collapse; font-family: var(--sans); font-size: 14px; }
.answer th, .answer td { border: 1px solid var(--hairline); padding: 6px 10px; text-align: left; }
.answer th { background: var(--bg); font-weight: 600; }

.chip { display: inline-flex; align-items: center; gap: 3px; margin: 0 1px; padding: 1px 7px 1px 6px; height: 18px; border: none; border-radius: 9px; background: var(--btn); color: #fff; font-family: var(--sans); font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; cursor: pointer; vertical-align: 1.5px; line-height: 1; box-shadow: 0 1px 1.5px rgba(16,38,30,.18); transition: background-color 150ms var(--ease), transform 120ms var(--ease), box-shadow 120ms var(--ease); }
.chip::before { content: "\2713"; font-size: 9px; opacity: .9; }
.chip:hover { background: var(--btn-hover); transform: translateY(-1px); box-shadow: 0 2px 6px rgba(14,138,95,.35); }
.chip:active { transform: scale(0.94); }

#cite-card { position: fixed; z-index: 50; max-width: min(360px, calc(100vw - 24px)); background: var(--raised); color: var(--ink); border: 1px solid var(--hairline); border-radius: 12px; padding: 11px 13px 10px; box-shadow: var(--shadow-pop); pointer-events: none; animation: cardin 140ms var(--ease); }
@keyframes cardin { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.cite-card-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--primary-dark); margin-bottom: 5px; }
.cite-card-quote { font-family: var(--serif); font-size: 14px; line-height: 1.5; color: var(--ink); border-left: 2px solid var(--primary); padding-left: 9px; }
.cite-card-hint { margin-top: 8px; font-family: var(--sans); font-size: 11px; color: var(--faint); }

.shimmer { font-family: var(--sans); font-size: 14.5px; color: var(--faint); background: linear-gradient(90deg, var(--faint) 30%, var(--ink) 50%, var(--faint) 70%); background-size: 200% 100%; -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; animation: sheen 1.4s linear infinite; }
@keyframes sheen { to { background-position: -200% 0; } }
.answer:not(:empty)::after { content: ""; display: inline-block; width: 7px; height: 1.05em; vertical-align: -0.18em; margin-left: 2px; background: var(--primary); border-radius: 1px; animation: caret 1s steps(1) infinite; }
.msg.assistant:has(.actions) .answer::after { display: none; }
@keyframes caret { 50% { opacity: 0; } }

.actions { display: flex; gap: 6px; margin-top: 10px; opacity: 0; transition: opacity 150ms var(--ease); }
.msg.assistant:hover .actions, .actions:focus-within { opacity: 1; }
@media (hover: none) { .actions { opacity: 1; } }
.action { background: transparent; border: 1px solid var(--line); border-radius: 8px; padding: 3px 10px; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); cursor: pointer; transition: border-color 120ms var(--ease), color 120ms var(--ease); }
.action:hover { border-color: var(--primary); color: var(--primary-dark); }
.stopped { font-size: 13px; color: var(--faint); font-style: italic; }

/* user-turn edit affordance */
.user-actions { justify-content: flex-end; }
.msg.user:hover .user-actions, .user-actions:focus-within { opacity: 1; }
.msg.user.editing { max-width: 100%; width: 100%; background: none; border: none; padding: 0; }
.edit-box { width: 100%; resize: vertical; background: var(--bg); border: 1px solid var(--primary); border-radius: 12px; color: var(--ink); padding: 10px 13px; font: inherit; font-size: 16px; line-height: 1.5; }
.edit-box:focus { outline: none; }
.edit-box:focus-visible { outline: var(--focus); outline-offset: 1px; }
.edit-row { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }

/* suggestion loading skeletons */
.suggestion-skeleton {
  height: 40px; border-radius: 10px;
  background: linear-gradient(90deg, var(--bg) 25%, var(--primary-light) 50%, var(--bg) 75%);
  background-size: 200% 100%; animation: skeleton 1.3s linear infinite;
  animation-delay: calc(var(--i) * 90ms);
}
@keyframes skeleton { to { background-position: -200% 0; } }

/* conversation export menu */
#convo-menu-wrap { position: relative; }
#convo-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 40; min-width: 200px; background: var(--raised); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-pop); padding: 6px; animation: cardin 120ms var(--ease); }
#convo-menu button { display: block; width: 100%; text-align: left; background: transparent; border: 0; border-radius: 8px; padding: 9px 11px; font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; }
#convo-menu button:hover { background: var(--primary-light); color: var(--primary-dark); }
.error-box { display: flex; align-items: center; gap: 10px; background: var(--danger-bg); border: 1px solid var(--danger-line); color: var(--danger); border-radius: 10px; padding: 10px 13px; font-size: 14px; }
.error-box::before { content: "!"; flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--danger-strong); color: #fff; font-size: 12px; font-weight: 800; line-height: 1; }
.retry { margin-left: auto; background: var(--btn); color: #fff; border: 0; border-radius: 7px; padding: 3px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.retry:hover { background: var(--btn-hover); }

#jump-latest { position: absolute; left: 50%; bottom: 84px; transform: translateX(-50%); z-index: 5; }
#jump-latest button { background: var(--raised); border: 1px solid var(--line); border-radius: 20px; padding: 7px 16px; font-size: 13px; font-weight: 600; color: var(--ink); cursor: pointer; box-shadow: var(--shadow-pop); animation: rise 160ms var(--ease); }

#ask-form { position: relative; display: flex; gap: 8px; align-items: flex-end; margin: 12px calc(16px + env(safe-area-inset-right, 0px)) calc(34px + env(safe-area-inset-bottom, 0px)) calc(16px + env(safe-area-inset-left, 0px)); padding: 8px 8px 8px 14px; background: var(--bg); border: 1.5px solid var(--line); border-radius: 16px; flex: none; box-shadow: 0 1px 2px rgba(16,38,30,.05); transition: border-color 140ms var(--ease), box-shadow 140ms var(--ease); }
#ask-form:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(14, 138, 95, 0.22); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 22%, transparent); }
#question { flex: 1; resize: none; background: transparent; border: 0; color: var(--ink); padding: 7px 2px; min-width: 0; max-height: 200px; font-size: 16px; line-height: 1.6; } /* 16px: prevents iOS focus zoom */
#question:focus { outline: none; }
#question::placeholder { color: var(--faint); }
.composer-hint { position: absolute; left: 0; right: 0; bottom: -19px; text-align: center; font-family: var(--sans); font-size: 11.5px; color: var(--faint); opacity: 0; pointer-events: none; transition: opacity 140ms var(--ease); }
#ask-form:focus-within .composer-hint { opacity: 1; }
#question:placeholder-shown ~ #ask-btn:not(.stop) { opacity: .8; }
#ask-btn { flex: none; width: 42px; height: 42px; display: grid; place-items: center; background: var(--btn); border: 0; border-radius: 12px; color: #fff; cursor: pointer; transition: background-color 150ms var(--ease), transform 100ms var(--ease), opacity 150ms var(--ease); }
#ask-btn:hover { background: var(--btn-hover); }
#ask-btn:active { transform: scale(0.95); }
#ask-btn.stop { background: var(--ink-soft); }
#ask-btn.stop svg { display: none; }
#ask-btn.stop::before { content: ""; width: 12px; height: 12px; background: #fff; border-radius: 3px; }

/* Question-quota meter: a quiet count above the composer that turns into a
   soft wall when the free allowance is spent (no surprise 429). */
.quota-meter { margin: 0 16px 6px; text-align: center; font-family: var(--sans); font-size: 12px; line-height: 1.45; color: var(--faint); }
.quota-meter.is-low { color: #b45309; font-weight: 600; }
.quota-meter.is-wall { color: var(--ink-soft); background: var(--primary-light); border: 1px solid color-mix(in srgb, var(--primary) 22%, transparent); border-radius: 12px; padding: 9px 14px; font-size: 12.5px; }
.quota-meter a { color: var(--primary-dark); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.quota-meter a:hover { color: var(--primary); }
html[data-theme="dark"] .quota-meter.is-low { color: #fbbf24; }
html[data-theme="dark"] .quota-meter a { color: var(--primary-dark); }

@media (max-width: 900px) {
  /* minmax(0, ...) so a pane's content height can never force its row open:
     without it the chat pane's min-content (empty state + suggestions) crushes
     the viewer row to a sliver on phones. */
  #panes { grid-template-columns: 1fr; grid-template-rows: minmax(0, 45fr) minmax(0, 55fr); }
  #chat-pane { border-left: none; border-top: 1px solid var(--hairline); }
  /* Keep zoom + fit reachable on touch: drop only the brand/page-count for room,
     never the viewer tools themselves. */
  #topbar .brand, #topbar .dot, #topbar #page-count { display: none; }
  #viewer-tools { display: flex; }
  .answer { max-width: 100%; }
}
/* Portrait phones: one pane at a time, chosen by the topbar tabs. A 45/55 split
   on a 375x667 screen gave the viewer ~277px, which fits about 60 percent of one
   page at half size. Tabs give whichever pane you are using the full height. */
@media (max-width: 900px) and (orientation: portrait) {
  #pane-tabs { display: flex; }
  #panes { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
  #panes.show-doc #chat-pane,
  #panes.show-chat #viewer-pane { display: none; }
  /* The tabs cost width; the zoom group is meaningless while the document is
     not on screen, so it yields. */
  #app.pane-chat #viewer-tools { display: none; }
  /* Trim the tabs to fit a 375px bar alongside the theme toggle, Export and
     New document. Measured 2px over before this. */
  #pane-tabs .tool-btn { padding: 6px 9px; font-size: 12.5px; }
  /* Each tab sheds the controls that belong to the OTHER pane: zoom is for a
     document on screen, Export is for the conversation. Without this the bar
     ran 10px over at 375px and 65px over at 320px once Export appeared. */
  #app:not(.pane-chat) #convo-menu-wrap { display: none; }
  /* Demo is a mode indicator, not a control; it yields before any of them. */
  #app #mode-badge { display: none; }
  #chat-pane { border-top: none; }
}

/* Landscape phones are under 900px wide but only ~390px tall, so the 45/55 row
   split left a ~152px viewer. Go back to two columns when the viewport is wider
   than it is tall. */
@media (max-width: 900px) and (min-aspect-ratio: 1/1) {
  #panes { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: none; }
  #chat-pane { border-left: 1px solid var(--hairline); border-top: none; }
}

/* Very narrow: keep the zoom controls tappable but shed the fit-mode text
   buttons + doc name so the topbar never clips New PDF. Fit stays reachable
   via the launcher command menu. Measured at 375px the row still came to
   422px, so tighten the gaps and padding as well. */
@media (max-width: 560px) {
  #fit-width, #fit-page, #doc-name { display: none; }
  #topbar { gap: 6px; padding: 0 8px; }
  #viewer-tools { min-width: 0; }
  .zoom-group .zoom-pct { min-width: 0; padding-inline: 6px; }
  .zoom-group .zoom-btn { padding: 5px 6px; }
  #new-doc { padding: 6px 9px; }
}
@media (max-width: 400px) {
  .zoom-group .zoom-pct { display: none; }
}

/* ---------- overlays ---------- */

#drop-overlay { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; padding: 16px; background: color-mix(in srgb, var(--bg) 78%, transparent);-webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); animation: cardin 120ms var(--ease); }
.drop-overlay-card { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: clamp(28px, 6vw, 44px) clamp(24px, 8vw, 60px); max-width: 100%; text-align: center; border-radius: 20px; color: var(--primary-dark); background: var(--card); border: 2px dashed var(--primary); box-shadow: var(--shadow-overlay); pointer-events: none; }
.drop-overlay-card strong { font-size: 20px; color: var(--ink); }
.drop-overlay-card span { font-size: 14px; color: var(--ink-soft); }

#toast { position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 12px); z-index: 110; max-width: calc(100vw - 32px); text-align: center; background: var(--ink); color: var(--bg); padding: 10px 18px; border-radius: 12px; font-size: 14px; font-weight: 600; box-shadow: var(--shadow-pop); opacity: 0; pointer-events: none; transition: opacity 200ms var(--ease), transform 200ms var(--ease); }
#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- viewer: find bar + match overlays ---------- */
.find-bar { position: absolute; top: 12px; right: 16px; z-index: 40; display: flex; align-items: center; gap: 6px; padding: 6px 6px 6px 10px; max-width: calc(100% - 32px); box-sizing: border-box; background: var(--raised); border: 1px solid var(--hairline); border-radius: var(--radius); box-shadow: var(--shadow); font-family: var(--sans); transform: translateY(-6px); opacity: 0; transition: opacity 160ms var(--ease), transform 160ms var(--ease); }
.find-bar.open { transform: translateY(0); opacity: 1; }
.find-count, .find-divider, .find-btn { flex: 0 0 auto; }
.find-input { flex: 1 1 160px; min-width: 0; border: none; outline: none; background: transparent; color: var(--ink); font: inherit; font-size: 14px; padding: 4px 2px; }
.find-input::placeholder { color: var(--faint); }
.find-count { min-width: 54px; text-align: right; color: var(--ink-soft); font-size: 12.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.find-bar.no-results .find-count, .find-bar.no-results .find-input { color: var(--danger); }
.find-divider { width: 1px; align-self: stretch; margin: 3px 2px; background: var(--hairline); }
.find-btn { display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: none; border-radius: 8px; background: transparent; color: var(--ink-soft); cursor: pointer; transition: background-color 120ms var(--ease), color 120ms var(--ease); }
.find-btn:hover { background: var(--primary-light); color: var(--primary-dark); }
.find-close:hover { background: var(--line); color: var(--ink); }
.find-hl { position: absolute; background: rgba(255, 191, 0, 0.40); border-radius: 2px; pointer-events: none; mix-blend-mode: multiply; z-index: 2; }
.find-hl.active { background: rgba(255, 145, 0, 0.55); box-shadow: 0 0 0 2px rgba(255, 145, 0, 0.9); }
html[data-theme="dark"] .find-hl { mix-blend-mode: screen; background: rgba(255, 200, 60, 0.32); }
html[data-theme="dark"] .find-hl.active { background: rgba(255, 176, 32, 0.5); box-shadow: 0 0 0 2px rgba(255, 190, 60, 0.95); }

/* ---------- viewer: zoom control group ---------- */
.zoom-group { display: flex; align-items: center; gap: 2px; }
.zoom-group .zoom-btn { min-width: 26px; padding: 5px 8px; line-height: 1; font-size: 15px; font-weight: 700; text-align: center; }
.zoom-group .zoom-pct { min-width: 48px; text-align: center; font-variant-numeric: tabular-nums; }

/* ---------- viewer: page pill + thumbnail rail ---------- */
.vnav-pill { position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%) translateY(6px); display: flex; align-items: center; gap: 2px; z-index: 6; padding: 4px; background: var(--card); border: 1px solid var(--hairline); border-radius: 999px; box-shadow: var(--shadow); color: var(--ink); opacity: 0; pointer-events: none; transition: opacity 200ms var(--ease), transform 200ms var(--ease); }
.vnav-pill.is-visible, .vnav-pill:focus-within { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
.vnav-pill :focus-visible { outline: var(--focus); outline-offset: var(--focus-offset); }
.vnav-pill-btn { display: grid; place-items: center; width: 30px; height: 30px; border: none; border-radius: 999px; background: transparent; color: var(--ink-soft); cursor: pointer; transition: background 120ms var(--ease), color 120ms var(--ease); }
.vnav-pill-btn:hover { background: var(--primary-light); color: var(--primary-dark); }
.vnav-pill-btn:disabled { opacity: 0.35; cursor: default; background: transparent; color: var(--ink-soft); }
.vnav-pill-field { display: flex; align-items: baseline; padding: 0 4px; font-variant-numeric: tabular-nums; }
.vnav-pill-input { width: 3ch; min-width: 3ch; text-align: right; border: none; background: transparent; color: var(--ink); font: inherit; font-size: 13.5px; font-weight: 600; padding: 2px 0; font-variant-numeric: tabular-nums; -moz-appearance: textfield; appearance: textfield; }
.vnav-pill-input::-webkit-outer-spin-button, .vnav-pill-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.vnav-pill-input:focus:not(:focus-visible) { outline: none; }
.vnav-pill-total { color: var(--faint); font-size: 13.5px; font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.vnav-rail-toggle { position: absolute; left: 12px; top: 12px; z-index: 7; display: grid; place-items: center; width: 34px; height: 34px; background: var(--card); border: 1px solid var(--hairline); border-radius: 10px; color: var(--ink-soft); box-shadow: var(--shadow); cursor: pointer; transition: color 120ms var(--ease), border-color 120ms var(--ease), background 120ms var(--ease); }
.vnav-rail-toggle:hover { color: var(--primary-dark); border-color: var(--primary); }
.vnav-rail-toggle.is-active { color: var(--primary-dark); background: var(--primary-light); border-color: var(--primary); }
.vnav-rail { position: absolute; left: 0; top: 0; bottom: 0; width: min(160px, 82vw); z-index: 5; display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 56px 10px 16px; overflow-y: auto; overscroll-behavior: contain; background: var(--card); border-right: 1px solid var(--hairline); box-shadow: 8px 0 28px rgba(16,38,30,.14); transform: translateX(-100%); transition: transform 260ms var(--ease); }
.vnav-rail.is-open { transform: translateX(0); }
html[data-theme="dark"] .vnav-rail { box-shadow: 8px 0 30px rgba(0, 0, 0, 0.55); }
/* Rail overlays the viewer (never reflows content). Optional push layout only on wide screens. */
@media (min-width: 1101px) { #viewer-pane.vnav-has-rail #viewer { padding-left: 184px; } }
.vnav-thumb { display: flex; flex-direction: column; align-items: center; gap: 4px; width: 100%; border: none; background: transparent; padding: 0; cursor: pointer; }
.vnav-thumb-shell { display: block; width: 120px; border: 1px solid var(--line); border-radius: 4px; background: var(--raised); overflow: hidden; box-shadow: var(--shadow); transition: border-color 120ms var(--ease), box-shadow 120ms var(--ease); min-height: 40px; }
.vnav-thumb-canvas { display: block; width: 120px; height: auto; }
.vnav-thumb-num { font-size: 11.5px; font-weight: 600; color: var(--faint); font-variant-numeric: tabular-nums; }
.vnav-thumb:hover .vnav-thumb-shell { border-color: var(--primary); }
.vnav-thumb.is-current .vnav-thumb-shell { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary); }
.vnav-thumb.is-current .vnav-thumb-num { color: var(--primary-dark); }
.vnav-thumb.is-failed .vnav-thumb-shell { background: var(--hairline); }

/* ---------- command menu (cmd-k) + help sheet ---------- */
.cmdk { position: fixed; inset: 0; z-index: 120; display: grid; place-items: start center; padding-top: 14vh; background: var(--scrim);-webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); animation: cardin 120ms var(--ease); }
.cmdk-box { width: min(520px, 92vw); background: var(--raised); border: 1px solid var(--hairline); border-radius: 14px; box-shadow: var(--shadow-overlay); overflow: hidden; }
.cmdk-input { width: 100%; border: 0; border-bottom: 1px solid var(--hairline); background: transparent; color: var(--ink); font: inherit; font-size: 16px; padding: 15px 18px; }
.cmdk-input:focus { outline: none; }
.cmdk-list { list-style: none; margin: 0; padding: 6px; max-height: 320px; overflow-y: auto; }
.cmdk-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; border-radius: 9px; cursor: pointer; }
.cmdk-item.active { background: var(--primary-light); }
.cmdk-label { font-size: 14.5px; font-weight: 600; color: var(--ink); }
.cmdk-item.active .cmdk-label { color: var(--primary-dark); }
.cmdk-hint { font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }
.help-sheet { position: fixed; inset: 0; z-index: 120; display: grid; place-items: center; padding: 16px; background: var(--scrim);-webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); animation: cardin 120ms var(--ease); }
.help-box { width: min(460px, 92vw); max-height: calc(100dvh - 32px); overflow-y: auto; background: var(--raised); border: 1px solid var(--hairline); border-radius: 16px; box-shadow: var(--shadow-overlay); padding: 22px 24px; }
.help-title { font-size: 20px; margin-bottom: 16px; }
.help-grid { display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; align-items: center; }
.help-key { justify-self: start; font-family: ui-monospace, Menlo, monospace; font-size: 12px; background: var(--bg); border: 1px solid var(--line); border-radius: 6px; padding: 2px 8px; color: var(--ink-soft); white-space: nowrap; }
.help-desc { font-size: 14.5px; color: var(--ink); }
.help-close { margin-top: 20px; background: var(--btn); color: #fff; border: 0; border-radius: 10px; padding: 8px 18px; font-size: 14px; font-weight: 700; cursor: pointer; }
.help-close:hover { background: var(--btn-hover); }
.cmdk-box :focus-visible, .help-box :focus-visible { outline: var(--focus); outline-offset: var(--focus-offset); }

/* ---------- viewer: pointer/touch launcher (opens command menu + help) ---------- */
.viewer-launch { position: absolute; right: 16px; bottom: 18px; z-index: 35; display: flex; gap: 8px; }
.viewer-launch[hidden] { display: none; }
.viewer-launch-btn { display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 1px solid var(--hairline); border-radius: var(--radius); background: var(--card); color: var(--ink-soft); font-size: 18px; font-weight: 700; line-height: 1; cursor: pointer; box-shadow: var(--shadow); transition: color 120ms var(--ease), border-color 120ms var(--ease), background 120ms var(--ease); }
.viewer-launch-btn:hover { color: var(--primary-dark); border-color: var(--primary); background: var(--primary-light); }


/* Touch: raise viewer + chrome controls to a 44px hit target. */
@media (hover: none) {
  .suggestion { padding-right: 14px; }
  .suggestion::after { display: none; }
}
@media (pointer: coarse) {
  .find-btn, .vnav-pill-btn, .vnav-rail-toggle, .site-theme-toggle.small, .viewer-launch-btn { width: 44px; height: 44px; }
  .tool-btn, .action, .ghost-btn, .zoom-group .zoom-btn { min-height: 44px; }
  /* These were all under the floor: the send button (42px), the recovery
     button after a failed answer, the export menu rows and the suggestions. */
  #ask-btn { width: 44px; height: 44px; }
  .zoom-group .zoom-btn { min-width: 44px; }
  .retry, #convo-menu button, .cmdk-item, .help-close, .suggestion { min-height: 44px; }
  .retry, .help-close { display: inline-flex; align-items: center; justify-content: center; }
  .arrival-pill-x { min-width: 44px; min-height: 44px; display: grid; place-items: center; padding: 0; }
  .vnav-pill-input { min-height: 44px; width: 4ch; min-width: 4ch; }
  /* The citation chip sits inline in flowing prose. An earlier attempt gave it a
     44x44 absolutely-positioned ::after, which is 13px taller than the line box
     in each direction: an invisible overlay lying across the words above and
     below, swallowing taps meant for them and interfering with selection.
     WCAG 2.5.8 exempts targets inline in a sentence, so grow the pill itself
     within its line instead of overlaying its neighbours. */
  .chip { height: auto; min-height: 24px; padding-block: 4px; }
  .fact-cite { min-width: 44px; min-height: 44px; }
}
.fact-cite { min-width: 24px; min-height: 24px; }

/* The find bar is anchored inside #viewer-pane, so bound it to the pane rather
   than the page, and keep it clear of the rail toggle at the same top offset. */
@media (max-width: 480px) {
  .find-bar { left: 12px; right: 12px; max-width: none; }
  #viewer-pane:has(.find-bar.open) .vnav-rail-toggle { opacity: 0; pointer-events: none; }
}
/* Below ~420px the centred page pill and the bottom-right launcher overlapped. */
@media (max-width: 420px) {
  .vnav-pill { left: 12px; transform: translateY(6px); }
  .vnav-pill.is-visible, .vnav-pill:focus-within { transform: translateY(0); }
  .viewer-launch { bottom: 72px; }
}

@media (prefers-reduced-motion: reduce) {
  *, ::after, ::before { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
  .shimmer { -webkit-text-fill-color: var(--faint); }
  .answer::after { display: none; }
  .find-bar, .vnav-pill, .vnav-rail { transition: none; }
  #dropzone:hover, #dropzone.over, .site-cta:hover, .site-cta:active,
  #ask-btn:active, .chip:active { transform: none !important; }
}

/* print: only the conversation, citations as static superscript page labels */
@media print {
  #site, #topbar, #viewer-pane, #ask-form, #jump-latest, #cite-card, #drop-overlay, #toast, .actions, .cmdk, .help-sheet,
  .scroll-progress, .arrival-pill, .quota-meter, .find-bar, .vnav-pill, .vnav-rail, .vnav-rail-toggle, .viewer-launch { display: none !important; }
  #app { height: auto; display: block; }
  #panes { display: block; }
  #chat-pane { border: 0; background: #fff; }
  #messages { display: block; overflow: visible; background: #fff; padding: 0; }
  .msg { max-width: 100% !important; break-inside: avoid; margin-bottom: 14px; }
  .msg.user { background: none; border: 0; padding: 0; font-weight: 700; }
  .msg.user::before { content: "You: "; }
  .answer { color: #000; max-width: 100%; }
  .answer::after { display: none; }
  .chip { background: none; color: #000; font-size: 9px; vertical-align: super; padding: 0; height: auto; }
  .chip::before { content: ""; }
}

/* ---------- legal / privacy page ---------- */
.legal { max-width: 760px; margin: 0 auto; padding: clamp(40px, 6vw, 72px) var(--gutter); }
.legal h1 { font-size: clamp(2rem, 4vw, 2.6rem); letter-spacing: -0.02em; margin: 0 0 8px; }
.legal .updated { color: var(--faint); font-size: 14px; margin: 0 0 28px; }
.legal .callout { background: var(--primary-light); border: 1px solid color-mix(in srgb, var(--primary) 20%, var(--hairline)); border-radius: 14px; padding: 18px 20px; margin: 0 0 30px; }
.legal .callout p { color: var(--ink); margin: 0; font-size: 16px; line-height: 1.6; }
.legal h2 { font-family: var(--sans); font-size: 19px; font-weight: 700; letter-spacing: -0.01em; color: var(--ink); margin: 34px 0 10px; }
.legal p { color: var(--ink-soft); font-size: 15.5px; line-height: 1.7; margin: 0 0 12px; max-width: 68ch; }
.legal ul { margin: 0 0 12px; padding-left: 1.3em; color: var(--ink-soft); font-size: 15.5px; line-height: 1.7; max-width: 68ch; }
.legal li { margin: 5px 0; }
.legal a { color: var(--primary-dark); }
.legal strong { color: var(--ink); font-weight: 650; }


/* Section eyebrow kicker (shared). */
.band-eyebrow { display: flex; align-items: center; justify-content: center; gap: 9px; font-family: var(--sans); font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 1.4px; color: var(--primary-dark); margin: 0 0 10px; }
.band-eyebrow::before, .band-eyebrow::after { content: ""; width: 22px; height: 2px; border-radius: 2px; background: linear-gradient(90deg, transparent, var(--primary)); }
.band-eyebrow::after { background: linear-gradient(90deg, var(--primary), transparent); }
/* See-it-work: self-playing citation -> highlight demo, centered under a heading. */
.demo-band { text-align: center; }
.hero-demo { position: relative; isolation: isolate; margin: 10px auto 0; width: 100%; max-width: 640px; text-align: left; }
.hero-demo::before { content: ""; position: absolute; left: 50%; top: 50%; width: 108%; aspect-ratio: 1; transform: translate(-50%, -50%); border-radius: 50%; z-index: -1; pointer-events: none; filter: blur(52px); opacity: 0.4; background: conic-gradient(from 0deg, #34c188, #14b8a6, #7be3b6, #eab308, #34c188); animation: fp-aurora 26s linear infinite; }
.demo-card { position: relative; border-radius: 16px; overflow: hidden; background: var(--card); border: 1px solid color-mix(in srgb, var(--primary) 26%, var(--line)); box-shadow: 0 2px 8px rgba(16, 38, 30, 0.1), 0 40px 80px -34px rgba(16, 38, 30, 0.5); animation: fp-float 7s ease-in-out infinite alternate; }
html[data-theme="dark"] .demo-card { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4), 0 40px 84px -34px rgba(0, 0, 0, 0.7); }
@keyframes fp-float { from { transform: translateY(3px); } to { transform: translateY(-9px); } }
.demo-bar { display: flex; align-items: center; gap: 6px; padding: 11px 15px; border-bottom: 1px solid var(--hairline); }
.demo-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line); }
.demo-name { margin-left: 8px; font-family: var(--sans); font-size: 11.5px; font-weight: 600; color: var(--faint); }
.demo-split { display: grid; grid-template-columns: 0.9fr 1.1fr; }
.demo-doc { padding: 18px 16px; display: flex; flex-direction: column; gap: 10px; background: color-mix(in srgb, var(--ink) 3%, var(--card)); border-right: 1px solid var(--hairline); }
.dl { height: 7px; border-radius: 4px; background: var(--line); }
.dl.w5 { width: 50%; } .dl.w6 { width: 62%; } .dl.w7 { width: 72%; } .dl.w8 { width: 84%; } .dl.w9 { width: 94%; }
.dl-cite { position: relative; overflow: visible; }
.dl-mark { position: absolute; inset: -3px -2px; width: 0; border-radius: 4px; background: rgba(245, 190, 60, 0.5); box-shadow: 0 0 0 1px rgba(245, 190, 60, 0.4); animation: fp-mark 9s var(--ease) infinite; }
.demo-chat { padding: 17px 17px 19px; display: flex; flex-direction: column; gap: 12px; }
.demo-ask { align-self: flex-end; max-width: 88%; background: var(--primary-light); color: var(--primary-dark); border-radius: 12px 12px 4px 12px; padding: 8px 12px; font-family: var(--sans); font-size: 13px; font-weight: 600; animation: fp-ask 9s var(--ease) infinite; }
.demo-ans { animation: fp-ans 9s var(--ease) infinite; }
.demo-ans-tag { display: block; font-family: var(--sans); font-size: 9.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--primary-dark); margin-bottom: 6px; }
.demo-ans-text { font-family: var(--serif); font-size: 14px; line-height: 1.55; color: var(--ink); margin: 0; }
.demo-cite { display: inline-flex; align-items: center; gap: 2px; margin: 0 3px; padding: 1px 6px; height: 16px; border-radius: 8px; background: var(--btn); color: #fff; font-family: var(--sans); font-size: 10px; font-weight: 700; vertical-align: 1px; animation: fp-cite 9s var(--ease) infinite; }
@keyframes fp-ask { 0%, 4% { opacity: 0; transform: translateY(7px); } 9%, 90% { opacity: 1; transform: none; } 97%, 100% { opacity: 0; } }
@keyframes fp-ans { 0%, 20% { opacity: 0; transform: translateY(9px); } 29%, 90% { opacity: 1; transform: none; } 97%, 100% { opacity: 0; } }
@keyframes fp-cite { 0%, 38% { opacity: 0; transform: scale(0.3); } 44% { opacity: 1; transform: scale(1.18); } 49%, 90% { opacity: 1; transform: scale(1); } 97%, 100% { opacity: 0; } }
@keyframes fp-mark { 0%, 45% { width: 0; opacity: 0; } 47% { opacity: 1; } 55%, 90% { width: calc(100% + 4px); opacity: 1; } 97%, 100% { width: calc(100% + 4px); opacity: 0; } }
@media (max-width: 620px) { .hero-demo { max-width: 460px; } }
/* Side by side, the chat column fell to ~146px on a phone and the answer broke
   into seven ragged lines. Stack the two halves instead. */
@media (max-width: 560px) {
  .demo-split { grid-template-columns: 1fr; }
  .demo-doc { border-right: 0; border-bottom: 1px solid var(--hairline); }
  .demo-ask { max-width: 92%; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-demo::before, .demo-card, .demo-ask, .demo-ans, .demo-cite { animation: none; }
  .demo-ask, .demo-ans, .demo-cite { opacity: 1; transform: none; }
  .dl-mark { animation: none; width: calc(100% + 4px); opacity: 1; }
}

/* ===== vendored shared header + footer (unified frame; source: shared-frame sync) ===== */
/* Shared-frame token map (property-owned): the vendored header/footer read
   --fp-* and follow the page theme. theme-boot.js always stamps data-theme,
   so both shared theme states are exercised. */
:root {
  --fp-header-h: 64px;
  --fp-bg: var(--bg);
  --fp-ink: var(--ink);
  --fp-green: var(--primary);
  --fp-green-soft: var(--primary-dark);
  --fp-orange: var(--dc-btn);
  --fp-orange-hover: var(--dc-btn-hover);
  --fp-orange-ink: #ffffff;
}

/* fp-shared-frame:start (vendored css; update via scripts/sync-shared-frame.sh) */
/* FormsPal shared header. Scope everything under .site-head (plus :root/html
   for variables and the no-JS fallback). Fleet look: dark-first, green
   primary, orange CTA. Properties override the --fp-* variables. */

/* The sticky bar would otherwise cover whatever a keyboard Tab or an anchor
   jump scrolls to the top of the viewport (WCAG 2.2 SC 2.4.11). */
html {
  scroll-padding-top: calc(var(--fp-header-h, 64px) + 8px);
}

:root {
  --fp-header-h: 64px;
  --fp-ease: cubic-bezier(0.2, 0, 0, 1);
  --fp-dur: 150ms;
}

.site-head {
  position: sticky;
  top: 0;
  z-index: 50;
  /* min-height, not height: if the measured collapse ever fails to fire, a
     wrapped nav grows the bar instead of overlapping the page beneath it.
     Content never exceeds 44px plus padding in the normal case, so the
     rendered height stays 64px and CLS is unchanged. */
  min-height: var(--fp-header-h);
  background: var(--fp-bg, #0b1f17);
  color: var(--fp-ink, #eaf5ef);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  --fp-head-soft: color-mix(in oklab, var(--fp-ink, #eaf5ef) 82%, var(--fp-bg, #0b1f17));
  --fp-head-muted: color-mix(in oklab, var(--fp-ink, #eaf5ef) 70%, var(--fp-bg, #0b1f17));
}
html[data-theme="light"] .site-head {
  background: var(--fp-bg, #f4faf7);
  color: var(--fp-ink, #10231a);
  border-bottom-color: rgba(0, 0, 0, 0.08);
  --fp-head-soft: color-mix(in oklab, var(--fp-ink, #10231a) 82%, var(--fp-bg, #f4faf7));
  --fp-head-muted: color-mix(in oklab, var(--fp-ink, #10231a) 70%, var(--fp-bg, #f4faf7));
}

/* The frame owns the box model of its own padded controls. Every control
   that combines padding with a 44px floor would otherwise render at
   44 + padding wherever the host page ships no reset: measured on a page
   with none, .site-cta, .site-nav a and .site-drop-list a all came out at
   60px instead of 44. Five properties ship a global reset, but
   formspal-legal-tools scopes its own to `.lp *` and `.dc-app *` and the
   frame sits at body level outside both, so the same markup rendered two
   different bars across the fleet. It is also latent breakage: the
   collapsed panel is positioned at top: var(--fp-header-h), so a property
   that lowered that token would grow the bar past it while the panel
   stayed put. <button> already gets border-box from the UA sheet; the
   anchors do not, and the frame should not depend on either.

   .site-nav-wrap is in this list for the same reason at a different scale.
   It is not a 44px control, but it is the one box here where padding meets
   a viewport-relative bound: collapsed, it carries
   max-height: calc(100vh - var(--fp-header-h)) together with
   padding: 8px 16px 16px. Under content-box those add rather than nest, so
   the panel's border box is the max-height plus 24px of padding plus its
   1px border. Measured at 700x600 the collapsed panel's bottom landed at
   625 against a 600px viewport, 25px past the fold, and the overshoot is
   the part holding the last row of links. Border-box makes the bound mean
   what it says. This one predates the 44px floors and is identical in
   v0.7.1, but the rule above claims the frame owns the box model of its own
   padded boxes, and this is the box where the claim pays. */
.site-head .site-cta,
.site-head .site-nav a,
.site-head .site-drop-btn,
.site-head .site-menu-btn,
.site-head .site-drop-list a,
.site-head .site-drop-list span[aria-current],
.site-head .site-nav-wrap,
/* The frame's own layout containers must not inherit the host page's box model.
   A property whose reset is scoped (e.g. `.lp * { box-sizing: border-box }`)
   leaves these in content-box, where max-width applies to the CONTENT box and
   the 16px padding is added on top: the bar then renders 32px wider than the
   footer's matching 1120px container and the two land on different edges. */
.site-head-inner {
  box-sizing: border-box;
}

.site-head-inner {
  max-width: 1120px;
  min-height: var(--fp-header-h);
  margin: 0 auto;
  padding: 0 16px;
  display: flex;
  align-items: center;
  gap: 20px;
}

.site-head .site-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  /* 44px floor: Apple HIG's default control size, and WCAG 2.5.5 AAA. The
     64px bar absorbs a 44px control with no change to its own height.
     min-width is deliberately NOT set here: on a flex item it would replace
     the automatic minimum size (min-width: auto, i.e. min-content) and let
     the brand be squeezed below its own nowrap content. Measured at 480px
     with the app name "Statute of Limitations", a 44px floor gave an 85px
     box around 202.6px of content: the trailing text ran out over the
     hamburger and, with justify-content: center, the logo mark clipped off
     the left edge. The floor is needed only below 430px, where the wordmark
     and app name are both hidden and the 28px mark alone would be the whole
     target, so it lives in that breakpoint with the centering it needs. */
  min-height: 44px;
  color: inherit;
  text-decoration: none;
  font-size: 17px;
  white-space: nowrap;
}
.site-head .site-brand svg { width: 28px; height: 28px; flex: none; }
.site-head .site-brand .app {
  color: var(--fp-head-soft);
  font-weight: 500;
}

.site-head .site-nav-wrap {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  flex: 1;
}

.site-head .site-dropdown { position: relative; }

.site-head .site-drop-btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 4px;
  font: inherit;
  font-size: 14px;
  color: inherit;
  background: none;
  border: 0;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.site-head .site-drop-btn:hover,
.site-head .site-drop-btn[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.08);
}
html[data-theme="light"] .site-head .site-drop-btn:hover,
html[data-theme="light"] .site-head .site-drop-btn[aria-expanded="true"] {
  background: rgba(0, 0, 0, 0.06);
}
.site-head .site-drop-btn .caret { width: 14px; height: 14px; }

.site-head .site-drop-list {
  list-style: none;
  margin: 0;
  padding: 6px;
}
.site-head .site-drop-list a,
.site-head .site-drop-list span[aria-current] {
  display: block;
  padding: 8px 12px;
  border-radius: 8px;
  color: inherit;
  text-decoration: none;
  font-size: 14px;
  white-space: nowrap;
}
.site-head .site-drop-list a:hover {
  background: var(--fp-green, #0e8a5f);
  color: #fff;
}
.site-head .site-drop-list span[aria-current] { color: var(--fp-head-muted); }

/* JS-enabled: dropdowns collapse into popovers. Without the fp-js class
   (JS disabled or failed) the lists stay in normal flow, fully visible. */
html.fp-js .site-head .site-drop-list {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 230px;
  background: var(--fp-bg, #0e2a1f);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
}
html[data-theme="light"].fp-js .site-head .site-drop-list {
  background: var(--fp-bg, #ffffff);
  border-color: rgba(0, 0, 0, 0.1);
}
html.fp-js .site-head .site-dropdown.open .site-drop-list { display: block; }

.site-head .site-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  /* Never overflow: hidden here. It converts "does not fit" into "silently
     disappears": measured at 768px the nav wanted 244px, got 79px, and lost
     two links entirely with no scrollbar to hint at it. header.js decides
     fit now. Wrapping is the visible, debuggable fallback. */
  flex-wrap: wrap;
}
.site-head .site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: inherit;
  text-decoration: none;
  font-size: 14px;
  padding: 8px 10px;
  border-radius: 8px;
  white-space: nowrap;
}
.site-head .site-nav a:hover { background: rgba(255, 255, 255, 0.08); }
html[data-theme="light"] .site-head .site-nav a:hover { background: rgba(0, 0, 0, 0.06); }

.site-head .site-right {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
  flex: none;
}

.site-head .site-menu-btn {
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  color: inherit;
  background: none;
  border: 0;
  padding: 8px;
  border-radius: 8px;
  cursor: pointer;
  margin-left: auto;
}
.site-head .site-menu-btn svg { width: 22px; height: 22px; display: block; }

/* No-JS fallback (all widths): without the fp-js class the dropdown lists
   stay in normal flow as plain visible link lists, so the bar can no longer
   hold a fixed height. It grows instead, and the nav wraps to its own full
   width row below the brand, which itself stacks when it runs out of width.
   The hamburger never appears without JS, so nothing here may be gated on
   the collapse class: only header.js sets it. This path is not the rare
   one it sounds like. ocr-web and pdf-extension both load header.js with
   defer, against the documented contract, so it is what paints on every
   page load there until the script runs. */
html:not(.fp-js) .site-head {
  height: auto;
  min-height: var(--fp-header-h);
}
html:not(.fp-js) .site-head .site-head-inner {
  flex-wrap: wrap;
  height: auto;
  padding: 8px 16px;
}
html:not(.fp-js) .site-head .site-nav-wrap {
  flex-basis: 100%;
  /* The panel has to stack here, not under html.fp-nav-collapsed. Only
     header.js ever sets that class, so with no script the wrap stayed a
     single unwrapped row: measured at 375px with fp-js absent, the document
     was 527px wide against a 375px viewport, and the wrap itself 511px
     inside a 343px box. That is the reflow failure (WCAG 1.4.10, measured
     at 320px) the 719px media block used to cover, because it applied
     whether or not fp-js was present.

     Wrapping rather than an unconditional column, and rather than a second
     breakpoint: nothing without JS can measure fit, and the fit point is
     property-owned (nav copy, page-nav slot). Wrap answers it from the
     content at every width. The groups sit side by side while they fit
     (at 1280px the no-JS bar is still the same single row it was) and
     stack when they do not, which is what the removed block did below
     719px. */
  flex-wrap: wrap;
  /* Bounded like the JS panel: without this the stacked groups make a
     header taller than the phone showing it. */
  max-height: calc(100vh - var(--fp-header-h));
  overflow: auto;
}
html:not(.fp-js) .site-head .site-menu-btn {
  display: none;
}

/* Collapsed: one hamburger; dropdown groups and page nav stack in a panel.
   Height stays fixed and the panel overlays below the bar (no CLS).

   Driven by a class rather than a width because the fit point is not a
   constant. It moves with the nav copy, the CTA label, and anything a
   property puts in .site-right, including the plan pill that only appears
   after sign-in. header.js sets this class from a real measurement. */
html.fp-nav-collapsed .site-head .site-menu-btn { display: inline-flex; }
html.fp-nav-collapsed .site-head .site-nav-wrap {
  display: none;
  position: absolute;
  top: var(--fp-header-h);
  left: 0;
  right: 0;
  flex-direction: column;
  align-items: stretch;
  background: var(--fp-bg, #0b1f17);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  padding: 8px 16px 16px;
  max-height: calc(100vh - var(--fp-header-h));
  overflow: auto;
}
html[data-theme="light"].fp-nav-collapsed .site-head .site-nav-wrap { background: var(--fp-bg, #f4faf7); }
html.fp-nav-collapsed .site-head.menu-open .site-nav-wrap { display: flex; }
html.fp-js.fp-nav-collapsed .site-head .site-drop-list,
html.fp-js.fp-nav-collapsed .site-head .site-dropdown.open .site-drop-list {
  position: static;
  display: block;
  min-width: 0;
  border: 0;
  box-shadow: none;
  background: none;
}
html.fp-nav-collapsed .site-head .site-drop-btn { pointer-events: none; }
html.fp-nav-collapsed .site-head .site-drop-btn .caret { display: none; }
html.fp-nav-collapsed .site-head .site-nav { flex-direction: column; align-items: stretch; }
/* There is deliberately no html:not(.fp-js).fp-nav-collapsed rule here.
   header.js adds fp-js at execute time and fp-nav-collapsed only after
   that, so the combination cannot occur and any rule written for it is
   dead code that reads like the no-JS fallback while doing nothing. The
   no-JS layout lives in one place, the html:not(.fp-js) block above. */

/* The hamburger belongs with the other controls, not adrift mid bar.
   .site-menu-btn and .site-right both carry margin-left: auto, and flexbox
   splits the free space between two auto margins: measured at 768px the
   brand ended at x=171.9, the hamburger sat at x=284.6 and the right
   cluster started at x=441.2, leaving 92.6px of dead space on each side.
   Dropping the right cluster's auto margin while collapsed hands all the
   free space to the hamburger's own, so the bar reads the way it does
   expanded: brand left, controls right. Scoped to the collapsed state
   because .site-right's auto margin is what right-aligns the cluster when
   the nav is a normal flex item.

   The coupling this creates: while collapsed, .site-right is right-aligned
   only because the hamburger's auto margin is still in the row absorbing
   the free space. Take the button out of the markup, or have a property
   force it display: none while collapsed, and nothing pushes: the cluster
   slides left from x=441.2 to x=191.9 and sits mid bar. No property in the
   fleet does either today, and the frame ships the button in header.html,
   so this is a note for whoever changes that, not a live bug. */
html.fp-nav-collapsed .site-head .site-right { margin-left: 0; }

/* Hallmark · component: header right-side controls · genre: modern-minimal
 * theme: FormsPal fleet tokens (--fp-*)
 * states: default · hover · focus-visible · active (loading/error/success N/A for nav)
 * Right-side controls: shared base styles. Properties may override, but the
 * bar ships finished. */

.site-head .site-drop-btn .caret {
  transition: transform var(--fp-dur) var(--fp-ease);
}
.site-head .site-drop-btn[aria-expanded="true"] .caret {
  transform: rotate(180deg);
}

.site-head .site-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: none;
  color: inherit;
  cursor: pointer;
  transition: background-color var(--fp-dur) var(--fp-ease);
}
.site-head .site-theme-toggle svg {
  width: 18px;
  height: 18px;
  display: block;
  stroke: currentColor;
}
.site-head .site-theme-toggle .moon { display: none; }
html[data-theme="light"] .site-head .site-theme-toggle .sun { display: none; }
html[data-theme="light"] .site-head .site-theme-toggle .moon { display: block; }
.site-head .site-theme-toggle:hover { background: rgba(255, 255, 255, 0.08); }
html[data-theme="light"] .site-head .site-theme-toggle:hover { background: rgba(0, 0, 0, 0.06); }
.site-head .site-theme-toggle:active { transform: translateY(1px); }

.site-head .site-cta {
  display: inline-flex;
  align-items: center;
  /* The frame owns this button's box, so it owns the containing block for
     anything a property decorates it with. Two properties add a ::after gleam
     that sweeps on hover, sized in percentages. Without position: relative
     those percentages resolved against .site-head, which is sticky and
     therefore the nearest positioned ancestor: the gleam came out 630px wide
     and 64px tall on a 150x44 button, and swept the full width of the bar.
     overflow: hidden then keeps it inside the rounded rect. Harmless for
     properties that add no decoration. */
  position: relative;
  overflow: hidden;
  min-height: 44px;
  padding: 8px 14px;
  border-radius: 10px;
  background: var(--fp-orange, #ef8b2d);
  color: var(--fp-orange-ink, #1c1206);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--fp-dur) var(--fp-ease), transform var(--fp-dur) var(--fp-ease);
}
.site-head .site-cta:hover { background: var(--fp-orange-hover, #f79c47); }
.site-head .site-cta:active { transform: translateY(1px); }

.site-head .site-theme-toggle:focus-visible,
.site-head .site-cta:focus-visible,
.site-head .site-drop-btn:focus-visible,
.site-head .site-menu-btn:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .site-head .site-drop-btn .caret,
  .site-head .site-theme-toggle,
  .site-head .site-cta {
    transition-duration: 0.01ms;
  }
}

/* Design elevation: glass bar, live tier badge, dropdown entrance.
   All motion is transform/opacity only and collapses under reduced motion. */

@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  html.fp-js .site-head {
    background: color-mix(in oklab, var(--fp-bg, #0b1f17) 86%, transparent);
    -webkit-backdrop-filter: blur(12px) saturate(1.4);
    backdrop-filter: blur(12px) saturate(1.4);
  }
  html[data-theme="light"].fp-js .site-head {
    background: color-mix(in oklab, var(--fp-bg, #f4faf7) 86%, transparent);
  }
}

.site-head .site-brand svg {
  transition: transform var(--fp-dur) var(--fp-ease);
}
.site-head .site-brand:hover svg {
  transform: rotate(-4deg) scale(1.06);
}

.site-head .tier-badge[hidden] { display: none; }
.site-head .tier-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: inherit;
  white-space: nowrap;
  border: 1px solid color-mix(in oklab, var(--fp-green, #0e8a5f) 45%, transparent);
  background: color-mix(in oklab, var(--fp-green, #0e8a5f) 14%, transparent);
}
.site-head .tier-dot {
  position: relative;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--fp-green-soft, #34d399);
}
.site-head .tier-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: fp-live 2.4s var(--fp-ease) infinite;
}
@keyframes fp-live {
  0% { transform: scale(1); opacity: 0.7; }
  70%, 100% { transform: scale(2.6); opacity: 0; }
}

html.fp-js .site-head .site-dropdown.open .site-drop-list {
  animation: fp-drop 160ms var(--fp-ease);
}
@keyframes fp-drop {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .site-head .tier-dot::after,
  html.fp-js .site-head .site-dropdown.open .site-drop-list {
    animation: none;
  }
  .site-head .site-brand svg {
    transition-duration: 0.01ms;
  }
}

/* Narrow screens: the bar sheds furniture in priority order (logo, hamburger,
   CTA, toggle, plan pill) instead of overflowing. Without this the right
   cluster keeps its full width and forces horizontal page scroll. */
@media (max-width: 560px) {
  .site-head .site-head-inner { gap: 12px; padding: 0 14px; }
  .site-head .site-brand b { display: none; }
  .site-head .site-cta { padding: 8px 12px; font-size: 13.5px; }
  .site-head .site-right { gap: 8px; min-width: 0; }
}
/* The 44px hit regions are 30px wider than what they replaced, and until
   this block paid for them the collapsed bar simply overflowed. Against
   v0.7.1 at a 320px viewport: brand 28 to 44, hamburger 38 to 44, theme
   toggle 36 to 44. The row ran to x=343.5 where v0.7.1 ended it at 313.5,
   and the document read 320/343 (23px of horizontal scroll) where v0.7.1
   read 320/320. That is a WCAG 1.4.10 reflow failure at the reference
   width, and it only appears with the plan pill shown, which is the state
   this release exists for: ocr-web ships the badge hidden and reveals it
   after sign-in, so it was signed-in phone users who got the scrollbar.

   The 30px comes back out of spacing and pill chrome, never out of a hit
   region. Each number continues a ladder the wider blocks already walk:
   inner gap 20/12/8, inner padding 16/14/10, .site-right gap 10/8/6.
   Collapsed, the row is brand + hamburger + cluster, so the inner gap is
   spent twice and only the LEFT inner padding moves the far edge that
   decides scrollWidth. Budget at 320px, pill shown: 10 + 44 + 8 + 44 + 8 +
   (9 + 6 + 44 + 6 + 134.5) = 313.5, back to where v0.7.1 had it, with
   every control still 44px. */
@media (max-width: 430px) {
  .site-head .site-head-inner { gap: 8px; padding: 0 10px; }
  .site-head .site-brand .app { display: none; }
  /* Only here is the brand small enough to need the floor: wordmark and app
     name are both gone and the 28px mark alone would be the target. Above
     this width the nowrap content is already wider than 44px, so declaring
     the floor there only broke the automatic minimum size. */
  .site-head .site-brand { min-width: 44px; justify-content: center; }
  .site-head .site-right { gap: 6px; }
  /* The pill is already only a dot here: .tier-label goes to display: none
     just below, so the border, background and 7px of side padding are a
     ring around a 7px dot and 14px of the row. Shed the ring, keep the
     indicator. The dot and its live pulse both survive, so a signed-in user
     still sees plan status, and the badge keeps its title attribute. The
     pill is last in the priority order at the head of this narrow-screen
     section, and the ring is chrome rather than content, which is why it
     goes before any 44px control is touched. */
  .site-head .tier-badge {
    padding: 0;
    gap: 0;
    border-color: transparent;
    background: none;
  }
  .site-head .tier-label { display: none; }
  .site-head .site-cta { padding: 7px 10px; font-size: 13px; }
}

/* Stacked rows get the floor only where the frame is actually thumbed. Above
   900px the dropdown keeps its denser pointer rhythm: rows are 33px tall
   and 230px+ wide, clearing WCAG 2.5.8 AA on size alone, no exception
   needed. */
@media (max-width: 900px) {
  .site-head .site-drop-list a,
  .site-head .site-drop-list span[aria-current] {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
}

/* FormsPal shared footer. Scope everything under .site-foot (plus html for
   theme variants). Dark-first; properties override the --fp-* variables.
   No JS: the footer is fully static. */

.site-foot {
  background: var(--fp-bg, #0b1f17);
  color: var(--fp-ink, #eaf5ef);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  /* Dimmed text uses mixed colors, never opacity. Opacity dims toward
     whatever is behind: that keeps contrast on a dark backdrop and destroys
     it on a light one, which is how the light theme fell under 4.5:1. */
  --fp-foot-soft: color-mix(in oklab, var(--fp-ink, #eaf5ef) 85%, var(--fp-bg, #0b1f17));
  --fp-foot-label: color-mix(in oklab, var(--fp-ink, #eaf5ef) 78%, var(--fp-bg, #0b1f17));
  --fp-foot-muted: color-mix(in oklab, var(--fp-ink, #eaf5ef) 70%, var(--fp-bg, #0b1f17));
  --fp-foot-link: color-mix(in oklab, var(--fp-green, #0e8a5f) 45%, #fff);
}
html[data-theme="light"] .site-foot {
  /* Fallbacks must flip with the theme too: a property that does not define
     --fp-ink/--fp-bg would otherwise dim light-theme text using the dark
     default ink and land at ~1.5:1. */
  --fp-foot-soft: color-mix(in oklab, var(--fp-ink, #10231a) 85%, var(--fp-bg, #f4faf7));
  --fp-foot-label: color-mix(in oklab, var(--fp-ink, #10231a) 78%, var(--fp-bg, #f4faf7));
  --fp-foot-muted: color-mix(in oklab, var(--fp-ink, #10231a) 70%, var(--fp-bg, #f4faf7));
  --fp-foot-link: color-mix(in oklab, var(--fp-green, #0e8a5f) 72%, #000);
}
html[data-theme="light"] .site-foot {
  background: var(--fp-bg, #f4faf7);
  color: var(--fp-ink, #10231a);
  border-top-color: rgba(0, 0, 0, 0.08);
}

/* Same reasoning as .site-head-inner in header.css: own the box model rather
   than inheriting whatever reset the host page happens to have. */
.site-foot .foot-cols,
.site-foot .foot-bottom-inner,
.site-foot .foot-ghost {
  box-sizing: border-box;
}

.site-foot .foot-cols {
  max-width: 1120px;
  margin: 0 auto;
  padding: 40px 16px 28px;
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr;
  gap: 28px;
}

.site-foot .foot-brand svg { width: 34px; height: 34px; }
.site-foot .foot-brand b {
  display: inline-block;
  margin-left: 8px;
  font-size: 17px;
  vertical-align: super;
}
.site-foot .foot-brand p {
  font-size: 14px;
  line-height: 1.5;
  color: var(--fp-foot-soft);
  margin: 10px 0;
}
.site-foot .foot-brand a {
  color: var(--fp-foot-link);
  text-decoration: none;
  font-size: 14px;
}
.site-foot .foot-addr {
  font-style: normal;
  font-size: 13px;
  color: var(--fp-foot-label);
  margin-top: 12px;
  line-height: 1.5;
}
.site-foot .foot-addr strong { display: block; }

.site-foot .foot-col .foot-col-title {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fp-foot-label);
  margin: 4px 0 12px;
  font-weight: 600;
}
.site-foot .foot-col ul { list-style: none; margin: 0; padding: 0; }
.site-foot .foot-col li { margin: 0 0 9px; }
.site-foot .foot-col a {
  color: var(--fp-foot-soft);
  text-decoration: none;
  font-size: 14px;
}
.site-foot .foot-col a:hover { color: var(--fp-foot-link); }
.site-foot .foot-col span[aria-current] { font-size: 14px; color: var(--fp-foot-muted); }

.site-foot .foot-bottom { border-top: 1px solid rgba(255, 255, 255, 0.08); }
html[data-theme="light"] .site-foot .foot-bottom { border-top-color: rgba(0, 0, 0, 0.08); }
.site-foot .foot-bottom-inner {
  max-width: 1120px;
  margin: 0 auto;
  padding: 14px 16px 18px;
  font-size: 13px;
  color: var(--fp-foot-soft);
}
.site-foot .foot-disclaimer { margin: 0 0 10px; line-height: 1.55; }
.site-foot .foot-legal { display: block; }
.site-foot .foot-legal a {
  color: inherit;
  text-decoration: none;
  margin-right: 14px;
}
.site-foot .foot-legal a:hover { color: var(--fp-foot-link); }

/* The frame owns focus for its own components: a property that ships no
   global focus style (or resets outlines) must not lose the focus ring. */
.site-foot a:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
  border-radius: 4px;
}

@media (max-width: 900px) {
  .site-foot .foot-cols { grid-template-columns: 1fr 1fr; }
  .site-foot .foot-brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) {
  .site-foot .foot-cols { grid-template-columns: 1fr; }
}

/* Match the header's gutter scale. The bar narrows to 14px then 10px so it can
   shed furniture instead of overflowing, but the footer stayed at a flat 16px,
   so footer content sat 2px then 6px inboard of the brand directly above it.
   Two gutters on one page is visible as a broken alignment line on any phone. */
@media (max-width: 560px) {
  .site-foot .foot-cols,
  .site-foot .foot-bottom-inner,
  .site-foot .foot-ghost { padding-inline: 14px; }
}
@media (max-width: 430px) {
  .site-foot .foot-cols,
  .site-foot .foot-bottom-inner,
  .site-foot .foot-ghost { padding-inline: 10px; }
}

/* Design elevation: signature top rule, heading accent ticks, link
   micro-shift, ghost wordmark half-cropped behind the bottom bar. */

.site-foot {
  border-top: 2px solid var(--fp-green, #0e8a5f);
}
.site-foot .foot-col .foot-col-title::before {
  content: "";
  display: block;
  width: 18px;
  height: 2px;
  margin-bottom: 8px;
  background: var(--fp-green, #0e8a5f);
}
.site-foot .foot-col a {
  display: inline-block;
  transition: color var(--fp-dur, 150ms) var(--fp-ease, ease-out), transform var(--fp-dur, 150ms) var(--fp-ease, ease-out);
}
.site-foot .foot-col a:hover {
  transform: translateX(2px);
}
.site-foot .foot-ghost {
  max-width: 1120px;
  margin: 8px auto -0.4em;
  padding: 0 16px;
  font-weight: 800;
  font-size: clamp(40px, 13vw, 190px);
  white-space: nowrap;
  line-height: 1;
  letter-spacing: -0.045em;
  opacity: 0.05;
  user-select: none;
  pointer-events: none;
  overflow-wrap: anywhere;
}
.site-foot .foot-bottom {
  position: relative;
  background: var(--fp-bg, #0b1f17);
}
html[data-theme="light"] .site-foot .foot-bottom {
  background: var(--fp-bg, #f4faf7);
}
@media (prefers-reduced-motion: reduce) {
  .site-foot .foot-col a { transition-duration: 0.01ms; }
}

/* Footer rows are 14px type on a 9px rhythm: a 16.5px box at 25.5px pitch.
   That clears WCAG 2.5.8 AA on the spacing exception but sits well under the
   44px Apple asks for. Raised only where the footer is thumbed; above 900px
   the columns keep their denser desktop rhythm. */
/* A second @media (max-width: 900px) block on purpose: keep it separate
   from the one above. The "design elevation" section earlier in this file
   sets .site-foot .foot-col a { display: inline-block } at equal
   specificity. Merging these rules up there would put them before that one
   in source order, so inline-block would win the cascade and silently
   shrink the 44px row back down to a text-width link. */
@media (max-width: 900px) {
  .site-foot .foot-col li { margin: 0; }
  .site-foot .foot-col a,
  .site-foot .foot-col span[aria-current] {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
  /* Width needs the floor too: these are short words, and a hit region is
     44x44, not 44 tall. Measured at 880px before this rule: Privacy 44.19,
     Cookies 48.64, Terms 37.21, CCPA 34.76, DMCA 38.32. They are inline-flex
     boxes on a line box, so widening them pushes their neighbours along the
     row instead of changing any layout around it. */
  .site-foot .foot-legal a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    margin-right: 18px;
  }
}
/* fp-shared-frame:end */

/* ---------- property-side corrections to the vendored frame ----------
   These belong upstream in digidocuments/formspal-shared-frame. They are
   overrides here so pdf-chat is not left visibly broken while that lands.
   Do NOT fold them into the block above: sync-shared-frame.sh rewrites it. */

/* The frame's CTA focus ring is currentColor, which is white on an orange pill
   sitting on a near-white header: 1.06:1 in light theme. */
.site-head .site-cta:focus-visible {
  outline: 2px solid var(--fp-ink, #10231a);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--fp-bg, #f7f9fb);
}

/* Arrival pill: attribution for extension handoffs (see arrival.js). */
.arrival-pill {
  position: fixed; top: calc(var(--fp-header-h, 64px) + 10px); left: 50%;
  translate: -50% 0; z-index: 60;
  max-width: calc(100vw - 24px);
  display: flex; align-items: center; gap: 8px;
  background: color-mix(in srgb, var(--fp-green, #16a571) 16%, var(--bg, #15181b));
  border: 1px solid color-mix(in srgb, var(--fp-green, #16a571) 50%, transparent);
  color: var(--ink, #e8f5ee);
  border-radius: 999px; padding: 7px 10px 7px 16px;
  font-size: 13px; font-weight: 600;
  opacity: 1; transition: opacity 300ms ease, translate 300ms ease;
}
.arrival-pill-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.arrival-pill-hide { opacity: 0; translate: -50% -8px; pointer-events: none; }
.arrival-pill-x {
  border: 0; background: none; color: inherit; opacity: .7;
  font-size: 15px; line-height: 1; cursor: pointer; padding: 2px 6px;
}
.arrival-pill-x:hover { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .arrival-pill { transition: opacity 300ms ease; }
  .arrival-pill-hide { translate: -50% 0; }
}
