/* ============================================================
   Release-announcement visual exploration — shared scaffolding
   Tokens, scroll-stage mechanics, and the content skeleton.
   Art direction lives in each direction file, never here.
   Palette 008 "Ink & Lime".
   ============================================================ */

:root {
  --ink:            #0c0c0e;
  --ink-on-dark:    #f0f0ed;
  --ink-muted:      #6b6b70;
  --bg-subtle:      #f8faf0;
  --primary:        #84cc16;
  --primary-on-dark:#a3e635;
  --secondary:      #e4e6d4;
  --link:           #65a30d;

  /* The qualification indicator, as the product paints it. See
     FirmPortal/wwwroot/css/site.css — --bs-success, --ip-neutral-200,
     --ip-neutral-500. Deliberately the product’s values and not the
     marketing palette’s, so a product mock matches the real screen. */
  --qual-lit:       #4d7c0f;
  --qual-dim:       #e7e5e4;
  --qual-label:     #78716c;

  --font:    "Plus Jakarta Sans", system-ui, sans-serif;
  --display: "Reem Kufi", "Plus Jakarta Sans", system-ui, sans-serif;
  --serif:   "Lora", Georgia, serif;

  /* The firm whose brand the client report wears: "Fake, Fictional &
     Associates, Certified Public Accountants" — a logo built for product
     testing, and unmistakable fiction, which is the point. Both colors are
     sampled from the mark itself and are deliberately NOT IP lime: the whole
     claim of Beat II is that the report carries the firm's color, not ours. */
  --mock-firm:   #1b81fc;
  --mock-firm-2: #4837d1;
}

* { box-sizing: border-box; }
html { scroll-behavior: auto; }
body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ── Shared type scaffolding ───────────────────────────────── */

.eyebrow {
  font-family: var(--font);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 28px;
}

.headline {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin: 0;
  font-size: clamp(2.1rem, 6.4vw, 5rem);
}

.beat-title {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin: 0 0 18px;
  font-size: clamp(1.75rem, 4.2vw, 3.1rem);
}

.beat-body {
  font-size: clamp(1rem, 1.2vw, 1.1rem);
  line-height: 1.65;
  max-width: 46ch;
  margin: 0;
}

em { font-family: var(--serif); font-style: italic; font-weight: 400; }

/* ── Chrome ────────────────────────────────────────────────── */

.bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 14px 28px;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  backdrop-filter: blur(14px);
}
.bar img { display: block; height: 11px; width: auto; }
.bar a { text-decoration: none; }

/* Scroll-progress hairline, so the scrub length is legible while judging. */
.progress {
  position: fixed;
  top: 0; left: 0;
  height: 2px;
  width: 100%;
  transform-origin: 0 50%;
  z-index: 70;
  background: var(--primary);
}

/* ── Name-only (Beat I) ───────────────────────────────────── */
/* The claim and the demonstration of it sit side by side, so the
   reader is never asked to hold one in memory while looking at the
   other. */

/* The claim sits above its demonstration; the demonstration reads left to
   right, because that is the direction the sentence runs in too: a name
   goes in on one side and an answer comes back on the other. */
.nameonly {
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
}

.nameonly-copy { margin-bottom: clamp(38px, 5vh, 56px); }

/* Everything in the row hangs from one top line rather than centring on
   the card, which is much taller than the field it answers. */
.nameonly-demo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 92px 340px;
  align-items: start;
  gap: 0;
}

.nameonly-field { min-width: 0; }

/* Offset to the vertical middle of the input box, not of the row. */
.nameonly-arrow {
  display: flex;
  justify-content: center;
  margin-top: 42px;
}
/* Both arrows on the page share these — without fill:none the open
   arrowhead path fills solid black. */
.nameonly-arrow svg,
.booklist-up svg {
  width: 62px;
  height: 18px;
  overflow: visible;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* The shaft draws; the head arrives once it has somewhere to sit. */
.arrow-line {
  stroke-dasharray: 68;
  stroke-dashoffset: calc(68 * (1 - var(--draw, 0)));
}
.arrow-head { opacity: var(--head, 0); }

.noinput-label {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  margin: 0 0 9px;
}
.noinput-box {
  display: flex;
  align-items: center;
  min-height: 52px;
  padding: 14px 16px;
  font-size: 0.9375rem;
  white-space: pre;
}

/* The caret belongs to the box only while the box is being used. */
.caret.is-off { animation: none; opacity: 0; }

/* The answer. --rise lifts it in; --bar sweeps the lime rule across the
   top edge. That rule is the loading bar and then, with no transition
   at all, it is simply the card's rule. */
.nocard {
  overflow: hidden;
  opacity: var(--rise, 0);
  transform: translateY(calc((1 - var(--rise, 0)) * 18px));
}
.nocard-bar {
  display: block;
  height: 4px;
  transform: scaleX(var(--bar, 0));
  transform-origin: 0 50%;
}
.nocard-body {
  padding: 24px 26px 28px;
  display: flex;
  flex-direction: column;
  gap: 19px;
}
.nocard [data-part] { opacity: 0; }

/* ── The whole book (Beat I, second screen) ────────────────
   The same row as the screen before it, widened: a pasted client list on
   the left, the scored opportunity table on the right. Keeping the two
   screens on one grammar is the point — it is the same gesture at the
   scale of the whole book. */
.nameonly.booklist { max-width: 1020px; }

.booklist .nameonly-demo { grid-template-columns: 280px 72px minmax(0, 1fr); }

.booklist .intake-lines { min-height: 164px; }

/* Offset to the middle of the paste box rather than of the row. */
.booklist .nameonly-arrow { margin-top: 104px; }

.booklist .rows { max-width: none; }
.booklist .rows-head,
.booklist .row { grid-template-columns: minmax(0, 1fr) 150px 148px; gap: 14px; }

/* The conclusion belongs to the table, so it lines up with the table —
   past the paste box and the arrow — and points back up at it. */
.booklist-note {
  margin-top: 10px;
  margin-left: 352px;
}
.booklist-up {
  width: 18px;
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Clear of the table's left edge rather than hard against it. */
  margin-left: 36px;
}
/* The same arrow stood on its end, so both draw from the same two
   custom properties and cannot drift apart. */
.booklist-up svg {
  width: 46px;
  flex: none;
  transform: rotate(-90deg);
}
.booklist [data-kicker] { margin: 8px 0 0; }

.nocard-eyebrow {
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.nocard-name {
  font-family: var(--display);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.15;
}
.nocard-rule { height: 1px; margin-bottom: 19px; }
.nocard-label {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  margin-bottom: 10px;
}
.nocard-credit {
  font-family: var(--display);
  font-size: 2.125rem;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

/* The card carries the product's own 11px square rather than the 9px
   the results table uses, because it is shown at document scale. */
.nocard .qual-sq { width: 11px; height: 11px; border-radius: 3px; }
.nocard .qual-label {
  opacity: 0;
  min-width: 0;
  font-size: 0.75rem;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 400;
}

/* ── The pasted client list (Beat I, second screen) ───── */

.intake-lines {
  min-height: 132px;
  /* Four clients in the whole-book scene, three in direction A. */
  font-size: 0.9375rem;
  line-height: 2.05;
}
.intake-line { display: block; white-space: pre; }
.caret {
  display: inline-block;
  width: 1px;
  height: 1.05em;
  vertical-align: -0.17em;
  margin-left: 1px;
  animation: blink 1.05s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

/* ── Result rows (Beat I, scene 3) ─────────────────────────── */

.rows { width: 100%; max-width: 760px; margin: 0 auto; }

/* Each row is its own grid, so the non-flexible columns are given
   fixed widths — "auto" would size to each row's own content and the
   three rows would never line up with each other or with the header. */
.row {
  display: grid;
  grid-template-columns: 1fr 190px 170px;
  align-items: center;
  gap: 18px;
  padding: 19px 4px;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .45s ease, transform .55s cubic-bezier(.2,.7,.2,1);
}
.row.is-in { opacity: 1; transform: none; }
.row-name { font-weight: 500; font-size: 0.9375rem; }
.row-sub { font-size: 0.75rem; margin-top: 2px; }
.row-credit {
  font-variant-numeric: tabular-nums;
  font-size: 0.875rem;
  font-weight: 500;
  text-align: right;
  white-space: nowrap;
}

/* The three-square indicator. Strength is COUNT, never color —
   this mirrors _QualificationIndicator.cshtml exactly. */
.qual { display: flex; align-items: center; gap: 9px; }
.qual-squares { display: flex; gap: 3px; }
.qual-sq {
  width: 9px; height: 9px;
  border-radius: 1.5px;
  transition: background-color .4s ease .1s, border-color .4s ease;
}
.qual-label {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  min-width: 78px;
}

/* ── Beat III-ii · the share control ────────────────────
   One object, and it is the control rather than its consequence. Two
   earlier versions drew what the partner ends up seeing — first as the
   product's two tables, then as two lists of names — and both spent a
   whole screen explaining a rule. This shows the advisor deciding it,
   which is the actual answer to the fear the beat exists to defuse.
   The two empty boxes carry the restriction for free.
   ─────────────────────────────────────────────────── */

/* The page's only eyebrow, and the only one set as a badge. Every other
   eyebrow was cut for restating its headline; this one qualifies it — it
   is the single beat that does not apply to every reader, so it has to
   be read before the headline rather than scanned past with it. */
.eyebrow-who {
  display: inline-block;
  padding: 7px 15px 6px;
  border-radius: 999px;
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  margin-bottom: 20px;
}

.sharecard {
  width: 100%;
  border-radius: 12px;
  overflow: hidden;
  opacity: var(--rise, 0);
  transform: translateY(calc((1 - var(--rise, 0)) * 16px));
}
.sharecard-head { padding: 16px 20px 15px; }
.sharecard-eyebrow {
  display: block;
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 5px;
}
.sharecard-who {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.2;
}

.sharerow {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 20px;
  font-size: 0.875rem;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .4s ease, transform .5s cubic-bezier(.2,.7,.2,1);
}
.sharerow.is-in { opacity: 1; transform: none; }

/* An unticked box is not a disabled one. It is a client the advisor has
   not shared and can share whenever they like — so it keeps its full
   border and its name keeps full contrast. */
.sharebox {
  width: 17px;
  height: 17px;
  flex: none;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color .3s ease, border-color .3s ease;
}
.sharebox svg {
  width: 11px;
  height: 11px;
  fill: none;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
  transform: scale(.7);
  transition: opacity .22s ease, transform .3s cubic-bezier(.2,.9,.3,1.4);
}
.sharebox.is-on svg { opacity: 1; transform: none; }

.sharecard-foot { padding: 15px 20px 18px; }
.sharebtn {
  display: block;
  padding: 11px 16px;
  border-radius: 8px;
  text-align: center;
  font-size: 0.8125rem;
  font-weight: 600;
  transition: background-color .3s ease, color .3s ease;
}

/* ── Client report mock/* ── Client report mock (Beat II) ──────────────────────────── */

/* The reveal is composed here rather than written inline by the scroll
   engine, which only sets --rise (0..1). That leaves the stylesheet free
   to fold in a per-breakpoint scale without the two fighting. */
.report {
  opacity: var(--rise, 0);
  transform:
    translateY(calc((1 - var(--rise, 0)) * 44px))
    scale(calc((0.94 + var(--rise, 0) * 0.06) * var(--report-scale, 1)));
  width: 100%;
  max-width: 400px;
  aspect-ratio: 8.5 / 11;
  padding: 30px 30px 24px;
  background: #fff;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 15px;
  transform-origin: center;
}

.report-brand {
  border-bottom: 1px solid rgba(0,0,0,.1);
  padding-bottom: 13px;
}
/* The logo is the letterhead; it already says "Certified Public
   Accountants", so the sub-line that used to sit under the name is gone. */
.report-logo { display: block; width: 190px; height: auto; }
.report-prepared { font-size: 0.5625rem; color: var(--ink-muted); letter-spacing: 0.04em; }
.report-client { font-family: var(--display); font-size: 1.125rem; font-weight: 600; line-height: 1.2; }
.report-loc { font-size: 0.5625rem; color: var(--ink-muted); }

.report-figures {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  padding: 14px 0;
  border-top: 1px solid rgba(0,0,0,.08);
  border-bottom: 1px solid rgba(0,0,0,.08);
}
.report-fig-label {
  font-size: 0.5rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 5px;
}
.report-fig-value { font-family: var(--display); font-size: 1rem; font-weight: 600; line-height: 1.15; }
.report-fig-note { font-size: 0.5rem; color: var(--ink-muted); margin-top: 3px; }

.report-body { font-size: 0.5625rem; line-height: 1.6; color: #3a3a40; }
.report-h { font-size: 0.5rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: 5px; }
.report-list { margin: 0; padding-left: 13px; font-size: 0.5625rem; line-height: 1.65; color: #3a3a40; }

.report-cta {
  margin-top: auto;
  background: var(--mock-firm);
  color: #fff;
  padding: 13px 15px;
  display: flex;
  gap: 13px;
}
.report-step { flex: 1; }
.report-step-n {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: rgba(255,255,255,.7);
  margin-bottom: 3px;
}
.report-step-t { font-size: 0.5625rem; font-weight: 600; }
.report-powered { font-size: 0.4375rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-muted); text-align: right; }

/* The firm's own brand color as a rule across the top — run as a gradient
   between the two sampled blues, because the mark itself is a gradient of
   them. This is the customer's brand, not ours; the IP rule against
   decorative gradients governs IP surfaces. */
.report-rule {
  height: 3px;
  margin: -30px -30px 0;
  background: linear-gradient(90deg, var(--mock-firm), var(--mock-firm-2));
}

/* ── Side-by-side object and copy (Beat III) ───────────────────
   The same shape as the client report: one object, the copy beside
   it. Used where nothing crosses the screen and the object itself
   is what changes. ────────────────────────────────────────────── */

.side {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 420px;
  gap: clamp(40px, 6vw, 86px);
  align-items: center;
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
}
.side-copy .beat-title { margin-bottom: 16px; }
.side-copy .beat-body + .beat-body { margin-top: 16px; }

/* ── Beat III · the questionnaire that fills itself ──────────── */

.qcard { width: 100%; overflow: hidden; }
.qcard-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 13px 18px;
}
.qcard-title { font-size: 0.75rem; font-weight: 600; }
.qcard-count { font-size: 0.6875rem; white-space: nowrap; font-variant-numeric: tabular-nums; }

.q-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 132px;
  grid-template-rows: auto auto;
  align-items: center;
  gap: 0 12px;
  padding: 10px 18px 11px;
  font-size: 0.75rem;
}
.q-label {
  grid-column: 1;
  grid-row: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The claim sits on every field rather than once at the foot of the
   card. Five checks running down the left edge say "all of this"
   in a way one line of small caps underneath could not. */
.q-auto {
  grid-column: 1;
  grid-row: 2;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 4px;
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .34s ease;
}
.q-auto svg {
  width: 10px;
  height: 10px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.q-row.is-filled .q-auto { opacity: 1; }

/* The empty answer and the filled one occupy the same cell, so the
   card never changes height as it fills. */
.q-blank,
.q-value { grid-column: 2; grid-row: 1; }
.q-blank {
  height: 9px;
  border-radius: 2px;
  transition: opacity .3s ease;
}
.q-value {
  text-align: right;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .34s ease, transform .34s ease;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.q-row.is-filled .q-blank { opacity: 0; }
.q-row.is-filled .q-value { opacity: 1; transform: none; }

.q-doc {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 4px;
  font-size: 0.625rem;
}


/* ── Beat IV · the year as a rail ────────────────────────────── */

/* Full width of the column, left-aligned with the copy above it: a year
   should feel like the widest thing on the page. */
.rail-stage { width: 100%; margin: clamp(48px, 7vh, 80px) 0 0; }

.rail {
  position: relative;
  height: 118px;
}
/* The line draws left to right as the year runs. */
.rail-line {
  position: absolute;
  left: 0;
  right: 0;
  top: 74px;
  height: 1px;
  transform: scaleX(var(--draw, 0));
  transform-origin: 0 50%;
}
.rail-close {
  position: absolute;
  right: 0;
  top: 82px;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  opacity: 0;
  transition: opacity .4s ease;
}
.rail-close.is-in { opacity: 1; }

.rail-mark {
  position: absolute;
  left: var(--at);
  top: 0;
  width: 150px;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .42s ease, transform .5s cubic-bezier(.2,.7,.2,1);
}
.rail-mark.is-in { opacity: 1; transform: none; }
.rail-dot {
  position: absolute;
  left: 0;
  top: 70px;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  transform: translateX(-4px);
}
.rail-when {
  display: block;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  margin-bottom: 4px;
}
.rail-what { display: block; font-size: 0.8125rem; line-height: 1.35; }

.rail-out {
  margin: 30px 0 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.05rem, 2vw, 1.375rem);
  opacity: 0;
}

/* ── Beat V · the published page ───────────────────────────────
   The firm's own service page on the left with the form in its
   sidebar, the estimate the visitor gets back on the right. Same
   three-part row as the first screen — field, arrow, card — so the
   last beat is the page's opening gesture performed by a stranger. */

#s7-leads .nameonly-demo {
  grid-template-columns: minmax(0, 1fr) 72px 340px;
  align-items: center;
}
#s7-leads .nameonly-arrow { margin-top: 0; }

/* The page itself. Everything inside it except the form is abstracted,
   because it is the firm's page and inventing its words would be
   claiming to know them. */
.site {
  border-radius: 10px;
  overflow: hidden;
}
.site-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 16px;
}
.site-logo { display: block; width: 108px; height: auto; }
.site-links { display: flex; gap: 10px; }
.site-link {
  display: block;
  width: 26px;
  height: 5px;
  border-radius: 3px;
}

/* Two columns, which is the only arrangement that makes the claim: the
   form is one element of a page, beside the copy rather than instead
   of it. */
.site-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 204px;
  gap: 20px;
  align-items: start;
  padding: 18px 16px 22px;
}
.site-main { min-width: 0; }

.site-kicker {
  margin: 0 0 7px;
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.site-head {
  margin: 0 0 14px;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.15;
}
.site-line {
  display: block;
  width: var(--w, 100%);
  height: 6px;
  border-radius: 3px;
  margin-bottom: 8px;
}
/* A heading further down the page, so the column reads as an article
   rather than as one undifferentiated block of gray. */
.site-sub {
  display: block;
  width: 44%;
  height: 9px;
  border-radius: 3px;
  margin: 20px 0 13px;
}

/* The form is the page's sidebar: narrower than the copy, boxed, and
   starting at the top of the column so it is the first thing a reader
   who skims the page sees. */
.site-aside { min-width: 0; }
.leadform {
  display: block;
  border-radius: 8px;
  padding: 13px 13px 14px;
}
.leadform-tag {
  display: block;
  font-size: 0.5rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.leadform-head {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.8125rem;
  line-height: 1.25;
  margin-bottom: 10px;
}
.leadform .noinput-box { min-height: 34px; padding: 8px 10px; font-size: 0.75rem; }
.leadform-btn {
  display: block;
  margin-top: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  text-align: center;
  font-size: 0.6875rem;
  font-weight: 600;
}

/* ── The estimate the visitor gets back ───────────────────────
   Deliberately not inside a browser frame. The point of the right
   half is the document the visitor receives, so it is shown at
   document scale with nothing around it. */

.leadcard .nocard-body { padding: 20px 22px 24px; gap: 17px; }
.leadcard-logo {
  display: block;
  width: 116px;
  height: auto;
  margin-bottom: 3px;
}
.leadcard .nocard-name { font-size: 1.3125rem; }
.leadcard .nocard-credit { font-size: 1.9375rem; }

.nocard-cta {
  display: block;
  padding: 11px 16px;
  border-radius: 7px;
  text-align: center;
  font-size: 0.8125rem;
  font-weight: 600;
}
.nocard-cta-note {
  margin: 8px 0 0;
  text-align: center;
  font-size: 0.625rem;
  line-height: 1.4;
}

/* ── Beat VI · the firm's brand on everything ──────────────────
   Three artifacts side by side with no arrow between them. Nothing is
   transformed on this screen, so there is no gesture to draw — the
   claim is that the same mark is on all three, and three objects in a
   row is the plainest way to say it. ─────────────────────────────── */

.brand-copy { max-width: 760px; }
.brand-copy .beat-title { max-width: 26ch; }

.brandset {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.6vw, 34px);
  align-items: stretch;
  margin-top: clamp(44px, 6vh, 70px);
}
.brandcard {
  min-width: 0;
  display: flex;
  flex-direction: column;
  opacity: var(--rise, 0);
  transform: translateY(calc((1 - var(--rise, 0)) * 16px));
}

/* One abstracted text rule, shared by all three artifacts. Their words
   are not the point of this screen; the mark on them is. */
.m-line {
  display: block;
  width: var(--w, 100%);
  height: 5px;
  border-radius: 3px;
}

/* ── The client report, in miniature ─────────────────────────── */

.mrep { flex: 1; display: flex; flex-direction: column; border-radius: 8px; overflow: hidden; }
.mrep-rule { display: block; height: 3px; }
.mrep-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 15px;
  padding: 16px 16px 0;
}
.mrep-logo { display: block; width: 112px; height: auto; }
.mrep-eyebrow {
  font-size: 0.5rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin-bottom: 5px;
}
.mrep-name {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.15;
}
.mrep-figs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  padding: 11px 0;
}
.mrep-lab {
  display: block;
  font-size: 0.5rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  margin-bottom: 5px;
}
.mrep-val {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.8125rem;
  line-height: 1.2;
}
.mrep-lines { display: flex; flex-direction: column; gap: 7px; }
.mrep-band {
  margin-top: auto;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-right: -16px;
  margin-left: -16px;
  padding: 11px 16px;
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.05em;
}

/* ── The portal the client works in ──────────────────────────── */

.mport { flex: 1; display: flex; flex-direction: column; border-radius: 8px; overflow: hidden; }
.mport-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 14px;
}
.mport-logo { display: block; width: 88px; height: auto; }
.mport-who {
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mport-body { flex: 1; display: flex; flex-direction: column; padding: 15px 14px 17px; }
.mport-step {
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin-bottom: 9px;
}
/* The bar is the firm's color, so even the progress a client makes is
   measured in their accountant's brand rather than in ours. */
.mport-prog { height: 4px; border-radius: 3px; overflow: hidden; }
.mport-prog span { display: block; width: var(--at, 0); height: 100%; }

.mport-q { margin-top: 15px; }
.mport-q .m-line { margin-bottom: 7px; }
.mport-field { display: block; height: 28px; border-radius: 5px; }

.mport-btn {
  display: block;
  margin-top: auto;
  padding-top: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  text-align: center;
  font-size: 0.6875rem;
  font-weight: 600;
}

/* ── The finished study ──────────────────────────────────────── */

.mstudy { position: relative; flex: 1; display: flex; }
/* The sheet behind, so the study reads as a document of some weight
   rather than as a single page. */
.mstudy-back {
  position: absolute;
  top: -9px;
  right: -11px;
  left: 13px;
  bottom: 13px;
  border-radius: 8px;
}
.mstudy-face {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 24px;
  flex: 1;
  min-height: 300px;
  border-radius: 8px;
  padding: 18px 18px 20px;
}
.mstudy-eyebrow {
  font-size: 0.5rem;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}
.mstudy-rule {
  display: block;
  width: 34px;
  height: 2px;
  margin: 10px 0 20px;
}
.mstudy-logo { display: block; width: 138px; height: auto; }
.mstudy-prep { font-size: 0.6875rem; margin-bottom: 4px; }
.mstudy-client {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.15;
  margin-bottom: 4px;
}
.mstudy-years { font-size: 0.6875rem; }

/* ── The close and the ask ───────────────────────────────────── */

.close-inner { max-width: 820px; margin: 0 auto; }
/* The last screen now carries two lines instead of four, so it takes
   its air from below rather than from its own length. A page that
   simply stops reads as a page that ran out. */
.close { padding-bottom: clamp(150px, 22vh, 230px); }

/* Two lines, not a headline over paragraphs. The argument was made by the
   six screens above; the close only has to say what they added up to. */
.close-head {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.08;
  font-size: clamp(1.9rem, 4.4vw, 3.1rem);
  margin: 0 0 16px;
  max-width: 26ch;
}
/* Set in the display face so it reads as the second half of the headline
   rather than as body copy, but small enough that it cannot be mistaken
   for a second headline. */
.close-sub {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  font-size: clamp(1.1rem, 2.1vw, 1.5rem);
  margin: 0;
  max-width: 44ch;
}

/* Two asks side by side. The page has two readers and one ask would have
   made one of them guess which half was theirs. */
.close-ask {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(28px, 4vw, 52px);
  max-width: 660px;
  margin-top: clamp(44px, 6vh, 66px);
}
/* The divider is drawn by the color layer; the clearance it needs is
   structure, so it lives here. */
.ask + .ask { padding-left: clamp(24px, 3vw, 40px); }
.ask-label {
  margin: 0 0 12px;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
.close-cta {
  display: inline-block;
  padding: 14px 26px;
  border-radius: 999px;
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 600;
  transition: background-color .2s ease;
}
.ask-note {
  margin: 14px 0 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  max-width: 28ch;
}

/* ── Mobile ────────────────────────────────────────────────────
   Compositions are redesigned, not scaled. The field stack
   narrows and loses its padding; the result rows restack so the
   indicator and the figure sit under the name rather than beside
   it; the report shrinks to a readable share of the viewport.
   ─────────────────────────────────────────────────────────── */

@media (max-width: 760px) {
  /* The wordmark is ~233px at its desktop height and will not shrink,
     which drags the whole layout wider than the viewport. */
  .bar { padding: 11px 16px; gap: 10px; }
  .bar img { height: 9px; }


  /* No room for a row at this width, so the demonstration turns ninety
     degrees: field, arrow pointing down, card. The sequence survives. */
  .nameonly-copy { margin-bottom: 34px; }
  .nameonly .headline .was { max-width: none; }
  .nameonly-demo { grid-template-columns: 1fr; }
  .nameonly-arrow { justify-content: flex-start; margin: 0; padding: 16px 0 16px 26px; }
  .booklist .nameonly-demo { grid-template-columns: 1fr; }
  .booklist .nameonly-arrow { margin: 0; }
  /* Beat V: the two page states stack, so the arrow turns down with
     every other arrow on the page. */
  #s7-leads .nameonly-demo { grid-template-columns: 1fr; }
  #s7-leads .nameonly-arrow { margin: 0; }
  /* The sidebar has nowhere to go at this width, so the form drops
     below the copy the way it would on the firm's own phone layout. */
  .site-body { grid-template-columns: 1fr; gap: 16px; }
  /* The fixed columns are wider than the viewport here, so the rows
     restack like every other table on the page. */
  .booklist-note { margin-left: 0; }
  .booklist .rows-head { display: none; }
  .booklist .row { grid-template-columns: 1fr; gap: 9px; }
  .nameonly-arrow svg { transform: rotate(90deg); }


  /* Beat III-ii: the card drops below its copy, like Beat III's. */
  .sharerow { padding: 12px 14px; }
  .sharecard-head { padding: 14px; }
  .sharecard-foot { padding: 13px 14px 16px; }

  /* Beat III: the card drops below its copy. */
  .side { grid-template-columns: 1fr; gap: 30px; }
  .q-row { grid-template-columns: minmax(0, 1fr) 108px; padding: 9px 13px 10px; }
  .qcard-head { padding: 11px 13px; }

  /* Beat IV: three marks will not fit across a phone, so the rail stands
     up and the year runs down the screen instead of across it. The marks
     are ordered explicitly because Dec 31 is first in the markup — it is
     anchored to the far end of the horizontal rail. */
  .rail {
    display: flex;
    flex-direction: column;
    height: auto;
    padding-left: 22px;
  }
  .rail-line {
    left: 0;
    right: auto;
    top: 2px;
    bottom: 2px;
    width: 1px;
    height: auto;
    transform: scaleY(var(--draw, 0));
    transform-origin: 50% 0;
  }
  .rail-mark {
    order: 1;
    position: relative;
    left: 0;
    width: auto;
    padding: 0 0 24px;
  }
  .rail-dot { left: -22px; top: 3px; transform: none; }
  .rail-close {
    order: 2;
    position: relative;
    right: auto;
    top: auto;
    align-self: flex-start;
  }
  .rail-out { margin-left: 0; }

  /* Beat VI: three documents will not fit across a phone, so they
     stack. The order is the order a client meets them. */
  .brandset { grid-template-columns: 1fr; gap: 34px; }
  .brand-copy .beat-title { max-width: none; }
  .close-head { max-width: none; }
  .close-sub { max-width: none; }
  /* No room for two columns of ask, so they stack and the primary
     stays first — the reader it is for is the larger one. */
  .close-ask { grid-template-columns: 1fr; gap: 28px; }
  .ask + .ask { padding-left: 0; padding-top: 28px; }
  .ask-note { max-width: none; }


  .row {
    grid-template-columns: 1fr;
    gap: 9px;
    padding: 15px 2px;
  }
  .row-credit { text-align: left; }
  .qual-label { min-width: 0; }

  /* The report is NOT scaled here, and that is the fix for a bug worth
     recording. It used to be scaled to .72 with a -118px margin to
     reclaim the footprint a transform leaves behind — but the report's
     height comes from an aspect-ratio, so it varies with viewport
     width, while the margin was a constant. On anything narrower than
     the width it was tuned at, the margin over-pulled and the headline
     below rode up into the document.

     Dropping the scale removes the mismatch at its source rather than
     re-tuning a number that is wrong at every other width. The report
     is already capped at 400px and its body type is 9px, so shrinking
     it further was costing legibility to save vertical space on the
     one axis a phone has plenty of. */
  .report-figures { gap: 10px; padding: 11px 0; }
  .report-cta { padding: 10px 12px; gap: 9px; }

}

/* Anyone who has asked the OS for less motion gets the end state
   of every scene, immediately, with no scrubbing. */
@media (prefers-reduced-motion: reduce) {
  /* The driver already jumps each scene straight to its end state, so
     nothing tweens. What was still moving is the CSS transitions the
     end state triggers on arrival — a row fading up, a checkbox
     filling, a card rising. Those are listed here because they were
     added beat by beat and the original rule only knew about the
     first one. */
  .row, .qual-sq, .q-value, .q-blank, .q-auto,
  .rail-mark, .rail-close, .sharerow, .sharebox, .sharebox svg,
  .sharebtn, .caret { transition: none !important; }
  .row { opacity: 1 !important; transform: none !important; }
  .caret { animation: none; }
}
