:root {
  --bg: #0f1115;
  --panel: #171a21;
  --panel2: #1d212b;
  --ink: #e6e9ef;
  --mut: #9aa3b2;
  --line: #2a2f3a;
  --accent: #5b8cff;
  --good: #34d399;
  --warn: #fbbf24;
  --bad: #f87171;
  --radius: 10px;
}

/* A manual browser print (Ctrl+P) fallback for any report page -- the real
 * "Download PDF" button (pe_price_results.html) now generates an actual
 * PDF server-side (app/memo_pdf.py, GET /memo/pdf) instead of relying on
 * this, but a user hitting print directly should still get something
 * readable. This app is fixed dark-mode on screen, which would waste ink
 * printed, so print gets its own light palette by redefining the same
 * custom properties, not a parallel set of rules. Interactive chrome
 * (nav, every button, unsaved-status text) is hidden; every
 * .report-section (normally only one visible at a time via the
 * report-nav tab JS) is forced visible so a printed page is the whole
 * document, not whichever tab happened to be open. */
@media print {
  :root {
    --bg: #ffffff; --panel: #ffffff; --panel2: #f7f8fa; --ink: #16202b;
    --mut: #55636d; --line: #cfd8dc;
  }
  .sidebar, .mobile-topbar, .sidebar-backdrop, .back, .btn,
  .memo-input-row, .field-save-status, .report-nav-label { display: none !important; }
  .report-section { display: block !important; }
}

* { box-sizing: border-box; }
/* overflow-x lives on html only -- setting it on body too makes body its
 * own nested scroll container, which breaks position:sticky on .sidebar
 * (its nearest scrolling ancestor becomes body instead of the viewport).
 * The platform-wide background image lives here too, not on body -- html
 * is the real scrolling/root element in this layout, and a fixed
 * background painted on body instead relies on browser propagation
 * behavior that doesn't reliably cover the initial viewport. */
html {
  overflow-x: hidden;
  background:
    linear-gradient(180deg, rgba(15,17,21,.62) 0%, rgba(15,17,21,.55) 100%),
    url("/static/img/hero-bg.svg") center 45% / cover no-repeat fixed,
    var(--bg);
}
html, body { margin: 0; padding: 0; max-width: 100%; }
body {
  color: var(--ink);
  font: 16px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
code { background: var(--panel2); padding: 1px 5px; border-radius: 4px; font-size: .9em; }

/* --- Left sidebar shell ------------------------------------------------- */
.nav-toggle-input { display: none; }
.app-shell { display: flex; align-items: stretch; min-height: 100vh; }
.brand { font-weight: 700; font-size: 1.15rem; color: var(--ink); }
.brand-logo { height: 102px; width: auto; display: block; }

.sidebar {
  width: 240px; flex-shrink: 0; background: var(--panel);
  border-right: 1px solid var(--line); display: flex; flex-direction: column;
  padding: 20px 16px; position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.sidebar-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 22px; }
.sidebar-close, .sidebar-open { display: none; }
.sidebar-nav { display: flex; flex-direction: column; gap: 2px; flex: 1; }
.nav-section-label {
  color: var(--mut); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .04em; font-weight: 700; margin: 16px 0 4px;
}
.nav-section-label:first-child { margin-top: 0; }
.nav-link { color: var(--mut); font-weight: 500; padding: 9px 10px; border-radius: 8px; }
.nav-link:hover { color: var(--ink); background: rgba(255,255,255,.05); text-decoration: none; }
.nav-link.active { color: var(--ink); background: #1a2547; font-weight: 600; }
/* Per-report sidebar sub-navigation (populated by {% block report_nav %} on
 * pricer result pages) -- jumps between report-section panels instead of
 * scrolling a long page. Funds collapse behind a <details> so a many-fund
 * portfolio doesn't blow out the sidebar. */
.report-nav-label { color: var(--mut); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .04em; font-weight: 700; margin: 16px 0 4px; }
.report-nav-label:first-child { margin-top: 0; }
.report-nav-link { color: var(--mut); font-weight: 500; padding: 7px 10px; border-radius: 8px;
  font-size: .88rem; display: block; }
.report-nav-link:hover { color: var(--ink); background: rgba(255,255,255,.05); text-decoration: none; }
button.report-nav-link { width: 100%; text-align: left; background: none; border: none;
  font-family: inherit; cursor: pointer; }
button.report-nav-link small { display: block; }
.report-nav-link.active { color: var(--ink); background: #1a2547; font-weight: 600; }
.report-nav-fund { margin: 0; }
.report-nav-fund > summary { cursor: pointer; padding: 7px 10px; border-radius: 8px;
  color: var(--mut); font-weight: 500; font-size: .88rem; list-style: none;
  display: flex; align-items: center; gap: 6px; }
.report-nav-fund > summary::-webkit-details-marker { display: none; }
.report-nav-fund > summary::before { content: "▸"; font-size: .7rem; transition: transform .12s ease; }
.report-nav-fund[open] > summary::before { transform: rotate(90deg); }
.report-nav-fund > summary:hover { background: rgba(255,255,255,.05); color: var(--ink); }
.report-nav-fund .report-nav-sub { display: flex; flex-direction: column; padding-left: 18px; }
.report-nav-fund .report-nav-link { font-size: .84rem; padding: 6px 10px; }

/* /account/history: search box + pricer/asset-class tree, built to stay
 * navigable at ~100+ rows per account without scrolling the whole page to
 * find one fund. */
.history-search { width: 100%; padding: 12px 14px; margin-bottom: 20px; font-size: .95rem;
  color: var(--ink); background: var(--panel); border: 1px solid var(--line); border-radius: 10px; }
.history-search:focus { outline: none; border-color: var(--accent); }
.history-group { margin-bottom: 14px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--panel); overflow: hidden; }
.history-group > summary { cursor: pointer; padding: 14px 16px; font-weight: 700;
  font-size: 1.02rem; list-style: none; display: flex; align-items: center; gap: 8px; }
.history-group > summary::-webkit-details-marker { display: none; }
.history-group > summary::before { content: "▾"; font-size: .75rem; color: var(--mut); }
.history-group:not([open]) > summary::before { content: "▸"; }
.history-group .count, .history-subgroup .count { color: var(--mut); font-weight: 500; font-size: .85rem; }
.history-group-body { padding: 0 16px 14px; }
.history-subgroup { margin: 4px 0; border-top: 1px solid var(--line); padding-top: 10px; }
.history-subgroup:first-child { border-top: none; padding-top: 0; }
.history-subgroup > summary { cursor: pointer; padding: 6px 0; color: var(--mut); font-weight: 600;
  font-size: .9rem; list-style: none; display: flex; align-items: center; gap: 6px; }
.history-subgroup > summary::-webkit-details-marker { display: none; }
.history-subgroup > summary::before { content: "▸"; font-size: .68rem; transition: transform .12s ease; }
.history-subgroup[open] > summary::before { transform: rotate(90deg); }
.history-table { margin-top: 6px; }
.history-table th, .history-table td { padding: 8px 10px; }

/* Report sections -- only .active is shown; report_nav links toggle it via
 * charts.js instead of a normal in-page anchor jump, so a long report never
 * needs scrolling to reach a given panel. */
.report-section { display: none; }
.report-section.active { display: block; }
.report-section-head { color: var(--mut); font-size: .85rem; margin: 0 0 18px; }
.report-section-head strong { color: var(--ink); }

/* IC-memo AI drafting add-on (pe_price_results.html) -- the notes field and
 * button together span the section's full width (the button doesn't wrap
 * onto its own narrow line), the field itself is transparent (blends with
 * the page instead of sitting as an opaque white box), and the generated
 * result is a <details> disclosure -- same collapsible pattern as
 * .report-nav-fund/.history-group elsewhere, just styled as a full card
 * instead of a compact nav link. */
.memo-input-row { display: flex; gap: 12px; align-items: stretch; width: 100%; }
.memo-notes { flex: 1; width: 100%; box-sizing: border-box; background: transparent;
  color: var(--ink); border: 1px solid var(--line); border-radius: 8px; padding: 10px;
  font-size: 1rem; font-family: inherit; resize: vertical; }
.memo-notes::placeholder { color: var(--mut); }
.memo-notes:focus { outline: none; border-color: var(--accent); }
/* stretch (not flex-start) so the button's height matches the notes
   field's -- align-items: stretch on the row above does this automatically
   as long as nothing here overrides it with its own align-self. */
.memo-input-row .btn { flex-shrink: 0; white-space: nowrap; }
.memo-result { margin-top: 16px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--panel); overflow: hidden; }
.memo-result > summary { cursor: pointer; padding: 12px 16px; font-weight: 600;
  list-style: none; display: flex; align-items: center; gap: 8px; color: var(--mut); }
.memo-result > summary::-webkit-details-marker { display: none; }
.memo-result > summary::before { content: "▾"; font-size: .75rem; transition: transform .12s ease; }
.memo-result:not([open]) > summary::before { content: "▸"; }
.memo-result-body { padding: 0 16px 16px; }
.memo-status { font-weight: 600; }

/* The on-page IC memo's NAV fan chart -- an inline SVG rendered by
 * memo_pdf.fan_chart_svg() from the exact same reportlab Drawing the
 * PDF export draws (see that function's docstring), so this is the
 * literal same chart, not a re-themed copy. reportlab's SVG output
 * carries fixed width/height attributes with a matching viewBox; the
 * CSS below overrides those to make it scale with its container instead
 * of clipping/overflowing on a narrower viewport. */
.memo-fan-chart { max-width: 640px; margin: 10px 0; }
.memo-fan-chart svg { width: 100%; height: auto; display: block; }
.memo-status-ok { color: var(--good); }
.memo-status-warn { color: var(--warn); }

/* IC-memo document schema (EQUISECT_IC_MEMO_SCHEMA_PROPOSAL.pdf) -- every
 * sub-section is tagged with which of the three tiers produced it, reusing
 * this app's existing semantic colors (good/accent/warn) rather than new
 * ones, so the tag reads as consistent with every other status color on
 * the page, not a bolted-on design system. */
.tier-pill { display: inline-block; font-size: .68rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .03em; padding: 2px 8px;
  border-radius: 999px; margin-left: 8px; vertical-align: middle; white-space: nowrap; }
.tier-pill.tier-1 { background: rgba(52, 211, 153, .15); color: var(--good); }
.tier-pill.tier-2 { background: rgba(91, 140, 255, .15); color: var(--accent); }
.tier-pill.tier-3 { background: rgba(251, 191, 36, .15); color: var(--warn); }
.tier-pill.tier-na { background: rgba(154, 163, 178, .15); color: var(--mut); }

.memo-field-row { display: flex; flex-direction: column; gap: 6px; margin: 10px 0; }
.memo-field-row select, .memo-field-textarea { width: 100%; box-sizing: border-box;
  background: transparent; color: var(--ink); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px; font-size: 1rem; font-family: inherit; resize: vertical; }
.memo-field-row select:focus, .memo-field-textarea:focus { outline: none; border-color: var(--accent); }
.memo-field-textarea::placeholder { color: var(--mut); }
.field-save-status { font-size: .8rem; color: var(--mut); min-height: 1.2em; margin: 2px 0 0; }
.field-save-status.saved { color: var(--good); }
.field-save-status.err { color: var(--bad); }
.memo-subhead { margin-top: 26px; }

/* Tier-3 (analyst-entered) memo sections are individually collapsible --
 * same disclosure-triangle mechanics as .memo-result above, but the
 * summary carries the section's own heading (tier pill, completion tick)
 * rather than a status line, so it needs its own font-size/weight since
 * <summary> has no built-in heading styling the way <h3> does. Starts
 * open (see the `open` attribute in the templates) so nothing looks
 * hidden on first load -- collapsing is for tidying up sections you've
 * already reviewed, not for hiding required fields by default. */
.memo-tier3-section { margin-top: 26px; }
.memo-tier3-section > summary.memo-subhead { margin-top: 0; cursor: pointer;
  list-style: none; user-select: none; font-size: 1.17em; font-weight: bold;
  display: flex; align-items: center; gap: 6px; }
.memo-tier3-section > summary.memo-subhead::-webkit-details-marker { display: none; }
.memo-tier3-section > summary.memo-subhead::before { content: "▾"; font-size: .7rem;
  color: var(--mut); flex-shrink: 0; }
.memo-tier3-section:not([open]) > summary.memo-subhead::before { content: "▸"; }
.memo-tier3-body { margin-top: 8px; }

/* Fill-state indicator next to each Tier-3 summary -- same checkmark/
 * "not yet provided" convention as memo_pdf.py's _FILLED_TICK/
 * _UNFILLED_TICK, so a collapsed section's status is visible without
 * expanding it. Normal (non-bold) weight, unlike the summary text
 * itself, so it doesn't compete with the heading for attention. */
.tier-fill-tick { font-size: .78rem; font-weight: 700; color: var(--good); }
.tier-fill-tick.unfilled { color: var(--mut); font-weight: 400; text-transform: none;
  letter-spacing: normal; }

.sidebar-foot { border-top: 1px solid var(--line); padding-top: 14px; margin-top: 14px; }
.nav-user { color: var(--mut); font-size: .82rem; opacity: .85; margin: 0 0 10px; }
.nav-plan { color: var(--ink); opacity: 1; }
.nav-cta { background: var(--accent); color: #0b1020 !important; padding: 8px 14px;
  border-radius: 8px; font-weight: 600; display: inline-block; }
.nav-cta:hover { text-decoration: none; }

/* First-visit empty state for the sidebar's "Recent" slot -- a brand-new
   account with nothing priced yet gets a one-line nudge instead of the
   section just silently vanishing. */
.nav-empty-hint p { color: var(--mut); font-size: .84rem; margin: 0 0 10px; padding: 0 10px; }
.nav-empty-hint .btn { width: 100%; box-sizing: border-box; text-align: center; }

/* First-visit router card on the three pricer pages -- only rendered when
   the account has priced nothing yet (main.py's _first_visit_ctx), so a
   new user who landed on the "wrong" pricer for their need can redirect
   in one click instead of discovering the other two tools themselves. */
.first-visit-router { background: var(--panel2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 18px; margin: 0 0 20px; }
.router-label { color: var(--mut); font-size: .88rem; margin: 0 0 12px; }
.router-options { display: flex; gap: 12px; flex-wrap: wrap; }
.router-opt { flex: 1 1 220px; display: flex; flex-direction: column; gap: 3px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 14px; color: var(--ink); }
.router-opt:hover { border-color: var(--accent); text-decoration: none; }
.router-opt strong { font-size: .92rem; }
.router-opt span { color: var(--mut); font-size: .82rem; }

.sidebar-backdrop { display: none; }
.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.mobile-topbar { display: none; }

@media (max-width: 860px) {
  .sidebar {
    position: fixed; top: 0; left: 0; height: 100vh; z-index: 80;
    transform: translateX(-100%); transition: transform .18s ease;
    box-shadow: 0 0 40px rgba(0,0,0,.5);
  }
  .nav-toggle-input:checked ~ .app-shell .sidebar { transform: translateX(0); }
  .sidebar-close { display: inline-block; cursor: pointer; color: var(--mut); font-size: 1.1rem; }
  .nav-toggle-input:checked ~ .app-shell .sidebar-backdrop {
    display: block; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 70;
  }
  .mobile-topbar {
    display: flex; align-items: center; gap: 14px; padding: 12px 16px;
    border-bottom: 1px solid var(--line); position: sticky; top: 0;
    background: rgba(15,17,21,.92); backdrop-filter: blur(6px); z-index: 40;
  }
  .sidebar-open { display: inline-block; cursor: pointer; font-size: 1.3rem; color: var(--ink); }
}

/* whitepapers + builder + forms */
.paper-list { list-style: none; padding: 0; }
.paper-list li { padding: 18px 0; border-bottom: 1px solid var(--line); }
.paper-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; }
.paper-head a { font-size: 1.2rem; font-weight: 600; }
.ver { font-size: .72rem; font-weight: 700; color: var(--accent); background: #1a2547; padding: 2px 8px; border-radius: 20px; }
.paper-list .summary, .paper-list .meta { color: var(--mut); margin: 6px 0 0; font-size: .92rem; }
.whitepaper .paper-banner { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin: 6px 0 14px; }
.whitepaper .abstract { background: var(--panel); border-left: 3px solid var(--accent);
  border-radius: 6px; padding: 14px 16px; color: var(--mut); margin-bottom: 20px; font-size: .95rem; }

/* whitepaper body helpers — reusable exec tiles, callouts, exhibits, flow (dark theme) */
.post-body .wp-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 18px 0; }
.post-body .wp-tile { border: 1px solid var(--line); border-top: 3px solid var(--accent);
  border-radius: 8px; padding: 12px 14px; background: var(--panel); }
.post-body .wp-tile .n { font-size: 1.7rem; font-weight: 700; color: var(--ink); line-height: 1.1; }
.post-body .wp-tile .n.sm { font-size: 1.25rem; }
.post-body .wp-tile .l { font-size: .78rem; color: var(--mut); margin-top: 6px; line-height: 1.35; }
.post-body .wp-callout { background: var(--panel); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: 8px; padding: 14px 16px; margin: 16px 0; }
.post-body .wp-callout.good { border-left-color: var(--good); }
.post-body .wp-callout.warn { border-left-color: var(--warn); }
.post-body .wp-callout.bad  { border-left-color: var(--bad); }
.post-body .wp-callout p:last-child { margin-bottom: 0; }
.post-body .wp-kicker { font-size: .7rem; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--mut); font-weight: 700; margin-bottom: 6px; }
.post-body .wp-exh { border: 1px solid var(--line); border-radius: 8px; padding: 14px 16px 10px;
  margin: 18px 0; background: var(--panel); }
.post-body .wp-exh .cap { font-size: .8rem; color: var(--mut); margin-top: 10px; line-height: 1.4; }
.post-body .wp-exh .cap b { color: var(--ink); }
.post-body .wp-flow { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; margin: 14px 0; }
.post-body .wp-flow .step { border: 1px solid var(--line); border-right: 0; padding: 10px 11px; background: var(--panel); }
.post-body .wp-flow .step:last-child { border-right: 1px solid var(--line); background: #12241c; border-color: #1f3d2e; }
.post-body .wp-flow .step .k { font-size: .66rem; letter-spacing: .8px; text-transform: uppercase; color: var(--mut); }
.post-body .wp-flow .step .v { color: var(--ink); font-weight: 600; margin-top: 4px; font-size: .84rem; line-height: 1.2; }
.post-body .wp-flow .step:last-child .v { color: var(--good); }
.post-body .good { color: var(--good); font-weight: 700; }
.post-body .bad { color: var(--bad); font-weight: 700; }
.post-body .warnc { color: var(--warn); font-weight: 700; }
@media (max-width: 640px) {
  .post-body .wp-tiles { grid-template-columns: repeat(2, 1fr); }
  .post-body .wp-flow { grid-template-columns: 1fr; }
  .post-body .wp-flow .step { border-right: 1px solid var(--line); border-bottom: 0; }
}
.build-form fieldset { border: 1px solid var(--line); border-radius: 8px; padding: 14px 16px; margin: 0; }
.build-form legend { padding: 0 6px; color: var(--mut); font-weight: 600; }
.weight-row { display: grid; grid-template-columns: 1fr 90px; align-items: center; gap: 10px; margin: 8px 0; }
.weight-row input { width: 100%; }
.build-form .hint, .format-help .hint { color: var(--mut); font-size: .82rem; margin: 8px 0 0; }

/* explainers (builder + verifier descriptions) */
.explainer { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px 20px; margin: 8px 0 26px; }
.explainer h3 { margin: 0 0 8px; }
.explainer p { color: var(--mut); margin: 8px 0; font-size: .95rem; }
.explain-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 22px; margin: 12px 0; }
.explain-grid div { color: var(--mut); font-size: .9rem; }
.explain-grid strong { color: var(--ink); }
.explainer .hint { color: var(--mut); font-size: .85rem; }

/* Inputs -> Model -> Outputs schematic (public per-model docs, /docs/model-*) */
.model-diagram { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr;
  align-items: stretch; gap: 0; margin: 20px 0 28px; }
.model-diagram .dbox { background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 18px; }
.model-diagram .dbox h4 { margin: 0 0 8px; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--mut); }
.model-diagram .dbox.inputs { border-left: 3px solid var(--good); }
.model-diagram .dbox.model { border-left: 3px solid var(--accent); }
.model-diagram .dbox.outputs { border-left: 3px solid var(--warn); }
.model-diagram .dbox ul { margin: 0; padding-left: 18px; color: var(--mut); font-size: .88rem; }
.model-diagram .dbox li { margin-bottom: 4px; }
.model-diagram .dbox .kind { color: var(--ink); font-weight: 700; margin-bottom: 6px; }
.model-diagram .dbox p { color: var(--mut); font-size: .88rem; margin: 0; }
.model-diagram .darrow { display: flex; align-items: center; justify-content: center;
  color: var(--mut); font-size: 1.3rem; padding: 0 6px; }
.model-badges { margin: 10px 0 4px; }
.model-badges .tag { margin-right: 6px; }
@media (max-width: 720px) {
  .model-diagram { grid-template-columns: 1fr; }
  .model-diagram .darrow { transform: rotate(90deg); padding: 6px 0; }
}

/* pricing / billing */
.pricing { display: flex; justify-content: center; margin: 10px 0; }
.pricing.two { gap: 22px; flex-wrap: wrap; align-items: flex-start; }
.pricing .price-card { max-width: 420px; }
.price-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 26px 28px; max-width: 440px; width: 100%; }
.price-card.focus { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.price-card .price { font-size: 2rem; font-weight: 700; margin: 12px 0 6px; }
/* Deterministic step-down (4 -> 2 -> 1) instead of auto-fit: auto-fit lets a
   lone wrapped card (e.g. a 4th card alone on row 2) stretch to fill the
   whole row width, so cards end up visibly different sizes depending on
   how many landed in their row -- explicit breakpoints keep every card the
   same size within a row at every width. No align-items override -- the
   grid default (stretch) makes every card in a row match the tallest one's
   height, same as .analytics/.acard below. */
.price-grid { display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 16px; margin: 10px 0; }
.price-grid .price-card { max-width: none; padding: 20px 18px;
  display: flex; flex-direction: column; }
.price-grid .price { font-size: 1.4rem; }
@media (max-width: 1100px) {
  .price-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 860px) {
  .price-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
  .price-grid { grid-template-columns: 1fr; }
}
.price-blurb { color: var(--mut); margin: 0 0 16px; font-size: .95rem; }
.headline.compact { padding: 10px 14px; font-size: .98rem; margin: 0 0 12px; }
.price-feats { list-style: none; padding: 0; margin: 0 0 20px; }
/* Feature lists vary in length card to card; letting the list (not the
   card) absorb the extra height keeps every card's CTA lined up along the
   same bottom edge instead of floating at a different height per card. */
.price-grid .price-feats { flex: 1; }
.price-feats li { padding: 7px 0 7px 26px; position: relative; color: var(--mut); }
.price-feats li::before { content: "✓"; color: var(--good); position: absolute; left: 0; font-weight: 700; }
.inline-form { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }

/* portfolio holdings */
.holdings-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin: 12px 0; }
.hold-long { color: var(--good); margin: 0 0 6px; }
.hold-short { color: var(--bad); margin: 0 0 6px; }
.hold-list { list-style: none; padding: 0; margin: 0; }
.hold-list li { display: flex; justify-content: space-between; padding: 5px 10px;
  border-bottom: 1px solid var(--line); font-size: .92rem; }
.hold-list li span { color: var(--mut); font-variant-numeric: tabular-nums; }
@media (max-width: 680px) { .holdings-grid { grid-template-columns: 1fr; } }

/* factor catalog cards */
.factor-cards { display: grid; gap: 14px; margin: 8px 0 18px; }
.factor-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.fc-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.fc-head h3 { margin: 0; }
.fc-tag { font-size: .78rem; color: var(--accent); background: #1a2547; padding: 3px 9px; border-radius: 20px; }
.fc-badge { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  color: var(--good); background: #14321f; padding: 3px 8px; border-radius: 20px; }
.fc-metrics { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 8px 0; color: var(--mut); font-size: .9rem; }
.fc-metrics strong { color: var(--ink); }
.fc-metrics .ok strong { color: var(--good); }
.fc-metrics .warn strong { color: var(--warn); }
.factor-card p { color: var(--mut); margin: 6px 0 0; font-size: .95rem; }

@media (max-width: 680px) { .explain-grid { grid-template-columns: 1fr; } }

.container { max-width: 1280px; margin: 0 auto; padding: 40px 24px 80px; }
/* Account page: uses the full available width by default (tables, forms,
   and history groups benefit from the extra room) rather than the
   1280px cap most content/marketing pages use for readable line length. */
.container.container-wide { max-width: none; }

.hero h1 { font-size: 2.4rem; line-height: 1.15; margin: 0 0 14px; }
.lede { color: var(--mut); font-size: 1.1rem; }
.cta-row { margin-top: 26px; display: flex; gap: 12px; flex-wrap: wrap; }
/* Real (not fabricated) proof point repeated right under the primary CTA --
   same warehouse stats shown lower on the page, borrowed for the
   first-look moment instead of making a visitor scroll to find them. */
.hero-stat { color: var(--mut); font-size: .85rem; margin: 16px 0 0; }

/* Homepage interactive demo -- calls the real pricing engine (POST
   /api/demo-price, unauthenticated, IP rate-limited) so a visitor sees the
   product move before ever signing in. Sits right after the hero, not
   buried lower on the page, since first-look conversion research is clear
   that an interactive demo here converts substantially better than a
   static screenshot. */
.demo-widget { background: var(--panel); border: 1px solid var(--accent);
  border-radius: var(--radius); padding: 26px 28px; margin: 8px 0 4px; }
.demo-widget-head p { color: var(--mut); font-size: .92rem; margin: 10px 0 0; max-width: 68ch; }
.demo-widget-head h2 { margin: 0; font-size: 1.3rem; }
.demo-widget-body { margin: 22px 0 20px; }
.demo-widget-body label { display: flex; justify-content: space-between;
  color: var(--mut); font-size: .88rem; font-weight: 600; margin-bottom: 8px; }
.demo-widget-body label span { color: var(--ink); font-variant-numeric: tabular-nums; }
.demo-widget-body input[type="range"] { width: 100%; accent-color: var(--accent); }
.demo-result { display: flex; gap: 32px; margin-top: 22px; flex-wrap: wrap; }
.demo-result-main .num { display: block; font-size: 2.2rem; font-weight: 700;
  font-variant-numeric: tabular-nums; line-height: 1.1; color: var(--ink); }
.demo-result-band #demo-band { display: block; font-size: 1.5rem; font-weight: 700;
  font-variant-numeric: tabular-nums; line-height: 1.1; color: var(--mut); }
.demo-result .lbl { display: block; color: var(--mut); font-size: .82rem; margin-top: 4px; }

.eyebrow { display: block; color: var(--accent); font-size: .8rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; margin: 0 0 10px; }

.section-head { margin: 56px 0 20px; }
.section-head h2 { margin: 0 0 8px; font-size: 1.5rem; }
.section-head p { color: var(--mut); margin: 0; }

/* Landing-page-only single-row variants of the shared .panel-stats grid
 * (used elsewhere with auto-fit wrapping that's fine at 5+ cards, but
 * leaves an awkward 1-card second row at exactly 3 or 4). */
.panel-stats.cols-3 { grid-template-columns: repeat(3, 1fr); }
.panel-stats.cols-4 { grid-template-columns: repeat(4, 1fr); }

.roi-band { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 24px; margin: 20px 0; }
.roi-compare { display: flex; align-items: center; justify-content: space-evenly; gap: 20px; flex-wrap: wrap; }
.roi-figure { text-align: center; }
.roi-figure .num { font-size: 2.6rem; font-weight: 700; line-height: 1; }
.roi-figure .lbl { color: var(--mut); font-size: .85rem; margin-top: 6px; }
.roi-figure.cost .num { color: var(--ink); }
.roi-figure.save .num { color: var(--good); }
.roi-vs { color: var(--mut); font-size: 1.3rem; font-weight: 700; }

@media (max-width: 860px) {
  .panel-stats.cols-3, .panel-stats.cols-4 { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 520px) {
  .panel-stats.cols-3, .panel-stats.cols-4 { grid-template-columns: 1fr; }
}

.btn {
  display: inline-block; padding: 11px 18px; border-radius: var(--radius);
  border: 1px solid var(--line); color: var(--ink); background: var(--panel);
  font-weight: 600; cursor: pointer;
}
.btn:hover { text-decoration: none; border-color: var(--accent); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #0b1020; }
.btn.danger { background: var(--bad); border-color: var(--bad); color: #2a0a0a; }
.btn.small { padding: 5px 10px; font-size: .82rem; font-weight: 500; }
.btn.large { padding: 16px 26px; font-size: 1.05rem; white-space: nowrap; }

/* Mid-page free-trial conversion banner -- a stronger, more developed
   pitch than the compact .alert.good nudge right under the hero, placed
   after the credibility-building sections (problems/process/stats/who
   it's for) rather than competing with that first, lighter-touch nudge. */
.trial-band { display: flex; align-items: center; justify-content: space-between; gap: 28px;
  flex-wrap: wrap; background: var(--panel); border: 1px solid var(--accent); border-radius: var(--radius);
  padding: 28px 32px; margin: 8px 0 4px; }
.trial-copy h3 { margin: 0 0 12px; font-size: 1.15rem; }
.trial-facts { list-style: none; padding: 0; margin: 0; }
.trial-facts li { padding: 5px 0 5px 26px; position: relative; color: var(--mut); font-size: .92rem; }
.trial-facts li::before { content: "✓"; color: var(--good); position: absolute; left: 0; font-weight: 700; }
@media (max-width: 680px) { .trial-band { padding: 22px; } }

.key-form { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 14px; }
.key-form input { flex: 1; max-width: 340px; padding: 10px 12px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--panel); color: var(--ink); }
.key-reveal { background: var(--panel); border: 1px solid var(--line); border-radius: 6px;
  padding: 10px 12px; overflow-x: auto; font-size: .85rem; margin: 8px 0; }

.code-block { background: var(--panel); border: 1px solid var(--line); border-radius: 6px;
  padding: 14px 16px; overflow-x: auto; font-size: .85rem; line-height: 1.5;
  white-space: pre; margin: 10px 0 20px; }

.ladder { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 48px 0; }
.ladder.four { grid-template-columns: repeat(4, 1fr); }
.rung { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; }
.rung h3 { margin: 10px 0 6px; }
.rung p { color: var(--mut); font-size: .95rem; margin: 0; }

.tag { font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: 3px 8px; border-radius: 20px; }
.tag.free { background: #14321f; color: var(--good); }
.tag.paid { background: #1a2547; color: var(--accent); }
.tag.info { background: var(--panel2); color: var(--mut); }
.tag.soon { background: #322a12; color: var(--warn); }

.latest { margin-top: 40px; }
.post-list { list-style: none; padding: 0; }
.post-list li { padding: 16px 0; border-bottom: 1px solid var(--line); }
.post-list a { font-size: 1.05rem; font-weight: 600; }
.post-list.big a { font-size: 1.25rem; }
.post-list .date { color: var(--mut); font-size: .82rem; margin-left: 10px; }
.post-list .summary { color: var(--mut); margin: 6px 0 0; font-size: .95rem; }

.page-head h1 { font-size: 1.9rem; margin: 0 0 10px; }
.page-head h2 { font-size: 1.5rem; margin: 0 0 10px; }
.meta { color: var(--mut); font-size: .9rem; }

.page-head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.page-head-row h1 { margin: 0 0 10px; }
.export-row { display: flex; justify-content: flex-end; margin: 6px 0 0; }
.btn.export-csv { padding: 12px 22px; font-size: .95rem; }

.post-body { margin-top: 20px; }
.post-body h1 { font-size: 1.8rem; }
.post-body h2 { margin-top: 1.6em; border-bottom: 1px solid var(--line); padding-bottom: .3em; }
.post-body table { border-collapse: collapse; width: 100%; }
.post-body th, .post-body td { border: 1px solid var(--line); padding: 8px 10px; text-align: left; }
.post .back, .legend .back { color: var(--mut); }
.post .date { color: var(--mut); font-size: .85rem; }

.validate-form { background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 24px; display: grid; gap: 18px; max-width: 520px; }
.validate-form label { display: grid; gap: 6px; font-weight: 600; }
.validate-form label small { color: var(--mut); font-weight: 400; }
.validate-form input, .validate-form select, .validate-form textarea {
  background: var(--panel2); border: 1px solid var(--line); color: var(--ink);
  padding: 10px; border-radius: 8px; font-size: 1rem; font-family: inherit; resize: vertical; }
/* Builder / analysis-tool forms span the full page width; their fields and
   dropdowns fill it (matches the page text above them). Compact .validate-form
   forms — login, verify, single-file uploads — stay narrow on purpose. */
.validate-form.build-form { max-width: none; }
.validate-form.build-form select,
.validate-form.build-form input[type="text"],
.validate-form.build-form input[type="number"],
.validate-form.build-form input[type="file"],
.validate-form.build-form input[type="email"] { width: 100%; box-sizing: border-box; }
.format-help { margin-top: 28px; color: var(--mut); }
.format-help li { margin: 6px 0; }

.alert { background: #3a1b1b; border: 1px solid var(--bad); color: #fecaca;
  padding: 12px 16px; border-radius: 8px; margin-bottom: 18px; }

.headline { padding: 18px 20px; border-radius: var(--radius); font-size: 1.1rem;
  font-weight: 600; margin: 18px 0 26px; border: 1px solid var(--line); }
.headline.good { background: #0f2a1e; border-color: var(--good); color: #bbf7d0; }
.headline.warn { background: #2b2410; border-color: var(--warn); color: #fde68a; }
.headline.bad  { background: #2c1414; border-color: var(--bad);  color: #fecaca; }

/* Grid, not flex -- same treatment as .analytics/.acard below: every stat in
   a row stretches to the same width and height (a flex row instead sized
   each card to its own label length, so a card with a long two-line label
   sat next to a much narrower one). */
.panel-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px; margin-bottom: 24px; }
.stat { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px 22px; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.stat .num { font-size: 2rem; font-weight: 700; line-height: 1.1; }
.stat .lbl { color: var(--mut); font-size: .85rem; }
.stat.good .num { color: var(--good); }
.stat.bad .num { color: var(--bad); }
.stat.muted .num { color: var(--mut); }
.stat.warn .num { color: var(--warn); }

table.results { width: 100%; border-collapse: collapse; font-size: .92rem; }
table.results th, table.results td { padding: 9px 10px; border-bottom: 1px solid var(--line); text-align: right; }
table.results th:first-child, table.results td.name { text-align: left; }
table.results th { color: var(--mut); font-weight: 600; }
td.ci.ok { color: var(--good); }
td.ci.warn { color: var(--warn); }
td.ok, td.good { color: var(--good); }
td.warn { color: var(--warn); }
td.bad { color: var(--bad); }
.reasons-row .reasons { text-align: left; color: var(--mut); font-size: .82rem; padding-top: 0; }

.badge { padding: 3px 9px; border-radius: 20px; font-size: .78rem; font-weight: 700; white-space: nowrap; }
.badge.survives { background: #14321f; color: var(--good); }
.badge.likely-overfit { background: #2c1414; color: var(--bad); }
.badge.inconclusive, .badge.insufficient-data { background: #2a2f3a; color: var(--mut); }

.notes, .legend { margin-top: 30px; color: var(--mut); }
.notes ul, .legend ul { padding-left: 18px; }
.legend strong { color: var(--ink); }

.audit-footer { margin-top: 30px; padding: 16px 20px; border: 1px solid var(--line);
  border-radius: 8px; color: var(--mut); font-size: .85rem; }
.audit-footer h3 { margin: 0 0 10px; font-size: .78rem; text-transform: uppercase;
  letter-spacing: .04em; color: var(--mut); }
.audit-footer ul { padding-left: 18px; margin: 0; }
.audit-footer li { margin-bottom: 6px; }
.audit-footer strong { color: var(--ink); }

.data-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 30px 0; }
.data-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }

/* Legal pages (Terms & Conditions / Disclaimer) */
.legal { max-width: 820px; }
.legal h2 { font-size: 1.12rem; margin: 30px 0 8px; border-top: 1px solid var(--line, #2a2f3a); padding-top: 20px; }
.legal p, .legal li { color: var(--mut); line-height: 1.65; font-size: .95rem; }
.legal ul { margin: 8px 0 8px 1.1rem; }
.legal li { margin: 6px 0; }
.legal .legal-callout { border: 1px solid var(--accent, #d9534f); border-radius: 10px;
  padding: 18px 22px; margin: 26px 0; background: rgba(217,83,79,.06); }
.legal .legal-callout h2 { border-top: none; padding-top: 0; margin-top: 0; color: var(--ink); }
.footer-links { margin-top: 8px; font-size: .85rem; }
.footer-links a { color: var(--mut); }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; }
.card h3 { margin-top: 0; }
.card p { color: var(--mut); font-size: .95rem; }
.gate { background: var(--panel2); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 24px; text-align: center; margin-top: 24px; }
.gate .btn { margin: 10px 0; }

/* charts + figures */
.chart-fig, .chart-host { background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px 18px; margin: 22px 0; overflow-x: auto; }
.chart-host[data-chart="fan"] { min-height: 340px; }
.chart-host[data-chart="sensitivity"] { min-height: 260px; }

/* climate section */
.climate-strip { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 18px; background: linear-gradient(120deg, #1a2230, #1d2433);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 22px 24px; margin: 40px 0; }
.climate-strip h3 { margin: 8px 0 4px; }
.climate-strip p { color: var(--mut); margin: 0; max-width: 60ch; font-size: .95rem; }
.climate-strip .btn { white-space: nowrap; }

/* "Built to survive scrutiny" -- data-handling / accountability facts,
   plainer and lower-key than the .problem-grid cards below it (no border
   accent, no CTA) since this is reassurance, not a pitch. */
.trust-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 8px 0 4px; }
.trust-item h3 { margin: 0 0 8px; font-size: .98rem; }
.trust-item p { color: var(--mut); font-size: .88rem; margin: 0; line-height: 1.55; }
@media (max-width: 860px) { .trust-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .trust-grid { grid-template-columns: 1fr; } }

/* Legend for the illustrative family-office cashflow chart (.chart-fig
   below already provides the panel/border/caption styling shared with the
   real product screenshots). */
.chart-legend { display: flex; gap: 20px; margin-top: 10px; font-size: .85rem; color: var(--mut); }
.legend-item { display: inline-flex; align-items: center; gap: 7px; }
.legend-swatch { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }

/* "Problems we solve" -- landing-page service cards, framed as the
   question a real desk asks rather than a feature name. */
.problem-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 8px 0 4px; }
.problem-card { display: flex; flex-direction: column; height: 100%; background: var(--panel);
  border: 1px solid var(--line); border-left: 3px solid var(--accent); border-radius: var(--radius);
  padding: 22px; color: var(--ink); }
.problem-card:hover { border-color: var(--accent); text-decoration: none; }
.problem-tag { display: inline-block; color: var(--accent); font-size: .72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: 10px; }
.problem-card h3 { margin: 0 0 10px; font-size: 1.08rem; line-height: 1.35; font-style: italic; color: var(--ink); }
.problem-card p { color: var(--mut); font-size: .92rem; margin: 0 0 14px; flex: 1; }
.problem-go { color: var(--accent); font-weight: 600; font-size: .9rem; margin-top: auto; }
@media (max-width: 860px) { .problem-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .problem-grid { grid-template-columns: 1fr; } }

/* "How it works" -- numbered process flow. Desktop connects steps with a
   thin rule across the row (::before on every step but the first); the
   number itself carries the sequence, so nothing breaks if it wraps. */
.process-steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 8px 0 4px; }
.process-step { position: relative; padding: 0 18px 0 0; }
.process-step:not(:first-child)::before {
  content: ""; position: absolute; top: 22px; left: -8px; width: 16px; height: 1px;
  background: var(--line);
}
.step-num { display: block; font-size: 1.6rem; font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums; margin-bottom: 10px; }
.process-step h3 { margin: 0 0 8px; font-size: 1.02rem; }
.process-step p { color: var(--mut); font-size: .88rem; margin: 0; }
@media (max-width: 860px) {
  .process-steps { grid-template-columns: 1fr 1fr; }
  .process-step:nth-child(3)::before, .process-step:nth-child(1)::before { display: none; }
}
@media (max-width: 560px) {
  .process-steps { grid-template-columns: 1fr; }
  .process-step::before { display: none !important; }
}

/* "Who it's for" -- audience segmentation cards. */
.segment-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 8px 0 4px; }
.segment-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 22px; }
.segment-card h3 { margin: 0 0 12px; font-size: 1.05rem; }
.segment-list { list-style: none; padding: 0; margin: 0; }
.segment-list li { padding: 7px 0 7px 26px; position: relative; color: var(--mut); font-size: .92rem; }
.segment-list li::before { content: "→"; color: var(--accent); position: absolute; left: 0; font-weight: 700; }
@media (max-width: 860px) { .segment-grid { grid-template-columns: 1fr; } }

.model-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: start; }
.model-card { display: flex; flex-direction: column; height: 100%; background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; color: var(--ink); }
.model-card:hover { border-color: var(--accent); text-decoration: none; }
.model-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.model-head h3 { margin: 0; }
.model-metric { color: var(--mut); font-size: .95rem; margin: 8px 0 14px; }
.model-facts { list-style: none; display: flex; flex-direction: column; gap: 6px; padding: 0; margin: 0 0 14px;
  color: var(--mut); font-size: .9rem; flex: 1; }
.model-facts strong { color: var(--ink); }
.model-go { color: var(--accent); font-weight: 600; font-size: .92rem; margin-top: auto; }

@media (max-width: 860px) {
  .model-list { grid-template-columns: 1fr; }
}
.soon-card .perils { color: var(--accent); font-size: .85rem; margin: 4px 0 8px; letter-spacing: .02em; }
.alert.info { background: #16233a; border-color: var(--accent); color: #cfe0ff; }
.alert.warn { background: #2b2410; border-color: var(--warn); color: #fde68a; }
.alert.good { background: #16241c; border-color: var(--good); color: #bbf7d0; }
hr.rule { border: 0; border-top: 1px solid var(--line, #2a2f3a); margin: 36px 0 8px; }
table.climate td { white-space: nowrap; }

.site-footer { border-top: 1px solid var(--line); padding: 24px; text-align: center; color: var(--mut); font-size: .85rem; }
/* Inline secondary text (a timestamp or tag next to a table row, a fund's
   sub-label under its name) -- shares .fine's muted, small-print look but
   is a <small>/<span>, not a caption paragraph, so it's untouched by the
   block-level caption rule below. */
.fine { font-size: .78rem; opacity: .8; }

/* Unified caption format for every block-level explanatory note under a
   chart, table, or section -- figure captions, "illustrative, not a
   guarantee" asides, methodology footnotes. Left-aligned at full content
   width: centered, narrow (70ch) text reads fine for one short line but
   hurts scanability for anything longer, so this is now the one shared
   look everywhere, rather than three slightly different treatments. The
   persistent site footer is the deliberate exception below -- sitewide
   legal chrome, not page content, kept centered by convention. */
p.fine, .chart-cap, .chart-fig figcaption {
  color: var(--mut); font-size: .85rem; line-height: 1.55; opacity: .85;
  margin: 10px 0 0; max-width: none; text-align: left;
}
.chart-cap { margin-top: -6px; padding-left: 2px; }
.chart-cap strong, p.fine strong { color: var(--ink); font-weight: 600; }
/* .fine.left is now a no-op alias -- left-aligned, full-width is p.fine's
 * own default -- kept so existing templates using the modifier still work. */
.fine.left { margin-left: 0; margin-right: 0; text-align: left; }

.site-footer p.fine { max-width: 70ch; margin: 6px auto 0; text-align: center; opacity: .8; }

.contact-form { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; max-width: 380px; }
.contact-form input, .contact-form textarea {
  padding: 9px 11px; border-radius: var(--radius); border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); font: inherit; resize: vertical;
}
.contact-form button { align-self: flex-start; }
.checkbox-row { display: flex; align-items: flex-start; gap: 8px; color: var(--mut);
  font-size: .88rem; line-height: 1.4; margin: 2px 0; }
.checkbox-row input { width: auto; margin-top: 3px; flex-shrink: 0; }

@media (max-width: 680px) {
  .ladder, .data-grid, .data-grid.cols-4 { grid-template-columns: 1fr; }
  table.results { font-size: .82rem; }
  /* Wide tables (sensitivity grids, cashflow calendars, API-key lists) get
     their own horizontal scrollbar instead of blowing out the page width. */
  table.results, .post-body table {
    display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap;
  }
}

@media (max-width: 560px) {
  .mobile-topbar { padding: 12px 16px; }
  .container { padding: 24px 16px 60px; }
  .price-card, .stat, .acard, .factor-card, .validate-form { padding: 16px; }
}

/* Deal-analytics cards -- shared by all three PE pricers */
.analytics{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin:6px 0 4px}
.acard{border:1px solid var(--line);border-left-width:4px;border-radius:10px;
  padding:13px 15px;background:var(--panel2)}
.acard .ac-h{font-size:12px;letter-spacing:.04em;text-transform:uppercase;color:var(--mut);font-weight:600}
.acard .ac-n{font-size:1.7rem;font-weight:680;line-height:1.15;margin:3px 0 2px;color:var(--ink);font-variant-numeric:tabular-nums}
.acard .ac-r{font-size:12.5px;color:var(--mut);line-height:1.45}
.acard .ac-r strong{color:var(--ink)}
.acard.t-good{border-left-color:var(--good)}
.acard.t-warn{border-left-color:var(--warn)}
.acard.t-bad{border-left-color:var(--bad)}
.acard.t-muted{border-left-color:var(--mut)}
