/* ═══════════════════════════════════════════════════════════════════════════
   Operforma — marketing component layer
   Direction: "O Documento" · Palette: Mata Noite
   Spec: research/design/direction.md

   Reads ONLY the semantic tokens defined by [data-brand="marketing"] in
   ui/static/tokens.css. Never the raw four values, never a hex.

   SURFACE-SCOPED, not page-scoped. The predecessor (76 .mk-* components) was
   linked by exactly ONE page; every other page hand-rolled the same nav,
   footer and tables inline under different class names. That is why fixing
   anything took four edits and never got four. Every page links this file.

   Two grounds, one component set:
     default              — Mata. The statement surface.
     [data-surface=paper] — bone. The reading surface (articles).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Faces ─────────────────────────────────────────────────────────────────
   Relative url()s resolve against web/dist/assets/fonts/ (copied from
   web/assets/fonts/ by shared/site_build.py). Latin subset, as served by
   Google Fonts. ~132KB total, cached across the whole site. */
@font-face { font-family: 'Source Serif Pro'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('fonts/source-serif-400.woff2') format('woff2'); }
@font-face { font-family: 'Source Serif Pro'; font-style: normal; font-weight: 600;
  font-display: swap; src: url('fonts/source-serif-600.woff2') format('woff2'); }
@font-face { font-family: 'Source Serif Pro'; font-style: italic; font-weight: 400;
  font-display: swap; src: url('fonts/source-serif-400-italic.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('fonts/plex-mono-400.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('fonts/plex-mono-500.woff2') format('woff2'); }
@font-face { font-family: 'Instrument Sans'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('fonts/instrument-sans-400.woff2') format('woff2'); }
@font-face { font-family: 'Instrument Sans'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('fonts/instrument-sans-500.woff2') format('woff2'); }
@font-face { font-family: 'Instrument Sans'; font-style: normal; font-weight: 600;
  font-display: swap; src: url('fonts/instrument-sans-600.woff2') format('woff2'); }

/* ── Metric-adjusted fallbacks (E9 — hero font CLS) ────────────────────────
   While a webfont loads, its stack fallback paints first; without matched
   metrics the swap reflows the whole fold (the LCP .h1 is Source Serif via
   `swap` → paints in Georgia → shifts). These local-face declarations pin the
   fallback to the webfont's metrics, so the swap is paint-only.
   Values computed with fontTools from the shipped woff2s vs the local faces
   (fontaine formulas: size-adjust = avg-width ratio over a PT-BR frequency
   sample; ascent/descent/line-gap-override = primary hhea metrics ÷ size-adjust). */
@font-face {
  font-family: 'Source Serif Pro Fallback'; src: local('Georgia');
  size-adjust: 100.02%; ascent-override: 91.78%; descent-override: 33.49%; line-gap-override: 0%;
}
@font-face {
  font-family: 'Source Serif Pro Fallback Times'; src: local('Times New Roman');
  size-adjust: 108.23%; ascent-override: 84.82%; descent-override: 30.95%; line-gap-override: 0%;
}
@font-face {
  font-family: 'Instrument Sans Fallback'; src: local('Arial');
  size-adjust: 99.88%; ascent-override: 97.11%; descent-override: 25.03%; line-gap-override: 0%;
}
@font-face {
  font-family: 'IBM Plex Mono Fallback'; src: local('Courier New');
  size-adjust: 99.98%; ascent-override: 102.52%; descent-override: 27.50%; line-gap-override: 0%;
}

/* ── Ground ────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }

/* The `hidden` ATTRIBUTE must beat any component's `display`.
   The UA stylesheet's [hidden]{display:none} has specificity (0,1,0) and loses to
   any author rule that sets display — `.chips{display:flex}` did exactly that, so
   every cluster panel rendered OPEN while still carrying hidden="". The markup was
   correct, the accessibility tree was correct, and the page was wrong: progressive
   disclosure with nothing disclosed progressively. Tests that assert the attribute
   cannot see this; only a computed style (or an eye) can. */
[hidden] { display: none !important; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--fg);
  font-family: var(--mk-font-read);
  font-size: calc(17px * var(--mk-text-scale));
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Kills DOUBLE-TAP zoom (and the 300ms tap delay it implies) — nothing else.
     Pinch-zoom is untouched and must stay that way: WCAG 2.2 SC 1.4.4 requires
     the reader be able to enlarge text, and the viewport meta deliberately
     carries no user-scalable=no / maximum-scale. This is the whole legitimate
     scope of "stop the page zooming by accident". */
  touch-action: manipulation;
}
img { max-width: 100%; height: auto; }

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 28px; }
/* a notched phone in landscape: the 28px gutter grows to clear the safe area */
@supports (padding: max(0px)) {
  .wrap {
    padding-left: max(28px, env(safe-area-inset-left));
    padding-right: max(28px, env(safe-area-inset-right));
  }
}

.skip-link {
  position: absolute; left: -9999px;
  background: var(--fg); color: var(--ground);
  padding: 10px 16px; font-family: var(--mk-font-ui); font-size: calc(14px * var(--mk-text-scale)); z-index: 100;
}
.skip-link:focus { left: 12px; top: 12px; }

:where(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus); outline-offset: 2px;
}

/* ═══ DOCUMENT FURNITURE ══════════════════════════════════════════════════
   The running head, the numbered footnotes and the marginalia are NOT
   decoration. They are what makes this direction the direction. A build that
   drops them is not "O Documento" — it is the old site in a new palette.
   See research/design/direction.md, "The standing risk".

   THE FOLIO IS GONE (2026-07-13). It read "§ 1 / 7". The founder rule is words,
   not symbols — and spelled out as "Seção 1 de 7" it stopped being a flourish and
   became a factual claim, one that is false: the site does not have seven
   sections. A decoration that cannot survive being said out loud has to go.
   ═══════════════════════════════════════════════════════════════════════ */
.runhead {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  padding: 15px 0 10px;
  border-bottom: 1px solid var(--rule);
  font-family: var(--mk-font-ui);
  font-size: var(--mk-label); letter-spacing: var(--mk-label-track); text-transform: uppercase;
  color: var(--fg-dim);
}
.runhead-mark {
  display: flex; align-items: center; gap: 9px;
  color: var(--fg); font-weight: 600; letter-spacing: .18em;
  text-decoration: none;
}
.runhead-mark i {
  width: 12px; height: 12px; border: 2px solid currentColor; border-radius: 50%;
  display: block; position: relative; font-style: normal; flex: none;
}
.runhead-mark i::after { content: ""; position: absolute; inset: 2.5px; background: currentColor; }
.runhead nav { display: flex; gap: 22px; flex-wrap: wrap; }
.runhead a { color: var(--fg-dim); text-decoration: none; }
@media (hover: hover) { .runhead a:hover { color: var(--after); } }
.runhead a[aria-current="page"] { color: var(--fg); }

/* THE RUNNING HEAD, ON A PHONE. Below 640px the one-line head cannot hold the
   wordmark plus four links; it used to flex-wrap into an accidental second line
   of ~15px-tall tap targets. A four-link nav earns no hamburger (hiding four
   items behind a tap is worse than showing them — and a printed document has a
   running head, not a drawer): the head becomes two deliberate rows, and the
   nav row is a rail of full-height (44px) targets that scrolls sideways if the
   width truly runs out. */
@media (max-width: 639px) {
  .runhead { display: block; padding: 12px 0 0; }
  .runhead-mark { padding: 2px 0 10px; }
  .runhead nav {
    flex-wrap: nowrap; gap: 2px;
    overflow-x: auto;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    border-top: 1px solid var(--rule);
  }
  .runhead nav a { scroll-snap-align: start; }
  .runhead nav::-webkit-scrollbar { display: none; }
  .runhead nav a {
    flex: none; display: inline-flex; align-items: center;
    min-height: 44px; padding: 0 10px;
    letter-spacing: .12em; white-space: nowrap;
  }
  .runhead nav a:first-child { padding-left: 0; }
  /* the current page: a rule that fills in — the same idiom as .cluster-btn,
     never a shadow (the system is ruled rows) */
  .runhead nav a { border-bottom: 2px solid transparent; }
  .runhead nav a[aria-current="page"] { border-bottom-color: var(--after); }
}
/* A tablet is wide enough for the one-line head but still a finger — the links
   keep their look and gain real tap height. */
@media (pointer: coarse) and (min-width: 640px) {
  .runhead nav a { padding: 14px 4px; margin: -14px 0; }
}

/* ── THE READER'S TEXT SIZE ────────────────────────────────────────────────
   Three steps, in the running head, on every page. It exists because the
   quiet furniture of this design bottoms out at 10px (--mk-cap: card meta,
   sources, lens labels, eyebrows) and browser zoom can only fix that by
   magnifying the whole page including the layout. This scales TEXT and leaves
   the measures alone, so a larger step reflows inside the same column.

   It ADDS to pinch-zoom, it does not replace it — see the touch-action note
   on body. Real buttons, so they are keyboard-reachable and announce their
   state; aria-pressed carries the current step. */
/* the standard clip-rect utility: read by a screen reader, invisible on screen.
   The three buttons all read "A" visually — their SIZE is the legend, which a
   screen reader cannot see, so each carries its meaning in text. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0; padding: 0; margin: -1px;
}
.textsize {
  display: flex; align-items: center; gap: 2px; flex: none;
}
.textsize button {
  font-family: var(--mk-font-read); font-weight: 500; line-height: 1;
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--fg-dim); cursor: pointer;
  min-width: 28px; min-height: 28px; padding: 4px 6px;
  display: inline-flex; align-items: center; justify-content: center;
}
/* the three steps read as three sizes — the control IS its own legend */
.textsize button[data-text-size-set="m"]  { font-size: 13px; }
.textsize button[data-text-size-set="g"]  { font-size: 16px; }
.textsize button[data-text-size-set="gg"] { font-size: 19px; }
/* fixed px on purpose: the control must not resize itself as it resizes the
   page, or the reader loses the target they are aiming at mid-tap. */
@media (hover: hover) { .textsize button:hover { color: var(--after); } }
.textsize button[aria-pressed="true"] { color: var(--fg); border-bottom-color: var(--after); }
@media (max-width: 639px) {
  /* the head is two rows on a phone; the control rides the wordmark row, right-aligned */
  .runhead { position: relative; }
  .textsize { position: absolute; top: 6px; right: 0; }
  .textsize button { min-width: 34px; min-height: 34px; }
}

/* the margin — where the corrections live */
/* The bottom of .page was 0, so a page whose content is an <article> — /carta/,
   /privacidade/, a Biblioteca article — ended FLUSH against whatever followed it.
   On /carta/ that is the green stage band, so the founder's bio touched the colour
   change with no seam at all. Every other page gets this space from its last .sec
   (padding: … 0 var(--mk-space-7)); an article page has no .sec, so it got none.
   Matching that value keeps the seam identical whichever construction a page uses.
   .page--hero overrides this with --mk-space-8 (the landing's deeper hero release),
   so the landing is unaffected. */
.page { display: grid; grid-template-columns: 1fr; gap: 0 44px;
  padding: var(--mk-space-7) 0 var(--mk-space-7); }
@media (min-width: 1000px) { .page { grid-template-columns: minmax(0, var(--mk-measure)) 1fr; } }
/* the landing's hero band opens tight and releases deep (E3: hero 48/88) */
/* Run 1E: the plate's release is a STATEMENT seam — 64 here + the next
   section's 32 top ≈ 96–102px measured, inside the ≤130 statement budget.
   The earlier 88 stacked into a measured 140px void. */
.page--hero { padding-bottom: var(--mk-space-8); }

/* ONE accent per block (E5): the tick + the label word carry --after; the body
   is annotation. All three used to shout the accent at once. */
.mark {
  font-family: var(--mk-font-ui);
  font-size: calc(12.5px * var(--mk-text-scale)); line-height: 1.5;
  color: var(--fg-annot);
  border-left: 2px solid var(--after);
  padding: 2px 0 2px 12px; margin: 0 0 var(--mk-space-5); max-width: 30ch;
  hyphens: auto;
}
.mark b {
  display: block; font-family: var(--mk-font-data);
  font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track); text-transform: uppercase;
  font-weight: 500; margin-bottom: 4px; color: var(--after);
}
@media (max-width: 999px) {
  .mark { margin: var(--mk-space-4) 0 var(--mk-space-5); padding: 11px 13px; background: var(--ground-2); max-width: none; }
}

/* the proofreader's hand, inline */
.strike {
  text-decoration: line-through;
  text-decoration-color: var(--after);
  text-decoration-thickness: 2px;
  color: var(--fg-dim);
}
.ins { color: var(--after); font-style: italic; font-weight: 600; }

/* footnote refs are NUMBERS, and numbers are always mono (E5) */
.fn {
  font-family: var(--mk-font-data); font-size: var(--mk-label); vertical-align: super;
  color: var(--after); font-weight: 500; text-decoration: none;
}
@media (hover: hover) { .fn:hover { text-decoration: underline; } }

.foots {
  font-family: var(--mk-font-ui); font-size: calc(12px * var(--mk-text-scale)); line-height: 1.6;
  color: var(--fg-annot); margin: var(--mk-space-5) 0 0; padding-top: var(--mk-space-4);
  border-top: 1px solid var(--rule);
}
.foots ol { margin: 0; padding-left: 1.6em; }
.foots li { margin: 0 0 6px; }
.foots ::marker { color: var(--after); font-weight: 600; }
.foots a { color: var(--fg-annot); }

/* ═══ TYPE ════════════════════════════════════════════════════════════════
   The scale (E2). Source Serif is a BOOK serif: the hero's authority comes
   from size + tight set, never weight — a 600 serif display reads faux-bold
   (direction.md). Light-huge hero, semibold-modest heads.
   Exactly TWO mono-label voices exist: --mk-cap (captions, quiet furniture)
   and --mk-label (meaning-bearing labels). 9.5px and 10.5px are retired. */
.eyebrow {
  font-family: var(--mk-font-data);
  font-size: var(--mk-label); letter-spacing: var(--mk-label-track); text-transform: uppercase;
  color: var(--after); margin: 0 0 14px;  /* coupled to its heading, not floating */
}
.h1 {
  font-family: var(--mk-font-read); font-weight: 400;
  font-size: clamp(34px, 5.2vw, 60px); line-height: 1.05; letter-spacing: -.021em;
  margin: 0 0 24px; max-width: 20ch; text-wrap: balance;
}
.h1 em { font-style: italic; color: var(--after); }
.h2 {
  font-family: var(--mk-font-read); font-weight: 600;
  font-size: clamp(23px, 2.7vw, 31px); line-height: 1.15; letter-spacing: -.014em;
  margin: 0 0 16px; max-width: 26ch; text-wrap: balance;
}
/* The third tier, defined ONCE (it used to be improvised at 17–19px across the
   file). Every card/section sub-head reads these values. */
.h3, .tier-name, .cluster-name, .cluster-head, .toc-t, .step-t, .qs li > span {
  font-family: var(--mk-font-read); font-weight: 600;
  font-size: calc(20px * var(--mk-text-scale)); line-height: 1.3; letter-spacing: -.01em;
}
.h3 { margin: 0 0 12px; }
/* headings never hyphenate; the ragged edge is editorial */
.h1, .h2, .h3, .tier-name, .cluster-name, .cluster-head, .toc-t, .step-t,
.shelf-title, .art-title, .pano-lead-title, .pano-card-title,
.pano-msec-label, .pano-d-seclabel, .pano-ml-head { hyphens: none; }
.lede { font-size: calc(20px * var(--mk-text-scale)); line-height: 1.5; letter-spacing: -.005em; margin: 0 0 24px; max-width: 52ch; text-wrap: pretty; }
.prose { font-size: calc(17px * var(--mk-text-scale)); line-height: 1.7; margin: 0 0 20px; max-width: var(--mk-measure); text-wrap: pretty; }
.prose b, .prose strong { font-weight: 600; }
/* the reading containers hang their quotes into the margin (Safari; progressive) */
.art, .prose { hanging-punctuation: first last; }
.dim { color: var(--fg-dim); }
.src {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); line-height: 1.65;
  letter-spacing: .02em; color: var(--fg-annot); margin: 16px 0 0;
}

/* ═══ CTA ═════════════════════════════════════════════════════════════════
   E6: the button speaks in the UI voice at sentence case — 15/500 Instrument
   Sans, not the 13px uppercase *label* voice it wore. Hover settles the Mata
   one step deeper (--after-deep) instead of jumping to ink; the arrow nudges
   2px. It had NO transition at all — the single cheapest elegance lever. */
.cta {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--after); color: var(--ground);
  text-decoration: none; border: 0; cursor: pointer;
  font-family: var(--mk-font-ui); font-size: calc(15px * var(--mk-text-scale)); font-weight: 500;
  padding: 11px 24px; border-radius: var(--radius); min-height: 44px;
  transition: background-color .15s ease, color .15s ease;
}
@media (hover: hover) {
  .cta:hover { background: var(--after-deep, var(--fg)); color: var(--ground); }
}
.cta:active { background: var(--after-deep, var(--fg)); color: var(--ground); }
.cta-arrow { display: inline-block; transition: transform .15s ease; }
@media (hover: hover) {
  .cta:hover .cta-arrow, .area-bar-invite:hover .cta-arrow { transform: translateX(2px); }
}
@media (prefers-reduced-motion: reduce) { .cta-arrow { transition: none; } }
.acts { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; margin-top: 6px; }
/* the secondary link beside the primary — UI voice, quiet underline */
.acts a:not(.cta) {
  font-family: var(--mk-font-ui); font-size: calc(15px * var(--mk-text-scale)); font-weight: 500;
  text-underline-offset: 3px;
}
.note { font-family: var(--mk-font-data); font-size: var(--mk-label); color: var(--fg-annot); margin: 0; }

/* THE SECONDARY LINK. Every link in marketing.css used to be styled by its own component
   class, and there was no fallback — so a plain <a> next to a .cta, or inside a .note,
   rendered in the USER-AGENT DEFAULT BLUE (#0000EE). Four of them shipped that way: the
   "Ver o que você recebe" link in the Biblioteca's gate band was default-blue on the dark
   ink stage, in production. The whole suite was green. Only a browser saw it.
   A design system with no default is a design system with a hole in it. */
.acts a:not(.cta), .note a { color: var(--after); text-decoration: none; }
@media (hover: hover) { .acts a:not(.cta):hover, .note a:hover { text-decoration: underline; } }

/* ═══ THE PROOF STRIP ═════════════════════════════════════════════════════
   Sits directly under the primary CTA. There are no customers to quote yet and
   fabricating them is not an option — so the proof is what can be VERIFIED:
   what arrives, how it is paid for, and what the method refuses to do. The
   labels take --after because each one IS the architected state.
   ═══════════════════════════════════════════════════════════════════════ */
/* Ruled top AND bottom: it reads as a spec block in the document, and the prose
   below it stops colliding with it. */
.proof {
  list-style: none; margin: var(--mk-space-6) 0 var(--mk-space-6); padding: 20px 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  display: grid; gap: 16px 30px;
}
@media (min-width: 700px) { .proof { grid-template-columns: repeat(3, 1fr); } }
.proof li { font-size: calc(14.5px * var(--mk-text-scale)); line-height: 1.5; }
.proof b {
  display: block; font-family: var(--mk-font-data);
  font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track); text-transform: uppercase;
  color: var(--fg-annot); font-weight: 500; margin-bottom: 5px;
  /* E7: demoted from --after — three accent labels above the fold made the CTA
     one voice among six. The fold's single resting accent is the CTA. */
}
.proof span { color: var(--fg-dim); }

/* ═══ THE MOBILE ASK ══════════════════════════════════════════════════════
   Phones only. The page is ~4,500px tall and the hero CTA leaves the screen at
   once; the desktop keeps an ask in view through the marginalia column, a phone
   cannot. Revealed by the landing's IntersectionObserver only after the hero CTA
   has scrolled off ABOVE — so it never competes with the primary ask, and with
   JS off it simply never appears.
   ═══════════════════════════════════════════════════════════════════════ */
.stick {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; background: var(--stage);
  /* Terra, not Mata: --after is Mata on the paper scope, and Mata on the Tinta
     stage is 1.4:1 — an invisible border (E6 chrome fix). Terra is the stage's
     own accent, and a rule is a fill, where Terra is allowed. */
  border-top: 1px solid var(--before);
  padding: 10px max(16px, env(safe-area-inset-left, 0px))
           calc(10px + env(safe-area-inset-bottom, 0px))
           max(16px, env(safe-area-inset-right, 0px));
}
.stick .cta {
  flex: 1; justify-content: center;
  background: var(--on-stage); color: var(--stage);
  min-height: 44px;  /* Apple HIG touch target */
}
@media (hover: hover) { .stick .cta:hover { background: var(--on-stage-2); color: var(--stage); } }
/* desktop never shows it; the colophon clears it on mobile so nothing is covered */
@media (min-width: 900px) { .stick { display: none !important; } }
@media (max-width: 899px) { .colophon { padding-bottom: 78px; } }

/* ═══ THE EXHIBIT — the price list that restructures ══════════════════════
   Carried over from the rejected "A Tabela" direction: the single clearest
   one-glance explanation of the product. Colour carries the argument — the
   loose list is --before (drifting), the ladder is --after (settled).
   ═══════════════════════════════════════════════════════════════════════ */
/* the plate: 2px --fg opens it; the closing rule is row-weight (1px --rule) —
   never 1px --fg, the in-between weight the vocabulary retires (E3) */
.fig { margin: var(--mk-space-6) 0 0; border-top: 2px solid var(--fg); border-bottom: 1px solid var(--rule); }
.fig-cap {
  display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap;
  font-family: var(--mk-font-ui); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--fg-annot);
  padding: 10px 0; border-bottom: 1px solid var(--rule); margin: 0;
}
.fig-cap b { color: var(--fg); font-weight: 600; }

/* E6: the toggle drops the black-fill pill for the site's own idiom — the
   rule that fills in (same as the nav's current page and the accordion). */
.swap { display: flex; gap: 16px; }
.swap button {
  appearance: none; background: transparent; border: 0; cursor: pointer;
  font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase;
  padding: 7px 0 5px; color: var(--fg-dim);
  border-bottom: 2px solid transparent;
  transition: color .15s ease, border-color .15s ease;
}
.swap button[aria-pressed="true"] { color: var(--fg); border-bottom-color: var(--after); }
@media (hover: hover) { .swap button:hover { color: var(--fg); } }

.sheet[data-state="depois"] .sheet-before { display: none; }
.sheet-after { display: none; }
.sheet[data-state="depois"] .sheet-after { display: block; }
/* E8: a 120ms opacity settle when the panels swap — opacity ONLY, the height
   snaps. Armed by the toggle's first click so nothing animates at load
   (motion doctrine: no entrance animations). */
@keyframes mk-fade { from { opacity: 0; } to { opacity: 1; } }
.sheet[data-armed] .sheet-before, .sheet[data-armed] .sheet-after { animation: mk-fade .12s ease; }
@media (prefers-reduced-motion: reduce) {
  .sheet .sheet-before, .sheet .sheet-after { animation: none !important; }
}

.row {
  display: grid; grid-template-columns: 6px 1fr auto; gap: 16px;
  align-items: baseline; padding: 11px 0; border-bottom: 1px solid var(--rule);
}
.row-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--before); align-self: center; }
.row-name { font-size: calc(16px * var(--mk-text-scale)); }
.row-sub { display: block; font-family: var(--mk-font-data); font-size: var(--mk-cap); color: var(--fg-annot); margin-top: 3px; }
.row-price {
  font-family: var(--mk-font-data); font-size: calc(14px * var(--mk-text-scale));
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; white-space: nowrap;
}

/* tier-settle REMOVED (2026-07-24): it was the one live violation of motion
   doctrine v4 — an entrance animation. Content is its own base state. */
.tier {
  display: grid; grid-template-columns: 6px 1fr auto; gap: 16px;
  align-items: stretch; padding: 18px 0; border-bottom: 1px solid var(--rule);
}

/* the bar climbs with the ladder — the rung IS the information */
.tier-bar { background: var(--after); border-radius: 1px; opacity: .34; }
.tier:nth-child(2) .tier-bar { opacity: .66; }
.tier:nth-child(3) .tier-bar { opacity: 1; }
.tier-name { display: block; }
.tier-desc { display: block; font-size: calc(14px * var(--mk-text-scale)); color: var(--fg-dim); margin-top: 5px; max-width: 48ch; line-height: 1.55; }
.tier-price {
  font-family: var(--mk-font-data); font-size: calc(17px * var(--mk-text-scale)); font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: -.03em;
  text-align: right; color: var(--after); white-space: nowrap;
}
.tier-per {
  display: block; font-family: var(--mk-font-data); font-size: var(--mk-cap);
  letter-spacing: var(--mk-cap-track); text-transform: uppercase;
  color: var(--fg-annot); font-weight: 400; margin-top: 5px;
}

/* ── The diagnosis rows (FIGURA 1's second state — 1C wires the markup) ────
   Same 6 rows as "A conta atual": the price stays, muted to context; below it
   the leak, marked with a Terra tick (the unstructured present is a FILL,
   never text). The finding band closes it — the same 2px-Mata + ground-2
   idiom as .honesty / .area-empty. */
.row--diag .row-price { color: var(--fg-dim); font-weight: 400; }
.row-leak {
  display: block; position: relative; margin-top: 6px; padding-left: 14px;
  font-family: var(--mk-font-ui); font-size: calc(13px * var(--mk-text-scale)); line-height: 1.55;
  color: var(--fg-annot); max-width: 52ch;
}
.row-leak::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 8px; height: 2px; background: var(--before);
}
.finding {
  border-left: 2px solid var(--after); background: var(--ground-2);
  padding: 16px 18px; margin: var(--mk-space-4) 0 0; font-size: calc(15.5px * var(--mk-text-scale)); line-height: 1.6;
}
.finding b { font-weight: 600; }
.proj-note {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: .04em;
  color: var(--fg-annot); margin: 8px 0 0;
}

.total {
  display: grid; grid-template-columns: 6px 1fr auto; gap: 16px;
  padding: 16px 0 14px; border-top: 2px solid var(--fg); align-items: baseline;
}
.total-k {
  grid-column: 2; font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--fg-annot);
}
.total-v {
  font-family: var(--mk-font-data); font-size: calc(22px * var(--mk-text-scale)); font-weight: 500;
  font-variant-numeric: tabular-nums; letter-spacing: -.04em; text-align: right;
}
.sheet[data-state="depois"] .total-v { color: var(--after); }
.total-v em {
  display: block; font-style: normal; font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--fg-annot); font-weight: 400; margin-top: 5px;
}

/* ═══ TABLES ══════════════════════════════════════════════════════════════ */
.tbl-scroll { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; }
.tbl th {
  font-family: var(--mk-font-ui); font-size: var(--mk-label); font-weight: 600;
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--fg-annot);
  text-align: left; padding: 10px 14px 8px 0; border-bottom: 1px solid var(--rule);
}
.tbl th:last-child, .tbl td:last-child { text-align: right; padding-right: 0; }
.tbl td { padding: 12px 14px 12px 0; border-bottom: 1px solid var(--rule); font-size: calc(16px * var(--mk-text-scale)); }
.tbl tr:last-child td { border-bottom: 0; }
.tbl .num { font-family: var(--mk-font-data); font-size: calc(14px * var(--mk-text-scale)); font-variant-numeric: tabular-nums; }
.tbl .new { color: var(--after); font-weight: 600; }

/* ═══ THE THREE QUESTIONS ═════════════════════════════════════════════════ */
.qs { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule); }
.qs li {
  display: grid; grid-template-columns: 8px 1fr; gap: 16px; align-items: baseline;
  padding: 15px 0; border-bottom: 1px solid var(--rule);
}
.qs li::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--after); align-self: center; }
/* .qs li > span sizes via the .h3 group rule (TYPE) */

/* ═══ ONE PICKER, EVERY SURFACE ═══════════════════════════════════════════
   Replaces BOTH the old landing chip-row AND the Biblioteca/Panorama
   "Você está vendo: X" bar + .area-chooser grid — two controls for one job.
   Every ofício is ALWAYS selectable. The count beside it is the truth, and an
   area with no content lands on an explicit empty state, never a blank
   filtered page. Built from src/operforma/marketing/areas.py.
   ═══════════════════════════════════════════════════════════════════════ */
.picker-lbl {
  font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--fg-annot);
  margin: 0 0 16px;
}
.picker-lbl b { color: var(--fg); font-weight: 500; }

/* Cluster-first: four choices, not fifteen. Opening one reveals its ofícios and
   closes the others (accordion — area-select.js owns the state). Fifteen
   equal-weight chips is a scan; four is a choice. */
.clusters { display: flex; flex-direction: column; border-top: 1px solid var(--rule); }
.cluster { border-bottom: 1px solid var(--rule); }
.cluster-btn {
  appearance: none; width: 100%; cursor: pointer;
  background: transparent; border: 0; text-align: left;
  display: flex; align-items: baseline; gap: 16px;
  padding: 15px 0; color: var(--fg); font-family: var(--mk-font-read);
}
/* .cluster-name sizes via the .h3 group rule (TYPE) */
/* the count is pushed right; the NAME stays left against its marker — the same
   left-aligned rhythm as .toc. (space-between would centre it between the two.) */
.cluster-n {
  margin-left: auto; font-weight: 400;
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: .1em;
  text-transform: uppercase; color: var(--fg-annot); white-space: nowrap;
}
/* the open marker: a rule that fills in, not a rotating chevron */
.cluster-btn::before {
  content: ""; flex: none; width: 14px; height: 2px; margin-right: 14px;
  background: var(--before); align-self: center; transition: width .15s ease;
}
.cluster-btn[aria-expanded="true"] { color: var(--after); }
.cluster-btn[aria-expanded="true"]::before { width: 26px; background: var(--after); }
@media (prefers-reduced-motion: reduce) { .cluster-btn::before { transition: none; } }
.cluster .chips { padding: 2px 0 18px 28px; }

.chips { display: flex; flex-wrap: wrap; gap: 7px; margin: 0; padding: 0; list-style: none; }
.chip {
  appearance: none; cursor: pointer; background: transparent;
  border: 1px solid var(--rule); border-radius: var(--radius);
  font-family: var(--mk-font-ui); font-size: calc(12.5px * var(--mk-text-scale)); padding: 8px 14px;
  color: var(--fg-dim); text-decoration: none;
  display: inline-flex; gap: 7px; align-items: baseline;
}
@media (hover: hover) { .chip:hover { border-color: var(--fg); color: var(--fg); } }
/* aria-current, not aria-pressed: these are LINKS, and area-select.js sets
   aria-current on the active pick. aria-pressed is for toggle buttons and was
   invalid here (it was also hardcoded to `pilates` on every render). */
.chip[aria-current="true"] { background: var(--after); border-color: var(--after); color: var(--ground); }
.chip small { font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: .04em; opacity: .75; }
.chip-empty { border-style: dashed; }

/* an area with no content on THIS surface: say so, and offer the way through */
.area-empty {
  border-left: 2px solid var(--after); background: var(--ground-2);
  padding: 16px 18px; margin: var(--mk-space-5) 0 0; font-size: calc(15.5px * var(--mk-text-scale));
}
.area-empty b { font-weight: 600; }
.area-empty a { color: var(--after); }
.area-hidden { display: none !important; }

/* ── the shelf's chooser is EXPANDED, not an accordion ──────────────────────
   The landing's picker is a chooser: four clusters, open one, pick. The
   Biblioteca index IS the directory — hiding its ofícios behind four toggles
   would bury the page's whole purpose one click deep. Same primitives
   (.clusters/.cluster/.chips/.chip), a static head instead of a button. */
.cluster-head {
  display: flex; align-items: baseline; gap: 14px; padding: 15px 0;
  color: var(--fg);  /* scale via the .h3 group rule (TYPE) */
}
.cluster-head::before {
  content: ""; flex: none; width: 14px; height: 2px;
  background: var(--cluster-accent, var(--before)); align-self: center;
}
.cluster-head .cluster-n { margin-left: auto; }

/* An ofício with no articles yet. It is NOT pickable — filtering to zero cards
   would self-heal to show-everything and read as a broken filter — but it is
   never a dead end either: it says so, and offers the way through. */
.chip-soon { cursor: default; border-style: dashed; color: var(--fg-annot); }
@media (hover: hover) { .chip-soon:hover { border-color: var(--rule); color: var(--fg-annot); } }
.chip-capture { color: var(--after); text-decoration: none; white-space: nowrap; }
@media (hover: hover) { .chip-capture:hover { text-decoration: underline; } }

/* The in-content entry control (_area_modal.html's area_bar()). E6/C3: it used
   to borrow the PASSIVE-ASIDE look (left border + ground-2 — "read if you
   like") while being the primary entry control. Promoted to a ruled section
   head: a 2px plate opens it, a mono eyebrow names it, and the invitation is a
   serif line in the signal colour. States (where the surface filters in place)
   are swapped by area-select.js's setBarState(), never by CSS alone:
     · nothing chosen  → the invitation ([data-area-bar-prompt])
     · ofício chosen   → "Você está vendo: X" + trocar/ver-todas on their own row */
.area-bar {
  border-top: 2px solid var(--fg);
  padding: 14px 0 0; margin: 0 0 var(--mk-space-5);
}
.area-bar-eyebrow {
  font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase;
  color: var(--fg-annot); margin: 0 0 6px;
}
.area-bar-invite {
  appearance: none; background: transparent; border: 0; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: 9px; min-height: 44px;
  font-family: var(--mk-font-read); font-size: calc(19px * var(--mk-text-scale)); letter-spacing: -.005em;
  color: var(--after); text-align: left;
  transition: color .15s ease;
}
@media (hover: hover) { .area-bar-invite:hover { color: var(--after-deep, var(--fg)); } }
.area-bar-chosen {
  display: block;
  font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: .06em; text-transform: uppercase; color: var(--fg-annot);
  padding: 12px 0 2px;
}
.area-bar-chosen strong { color: var(--fg); font-weight: 500; }
.area-bar-actions { display: flex; gap: 24px; flex-wrap: wrap; padding: 6px 0 4px; }
.area-bar-btn {
  appearance: none; background: transparent; border: 0; padding: 0; cursor: pointer;
  font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--after); text-decoration: none;
}

/* ═══ THE OFÍCIO PICKER MODAL (#area-modal) ═══════════════════════════════
   One dialog, rendered once by _base.html, imported by every surface's
   area_bar(). Native <dialog>+showModal(): a free focus trap, ESC-to-close
   and a ::backdrop — nothing hand-rolled. Reads ONLY the marketing semantic
   tokens (--ground/--fg/--rule/--after), same as the page behind it, so the
   picker reads as a page of the same document, not an imported widget — no
   box-shadow (the whole system is ruled rows, not cards; see .fig). No
   entrance animation either way (brand v4 motion doctrine D4 — the mark's
   heartbeat is the only sanctioned motion on marketing); it opens as it is. */
dialog.area-modal {
  background: var(--ground); color: var(--fg);
  border: 0; border-top: 2px solid var(--fg); border-bottom: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0; width: calc(100% - 32px); max-width: 560px;
  max-height: 82vh; max-height: 82dvh; /* dvh: vh overshoots under mobile browser chrome */
}
/* G1: token-derived (Tinta at 55%) with the literal as the fallback for
   engines that can't read custom properties in ::backdrop yet. */
dialog.area-modal::backdrop {
  background: rgba(16, 12, 13, .55);
  background: color-mix(in srgb, var(--mk-tinta) 55%, transparent);
  backdrop-filter: blur(2px);
}
/* <dialog>-unaware fallback (openDialog()'s data-attribute path, not showModal()):
   no ::backdrop applies, so the picker sits centred in normal flow instead. */
dialog.area-modal[open]:not(:modal) { position: static; margin: 40px auto; }

.area-modal-inner { position: relative; padding: 34px 30px 28px; max-height: 82vh; max-height: 82dvh; overflow-y: auto; }
.area-modal-x {
  position: absolute; top: 10px; right: 10px;
  appearance: none; background: transparent; border: 0; cursor: pointer;
  width: 34px; height: 34px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--fg-dim); font-size: calc(13px * var(--mk-text-scale)); line-height: 1;
}
@media (hover: hover) { .area-modal-x:hover { color: var(--fg); background: var(--ground-2); } }
.area-modal-h { margin: 0 0 6px; }
.area-modal-fallback { margin: 26px 0 0; font-size: calc(13px * var(--mk-text-scale)); }
.area-modal-fallback a { color: var(--after); }

@media (max-width: 640px) {
  dialog.area-modal { width: calc(100% - 24px); max-height: 88vh; max-height: 88dvh; }
  .area-modal-inner { padding: 28px 20px 24px; max-height: 88vh; max-height: 88dvh; }
}

/* ── the shelf itself ───────────────────────────────────────────────────────
   One card per record. Ruled rows, not boxes: the library reads as a document,
   the same as everything it links to. */
/* No border-top. The shelf opens 32px under the picker section's own closing
   rule, so a top rule here drew a SECOND identical hairline with nothing but
   empty paper between the two — the doubling the founder flagged. The section
   rule above IS the shelf's top edge. */
.shelf { list-style: none; margin: 0; padding: 0; }
.shelf-card {
  display: block; padding: var(--mk-space-5) 0; border-bottom: 1px solid var(--rule);
  text-decoration: none; color: inherit;
}
@media (hover: hover) { .shelf-card:hover .shelf-title { color: var(--after); } }
.shelf-meta {
  font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--fg-annot);
  display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline; margin: 0 0 10px;
}
.shelf-meta .art-tag { color: var(--fg); } /* E7: one resting accent per card — .shelf-go is it */
.shelf-title {
  font-family: var(--mk-font-read); font-size: calc(21px * var(--mk-text-scale)); line-height: 1.25;
  letter-spacing: -.01em; margin: 0 0 8px; max-width: 34ch; transition: color .15s ease;
}
.shelf-deck { margin: 0 0 12px; max-width: var(--mk-measure); color: var(--fg-dim); font-size: calc(15.5px * var(--mk-text-scale)); text-wrap: pretty; }
.shelf-go {
  font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--after);
}
.shelf-soon { margin: var(--mk-space-5) 0 0; color: var(--fg-annot); font-size: calc(14.5px * var(--mk-text-scale)); }
@media (prefers-reduced-motion: reduce) { .shelf-title { transition: none; } }

/* ═══ COMO FUNCIONA — the method ══════════════════════════════════════════
   The alternation IS the argument: the reader's work is small and bounded,
   the heavy lifting is the system's. `.step--op` marks the system's turns, so
   the reader can see at a glance that three of five steps are not theirs.
   ═══════════════════════════════════════════════════════════════════════ */
.steps { list-style: none; margin: var(--mk-space-6) 0 var(--mk-space-7); padding: 0; border-top: 1px solid var(--rule); }
.step {
  display: grid; grid-template-columns: 4ch 1fr; gap: 18px;
  padding: var(--mk-space-5) 0; border-bottom: 1px solid var(--rule);
}
.step-n {
  font-family: var(--mk-font-data); font-size: var(--mk-label); letter-spacing: .08em;
  color: var(--fg-annot); font-variant-numeric: tabular-nums; padding-top: 6px;
}
.step--op .step-n { color: var(--after); }
.step-who { display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline; margin: 0 0 6px; }
.step-actor {
  font-family: var(--mk-font-data); font-size: var(--mk-label); letter-spacing: var(--mk-label-track);
  text-transform: uppercase; color: var(--fg-annot); font-weight: 400;
}
.step--op .step-actor { color: var(--after); }
.step-t { /* scale via the .h3 group rule (TYPE) */ }
.step-d { margin: 0; color: var(--fg-dim); font-size: calc(15.5px * var(--mk-text-scale)); max-width: var(--mk-measure); text-wrap: pretty; }

/* the two doors out of this page */
.doors { display: grid; gap: 12px; margin: var(--mk-space-5) 0 0; }
@media (min-width: 720px) { .doors { grid-template-columns: 1fr 1fr; } }
.door {
  display: block; padding: 18px 20px; text-decoration: none; color: inherit;
  border: 1px solid var(--rule); border-radius: var(--radius);
}
@media (hover: hover) { .door:hover { border-color: var(--after); } }
.door-k {
  display: block; font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--after); margin-bottom: 7px;
}
.door-t { display: block; font-size: calc(16px * var(--mk-text-scale)); color: var(--fg-dim); }

/* the FAQ — the only FAQPage graph on the site renders from the same list */
.faq { border-top: 1px solid var(--rule); margin-top: var(--mk-space-5); }
.faq-item { border-bottom: 1px solid var(--rule); }
.faq-item summary {
  cursor: pointer; padding: 16px 0; list-style: none;
  font-family: var(--mk-font-read); font-size: calc(17px * var(--mk-text-scale)); color: var(--fg);
  display: flex; align-items: baseline; gap: 14px;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::before {
  content: ""; flex: none; width: 14px; height: 2px; background: var(--before);
  align-self: center; transition: width .15s ease;
}
.faq-item[open] summary { color: var(--after); }
.faq-item[open] summary::before { width: 26px; background: var(--after); }
.faq-item p { margin: 0 0 16px 28px; color: var(--fg-dim); font-size: calc(15.5px * var(--mk-text-scale)); max-width: var(--mk-measure); text-wrap: pretty; }
@media (prefers-reduced-motion: reduce) { .faq-item summary::before { transition: none; } }

/* ═══ O QUE VOCÊ RECEBE — the reader's own case ═══════════════════════════
   Inside [data-area-swap] exactly ONE block is visible and the default is
   `geral` — the OPPOSITE of the Biblioteca rule, where geral shows ALONGSIDE
   the picked area. area-select.js's resolveSwap() owns that inversion. Every
   ofício's copy still ships in the static HTML; the hide is client-side only,
   so a crawler reads all fifteen.
   ═══════════════════════════════════════════════════════════════════════ */
/* Scoped to the swap GROUP by attribute, not by `.swap` — that class also names
   the exhibit's Hoje/Depois toggle (line ~265), and the bare-class rule was
   pushing the toggle 30px out of its own caption row on the landing. */
[data-area-swap] { margin: 30px 0 0; }
.case { border-left: 2px solid var(--after); padding: 4px 0 4px 22px; }
.case-cap { margin: 0 0 16px !important; }
.case-h {
  font-family: var(--mk-font-data); font-size: var(--mk-label); letter-spacing: var(--mk-label-track);
  text-transform: uppercase; color: var(--fg-annot); margin: var(--mk-space-5) 0 7px;
}
.case-p { margin: 0; color: var(--fg-dim); font-size: calc(15.5px * var(--mk-text-scale)); max-width: var(--mk-measure); text-wrap: pretty; }

/* the barbell ofícios (pilates, salons, barbers, nails): for a studio, the OWNER
   is the real buyer, so those areas carry two readings of the same trade */
.variant { display: flex; flex-wrap: wrap; gap: 7px; margin: 0 0 18px; }
.variant-btn {
  appearance: none; cursor: pointer; background: transparent;
  border: 1px solid var(--rule); border-radius: var(--radius);
  font-family: var(--mk-font-ui); font-size: calc(12px * var(--mk-text-scale)); padding: 6px 12px; color: var(--fg-dim);
}
@media (hover: hover) { .variant-btn:hover { border-color: var(--fg); color: var(--fg); } }
.variant-btn[aria-current="true"] { background: var(--after); border-color: var(--after); color: var(--ground); }

/* Hoje → Cenário projetado, as two facing cards. The arrow must turn 90° once the
   cards stack, or it points sideways into nothing. */
.proj { display: grid; gap: 12px; align-items: center; margin: var(--mk-space-5) 0 var(--mk-space-4); }
.proj-arrow { justify-self: center; color: var(--fg-annot); transform: rotate(90deg); }
@media (min-width: 640px) {
  .proj { grid-template-columns: 1fr auto 1fr; }
  .proj-arrow { transform: none; }
}
.proj-card { border: 1px solid var(--rule); border-radius: var(--radius); padding: 14px 16px; }
.proj-card--to { border-color: var(--after); background: var(--ground-2); }
.proj-k {
  display: block; font-family: var(--mk-font-data); font-size: var(--mk-cap);
  letter-spacing: var(--mk-cap-track); text-transform: uppercase; color: var(--fg-annot); margin-bottom: 8px;
}
.proj-card--to .proj-k { color: var(--after); }
.proj-t { width: 100%; border-collapse: collapse; font-size: calc(14px * var(--mk-text-scale)); }
.proj-t th, .proj-t td { text-align: left; padding: 5px 0; vertical-align: top; }
.proj-t th { font-weight: 400; color: var(--fg-annot); padding-right: 12px; }
.proj-t td { color: var(--fg); font-family: var(--mk-font-data); font-size: calc(12.5px * var(--mk-text-scale)); }

/* ═══ THE CONTENTS — Biblioteca + Panorama as CHAPTERS ════════════════════
   The structural fix. They stop being separate sites sharing a localStorage
   key and become numbered entries in one table of contents.
   ═══════════════════════════════════════════════════════════════════════ */
.toc { list-style: none; margin: 0; padding: 0; }
.toc li {
  display: grid; grid-template-columns: 3.5ch 1fr auto; gap: 16px;
  align-items: baseline; padding: 13px 0; border-bottom: 1px solid var(--rule);
}
.toc-n { font-family: var(--mk-font-data); font-size: var(--mk-label); letter-spacing: .06em; color: var(--fg-annot); }
/* .toc-t sizes via the .h3 group rule (TYPE) */
.toc-t a { color: inherit; text-decoration: none; }
@media (hover: hover) { .toc-t a:hover { color: var(--after); } }
.toc-c {
  font-family: var(--mk-font-data); font-size: var(--mk-label); letter-spacing: .06em;
  color: var(--fg-annot); font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 400;
}
.toc-c b { color: var(--fg); font-weight: 500; }
.toc li[data-empty] { opacity: .55; }

/* ═══ SECTIONS + FOOTER ═══════════════════════════════════════════════════
   Varied rhythm (E3, amended 2026-07-24 — Run 1E, the SEAM budget): adjacent
   section paddings STACK at every boundary, so rhythm is budgeted at the
   seam, not per side. Base seam = 48+48 = 96px; a statement moment (the
   exhibit plate, the closing stage) opens with 48+64 = 112px + its 2px
   plate; a stub section (the landing picker) breathes at 32. The earlier
   64/88 per-side values doubled into measured 132–164px voids — founder
   review finding. A section boundary is a plate (2px --fg) only on
   statement moments — everywhere else it stays a quiet row rule. */
/* Asymmetric on purpose: the bottom row rule sits 48 below its own content
   and 32 above the NEXT head — the rule reads as the next section's head
   rule (the same coupling idiom as the .sec--major top plate). Base seam
   = 48 + 32 = 80px. */
.sec { padding: var(--mk-space-6) 0 var(--mk-space-7); border-bottom: 1px solid var(--rule); }
.sec:last-of-type { border-bottom: 0; }
/* NOTE: .sec--hero is currently unused by any template (the landing's hero
   plate is .page--hero above) — kept aligned to the same budget. */
.sec--hero { padding: var(--mk-space-7) 0 var(--mk-space-8); }
.sec--major { padding: var(--mk-space-8) 0; border-top: 2px solid var(--fg); }
/* a two-line stub section must not command a full seam */
.sec--compact { padding: var(--mk-space-6) 0; }
/* a trailing child's margin rides ON TOP of the seam — the padding owns it
   (markup is div.wrap > section.sec, so the section's own last child is the
   seam edge; measured riders: .src +26, .acts note +4, .toc/.prose +36) */
.sec > :last-child { margin-bottom: 0; }
/* the plate carries the boundary — the preceding row rule would double it */
.sec:has(+ .sec--major) { border-bottom: 0; }
/* SAME IDIOM, the case it had been missed on: the ofício bar opens its section
   with a 2px --fg plate (.area-bar), so the previous section's closing hairline
   drew a second line 32px above it with nothing in between. On the Biblioteca
   and Panorama hubs that was the first thing under the masthead. The plate
   carries this boundary too. */
.sec:has(+ .sec > .area-bar) { border-bottom: 0; }
/* on the ink stage the ground change IS the boundary; a Tinta-on-Tinta rule is noise */
.stage.sec--major { border-top: 0; }
/* a deep-linked section (…/#ferramentas) lands with a breath above it */
.sec[id] { scroll-margin-top: 16px; }

.stage { background: var(--stage); color: var(--on-stage); }
.stage .h2 { color: var(--on-stage); }
.stage .h2 em { color: var(--on-stage-2); }
.stage .eyebrow { color: var(--on-stage-2); }
.stage .cta { background: var(--on-stage); color: var(--stage); }
@media (hover: hover) { .stage .cta:hover { background: var(--on-stage-2); } }
/* --after is Mata — invisible on the ink stage. The secondary link needs the stage's own
   accent, or it reads as a hole in the band. */
.stage .acts a:not(.cta), .stage .note a { color: var(--on-stage-2); }
.stage .note { color: var(--on-stage); opacity: .6; }

.colophon {
  background: var(--stage); color: var(--on-stage);
  padding: var(--mk-space-5) 0;
  font-family: var(--mk-font-data); font-size: var(--mk-cap);
  letter-spacing: .11em; text-transform: uppercase;
}
.colophon .wrap { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; opacity: .72; }
.colophon a { color: inherit; transition: color .15s ease; }
@media (hover: hover) { .colophon a:hover { color: var(--on-stage-2); } }

/* ═══ BIBLIOTECA — the reading surface ════════════════════════════════════
   The article is the same document as the landing: bone paper, Source Serif,
   Mata only where the architected state appears. It reads on
   [data-surface="paper"], where --after IS Mata and the palette encodes state.

   Every component here draws ONE block type from the content record
   (src/operforma/marketing/content_model.py). Adding a block is a template case
   plus a rule here — not a migration, and never a hand-edit to 21 files.
   ═══════════════════════════════════════════════════════════════════════ */
.art { max-width: var(--mk-measure); }
.art-meta {
  font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--fg-annot);
  display: flex; gap: 10px; align-items: baseline; margin: 0 0 20px;
}
.art-tag { color: var(--after); text-decoration: none; font-weight: 500; }
.art-sep { color: var(--rule); }
.art-title { max-width: 24ch; }
.art-h2 { margin: var(--mk-space-7) 0 var(--mk-space-4); scroll-margin-top: 24px; }

/* why the text exists — the author's contract with the reader */
.framing {
  border-left: 2px solid var(--before);
  padding: 2px 0 2px 18px; margin: var(--mk-space-6) 0 var(--mk-space-6);
}
.framing p { margin: 0; font-size: calc(15.5px * var(--mk-text-scale)); line-height: 1.65; color: var(--fg-dim); }
.framing-label {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--fg-annot); margin: 0 0 6px !important;
}

.art-toc { border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
           padding: 16px 0; margin: 0 0 var(--mk-space-7); }
.art-toc-label {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--fg-annot); margin: 0 0 10px;
}
.art-toc ol { margin: 0; padding-left: 1.5em; }
.art-toc li { margin: 0 0 5px; font-size: calc(15px * var(--mk-text-scale)); }
.art-toc a { color: var(--fg-dim); text-decoration: none; }
@media (hover: hover) { .art-toc a:hover { color: var(--after); } }

/* THE PULL-STAT — 50 of them, and the schema had no field for a single one.
   The number is the moment; the source line beneath it is non-negotiable. */
.pstat {
  margin: var(--mk-space-6) 0; padding: var(--mk-space-5) 0;
  border-top: 2px solid var(--after); border-bottom: 1px solid var(--rule);
}
.pstat-n {
  font-family: var(--mk-font-data); font-size: clamp(30px, 4.4vw, 42px);
  font-weight: 500; letter-spacing: -.03em; color: var(--after);
  line-height: 1.05; margin-bottom: 12px; font-variant-numeric: tabular-nums;
}
.pstat-l { font-size: calc(16px * var(--mk-text-scale)); line-height: 1.55; margin: 0 0 8px; }
.pstat-s {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); line-height: 1.55;
  color: var(--fg-annot); margin: 0;
}

/* the worked example — the arithmetic, shown. It is a plate (2px), like .fig. */
.calc { margin: var(--mk-space-6) 0; border-top: 2px solid var(--fg); }
.calc-cap {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--fg-annot);
  padding: 10px 0; border-bottom: 1px solid var(--rule);
}
.calc-row {
  display: grid; grid-template-columns: 1fr auto; gap: 16px;
  padding: 10px 0; border-bottom: 1px solid var(--rule);
  font-size: calc(15.5px * var(--mk-text-scale)); align-items: baseline;
}
.calc-v {
  font-family: var(--mk-font-data); font-size: calc(14px * var(--mk-text-scale));
  font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right;
}
.calc-row.is-em .calc-v { color: var(--after); font-weight: 500; }
.calc-total {
  border-bottom: 0; border-top: 2px solid var(--fg); font-weight: 600;
  padding-top: 13px;
}
.calc-total .calc-v { color: var(--after); font-size: calc(16px * var(--mk-text-scale)); font-weight: 500; }

/* the numbered cost list */
.costs { list-style: none; margin: var(--mk-space-6) 0; padding: 0; }
.costs li {
  display: grid; grid-template-columns: 30px 1fr; gap: 14px;
  padding: 12px 0; border-bottom: 1px solid var(--rule);
  font-size: calc(15.5px * var(--mk-text-scale)); line-height: 1.6;
}
.costs-n {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: .1em;
  color: var(--after); padding-top: 4px;
}
.costs li strong { display: block; font-weight: 600; margin-bottom: 2px; }

/* "what this does not tell you" — the brand, not a disclaimer */
.honesty {
  background: var(--ground-2); border-left: 2px solid var(--after);
  padding: 18px 20px; margin: var(--mk-space-6) 0; border-radius: var(--radius);
}
.honesty p { margin: 0; font-size: calc(15px * var(--mk-text-scale)); line-height: 1.65; color: var(--fg-dim); }
.honesty-label {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--after); margin: 0 0 7px !important;
  font-weight: 500;
}

/* the apparatus tier (E5): one quiet grey voice — same 12px sans + --fg-annot
   as .foots; the boundary is a row rule, never the in-between 1px --fg */
.srcs { margin: var(--mk-space-7) 0 0; padding-top: 20px; border-top: 1px solid var(--rule); }
.srcs-label {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--fg-annot); margin: 0 0 12px;
}
.srcs ol { margin: 0; padding-left: 1.6em; }
.srcs li {
  font-size: calc(12px * var(--mk-text-scale)); line-height: 1.6; color: var(--fg-annot); margin: 0 0 7px;
  font-family: var(--mk-font-ui);
}
.srcs a { color: var(--fg-annot); }
.srcs ::marker { color: var(--after); }
/* a long unbroken source URL must wrap inside the measure, never overflow it */
.srcs li, .foots li, .pano-fig-src, .src { overflow-wrap: anywhere; }

/* article-to-article continuation (E10) — quiet ruled rows, same-ofício only */
.rel { margin: var(--mk-space-6) 0 0; padding-top: 16px; border-top: 1px solid var(--rule); }
.rel ul { list-style: none; margin: 0; padding: 0; }
.rel li { border-bottom: 1px solid var(--rule); }
.rel li:last-child { border-bottom: 0; }
.rel a {
  display: block; padding: 12px 0; color: var(--fg); text-decoration: none;
  font-family: var(--mk-font-read); font-size: calc(17px * var(--mk-text-scale)); line-height: 1.4;
  transition: color .15s ease;
}
@media (hover: hover) { .rel a:hover { color: var(--after); } }

/* ═══ PANORAMA — the newsroom ═════════════════════════════════════════════
   Replaces 17,730 bytes of inline <style> that shipped on all SIX panorama
   pages (43-48% of a spoke's bytes). It reads on the same bone paper as every
   other page now, instead of being a second website in a different palette.

   TWO BODIES, ONE DATA SET: the phone stacks by vertical; the desktop is a
   newsroom of lens columns. Same cards, so the copy cannot drift between them.
   ═══════════════════════════════════════════════════════════════════════ */
.pano-mast { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 20px; }
.pano-ed {
  font-family: var(--mk-font-data); font-size: var(--mk-label); letter-spacing: .1em;
  text-transform: uppercase; color: var(--fg-annot); margin: 0;
}
.pano-back { font: inherit; letter-spacing: inherit; }

.pano-body--mobile { display: block; }
.pano-body--desktop { display: none; }
@media (min-width: 860px) {
  .pano-body--mobile { display: none; }
  .pano-body--desktop { display: block; }
}

/* ONE RULE PER SECTION BOUNDARY (2026-07-24). Panorama used to stack three
   full-width hairlines inside ~123px at every vertical: the section's own
   closing rule, then the next section's head rule 71px later, then the lens
   column labels' rule 52px after that — with nothing between them but a title
   and a 10px label. Five verticals, so the page carried 64 rules and read as
   ruled paper. The head rule is the one that earns its place: it is the
   newspaper section underline, it sits directly under the vertical's name, and
   it squares off the columns. The other two are gone; the SEAM does their work
   (16px card + 32px section + 22px head = 70px, wide enough to read as a break
   without the void the founder flagged). */
.pano-msec, .pano-d-vsec { padding: 8px 0 var(--mk-space-6); }
.pano-msec-head, .pano-d-sechead {
  display: flex; align-items: baseline; gap: 16px;
  padding: 22px 0 12px; border-bottom: 1px solid var(--rule); margin-bottom: 8px;
}
.pano-msec-label, .pano-d-seclabel { font-family: var(--mk-font-read); font-size: calc(19px * var(--mk-text-scale)); }
.pano-vertudo {
  margin-left: auto; font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--after);
  text-decoration: none; white-space: nowrap;
}
@media (hover: hover) { .pano-vertudo:hover { text-decoration: underline; } }

/* THE LENS IS NAMED ONCE. The card macro used to repeat this exact string as a
   green kicker on every card under it (card(ed, c, lens.label_pt) — the same
   variable), so each column opened with two near-identical 10px mono lines 20px
   apart, told apart only by colour. The rule between them was the only thing
   making that legible. Dropping the rule without dropping the duplicate would
   have made it worse, so the kicker is gone from the macro and THIS is the lens
   signal — which is why it takes the Mata accent the kicker used to carry. */
.pano-lens-tab, .pano-d-collabel {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--after); font-weight: 500;
  margin: 22px 0 2px;
}

/* the newsroom grid: one column per lens */
.pano-d-lenscols { display: grid; gap: 26px; grid-template-columns: repeat(3, 1fr); }
.pano-d-col { min-width: 0; }

.pano-card {
  display: block; padding: 16px 0; border-bottom: 1px solid var(--rule);
  text-decoration: none; color: inherit;
}
.pano-card:last-child { border-bottom: 0; }
@media (hover: hover) { .pano-card:hover .pano-card-title { color: var(--after); } }
/* .pano-card-cat is retired — see the lens-label note above. The lead keeps its
   own kicker (.pano-lead-cat): it sits above both bodies with no column label
   over it, so there it is the only thing naming the vertical and the lens. */
.pano-card-title {
  font-family: var(--mk-font-read); font-size: calc(17px * var(--mk-text-scale)); line-height: 1.3;
  margin: 0 0 7px; transition: color .15s ease; text-wrap: pretty;
}
.pano-card-dek { margin: 0 0 10px; color: var(--fg-dim); font-size: calc(14.5px * var(--mk-text-scale)); line-height: 1.55; }

/* THE FIGURE AND ITS SOURCE. The `fonte:` is not decoration — it is the claim.
   Panorama's whole position is that its numbers are attributable. */
.pano-fig {
  margin: 0 0 6px; padding: 9px 12px; background: var(--ground-2);
  border-left: 2px solid var(--after); font-size: calc(13.5px * var(--mk-text-scale)); line-height: 1.5;
}
.pano-fig b { font-family: var(--mk-font-data); font-size: calc(13px * var(--mk-text-scale)); color: var(--fg); }
.pano-fig-claim { color: var(--fg-dim); }
.pano-fig-src {
  margin: 0 0 10px; font-family: var(--mk-font-data); font-size: var(--mk-cap);
  letter-spacing: .06em; color: var(--fg-annot);
}
.pano-fig-src a { color: var(--fg-annot); text-decoration: underline; }
@media (hover: hover) { .pano-fig-src a:hover { color: var(--after); } }
.pano-card-meta {
  margin: 0; font-family: var(--mk-font-data); font-size: var(--mk-cap);
  letter-spacing: .11em; text-transform: uppercase; color: var(--fg-annot);
}

.pano-ml { border-top: 1px solid var(--rule); padding-top: 22px; margin-top: 8px; }
.pano-ml-head { font-family: var(--mk-font-read); font-size: calc(18px * var(--mk-text-scale)); margin: 0; }
.pano-ml-sub {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--fg-annot); margin: 2px 0 14px;
}
.pano-ml-list { list-style: none; margin: 0; padding: 0; }
.pano-ml-item {
  display: grid; grid-template-columns: 3.5ch 1fr; gap: 14px; align-items: baseline;
  padding: 11px 0; border-bottom: 1px solid var(--rule);
  text-decoration: none; color: inherit;
}
/* the reset every other list here already had (.pano-card:1082, .rel li:1024,
   .tbl tr:501, .wf-row:1304) and this one was missing — so "Mais lidas" closed
   on a rule with nothing under it, directly above the stage band. */
.pano-ml-list li:last-child .pano-ml-item { border-bottom: 0; }
@media (hover: hover) { .pano-ml-item:hover .pano-ml-title { color: var(--after); } }
.pano-ml-num {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); color: var(--fg-annot);
  font-variant-numeric: tabular-nums;
}
.pano-ml-title { font-size: calc(16px * var(--mk-text-scale)); transition: color .15s ease; }
@media (prefers-reduced-motion: reduce) {
  .pano-card-title, .pano-ml-title { transition: none; }
}

/* the lead: one card, featured. The edition names it; the D4 gate proves it resolves. */
.pano-hero { padding: 22px 0 6px; }
.pano-lead { display: block; text-decoration: none; color: inherit; }
.pano-lead-cat {
  display: block; font-family: var(--mk-font-data); font-size: var(--mk-cap);
  letter-spacing: var(--mk-cap-track); text-transform: uppercase; color: var(--after); margin-bottom: 10px;
}
.pano-lead-title {
  font-family: var(--mk-font-read); font-size: clamp(24px, 3vw, 33px); line-height: 1.16;
  letter-spacing: -.015em; margin: 0 0 12px; max-width: 26ch; text-wrap: balance;
  transition: color .15s ease;
}
@media (hover: hover) { .pano-lead:hover .pano-lead-title { color: var(--after); } }
.pano-lead-dek { margin: 0 0 12px; color: var(--fg-dim); font-size: calc(16.5px * var(--mk-text-scale)); max-width: 56ch; text-wrap: pretty; }
.pano-lead-meta {
  margin: 0; font-family: var(--mk-font-data); font-size: var(--mk-cap);
  letter-spacing: .11em; text-transform: uppercase; color: var(--fg-annot);
}
@media (prefers-reduced-motion: reduce) { .pano-lead-title { transition: none; } }

/* ═══ PRIVACIDADE — a legal instrument that still has to be readable ══════ */
.priv-resumo { margin: 8px 0 0; padding-left: 18px; }
.priv-resumo li { font-size: calc(15px * var(--mk-text-scale)); line-height: 1.6; color: var(--fg-dim); margin-bottom: 7px; }
.art-toc ol { margin: 8px 0 0; padding-left: 20px; }
.art-toc li { font-size: calc(15px * var(--mk-text-scale)); line-height: 1.75; }
/* the policy's own prose: bare <p>/<ul>/<table> emitted from the record's `html` */
.art > p, .art > ul, .art > ol { font-size: calc(16.5px * var(--mk-text-scale)); line-height: 1.7; max-width: var(--mk-measure); }
.art > p { text-wrap: pretty; }
.art > ul, .art > ol { padding-left: 20px; }
.art > ul li, .art > ol li { margin-bottom: 8px; color: var(--fg-dim); }
.art .table-wrap { overflow-x: auto; margin: 18px 0; }
.art .table-wrap table { width: 100%; border-collapse: collapse; font-size: calc(14.5px * var(--mk-text-scale)); }
.art .table-wrap th, .art .table-wrap td {
  text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--rule); vertical-align: top;
}
.art .table-wrap th { font-family: var(--mk-font-data); font-size: var(--mk-label); letter-spacing: .08em;
  text-transform: uppercase; color: var(--fg-annot); }
/* biography PROSE — it rides on a .note (mono) in the markup, but prose never
   wears the data register (1D sweep finding); the quiet UI voice, like .foots */
.sig-bio { margin-top: var(--mk-space-5) !important; font-size: calc(12px * var(--mk-text-scale)) !important; line-height: 1.6; max-width: var(--mk-measure); font-family: var(--mk-font-ui); }
.carta-by { margin: 18px 0 30px !important; letter-spacing: .1em; text-transform: uppercase; }
.signature { display: flex; gap: 18px; align-items: flex-start; margin: 40px 0 0;
  padding-top: 26px; border-top: 1px solid var(--rule); }
.sig-photo { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; flex: none; }
.sig-name { font-family: var(--mk-font-read); font-size: calc(17px * var(--mk-text-scale)); margin: 0; }
.sig-role { font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--fg-annot); margin: 3px 0 0; }

/* the founder's pull-quote — the one line the letter wants you to keep */
.pull {
  font-family: var(--mk-font-read); font-size: calc(21px * var(--mk-text-scale)); line-height: 1.4;
  border-left: 2px solid var(--after); padding: 4px 0 4px 20px;
  margin: var(--mk-space-5) 0; max-width: 44ch; color: var(--fg);
}
.pull em { color: var(--after); font-style: italic; }
/* Links inside long-form prose (a Biblioteca article, the letter, the policy's own HTML
   blocks). Without this they fall to the user-agent default blue. */
.art p a, .art li a, .art td a, .art dd a { color: var(--after); }
.shelf-tools { margin-top: 14px !important; }
.shelf-tools a { color: var(--after); }

/* ═══ TOUCH TARGETS ═══════════════════════════════════════════════════════
   The document's small mono controls are precise under a cursor and hostile
   under a thumb. On coarse pointers every interactive control reaches the
   44px Apple HIG minimum — by padding, never by changing its face.
   ═══════════════════════════════════════════════════════════════════════ */
@media (pointer: coarse) {
  .chip { min-height: 44px; align-items: center; }
  .variant-btn { min-height: 44px; }
  .swap button { min-height: 44px; padding: 9px 2px; }
  .tool-seg button { min-height: 44px; }
  .area-bar-btn { min-height: 44px; display: inline-flex; align-items: center; }
  .area-modal-x { width: 44px; height: 44px; top: 4px; right: 4px; }
  .cluster-btn { min-height: 48px; }
  /* the footnote ref: a 10px superscript is a hostile target — pad the hit
     box without moving the glyph */
  .fn { padding: 10px 6px; margin: -10px -6px; }
}

/* ═══ TOOLS — the interactive pages (/tools/**) ═══════════════════════════
   The revenue-diagnostic form and the effective-rate calculator used to be
   two standalone pages carrying the RETIRED v4 palette in their own inline
   <style> — a different brand two clicks from the landing. They read on the
   document system now: bone paper, ruled panels, the figures in mono. These
   are the site's only form controls, so the primitives live here, not in a
   page.
   ═══════════════════════════════════════════════════════════════════════ */
.tool-grid { display: grid; gap: var(--mk-space-6); margin-top: var(--mk-space-6); }
@media (min-width: 860px) { .tool-grid { grid-template-columns: 1fr 1fr; align-items: start; } }

/* a panel is a ruled region of the document, not a card */
.tool-panel { border-top: 2px solid var(--fg); padding-top: 16px; }
.tool-panel-label {
  font-family: var(--mk-font-data); font-size: var(--mk-cap); letter-spacing: var(--mk-cap-track);
  text-transform: uppercase; color: var(--fg-annot); margin: 0 0 16px;
}

.tool-field { margin: 0 0 20px; }
.tool-field:last-child { margin-bottom: 0; }
.tool-lab {
  display: block; font-family: var(--mk-font-ui); font-size: calc(14px * var(--mk-text-scale));
  font-weight: 500; margin-bottom: 6px;
}
.tool-hint { font-size: calc(13px * var(--mk-text-scale)); line-height: 1.5; color: var(--fg-dim); margin: 0 0 8px; }
.tool-proxy { color: var(--after); font-weight: 500; }

/* 16px IS THE FIX, not a taste call. iOS Safari auto-zooms the viewport on focus
   for ANY control rendering under 16px, and does NOT zoom back out on blur — the
   reader taps a field and is left on a cropped page. That is the zoom jitter on
   the tools pages. The wrong cure is user-scalable=no in the viewport meta: it
   fails WCAG 2.2 SC 1.4.4, and iOS has ignored it since iOS 10, so it would take
   zoom away from Android readers while fixing nothing here. */
.tool-input, .tool-select, .tool-textarea {
  width: 100%; font-size: calc(16px * var(--mk-text-scale)); padding: 10px 12px;
  border: 1px solid var(--rule); border-radius: var(--radius);
  background: var(--ground); color: var(--fg);
  -webkit-appearance: none; appearance: none;
}
.tool-input { font-family: var(--mk-font-data); font-variant-numeric: tabular-nums; }
/* words are UI register; only figures read in mono */
.tool-input[type="text"], .tool-select, .tool-textarea { font-family: var(--mk-font-ui); }
.tool-textarea { min-height: 84px; resize: vertical; line-height: 1.5; }
.tool-input:focus-visible, .tool-select:focus-visible, .tool-textarea:focus-visible {
  outline: 2px solid var(--focus); outline-offset: 2px; /* unified focus offset (E6 chrome) */
}
/* ≥16px on phones so iOS Safari never auto-zooms on focus */
@media (max-width: 600px) {
  .tool-input, .tool-select, .tool-textarea { font-size: calc(16px * var(--mk-text-scale)); }
}

/* the segmented pick (tax regime, presets) — the chip, doing a button's job */
.tool-seg { display: flex; gap: 7px; flex-wrap: wrap; }
.tool-seg button {
  appearance: none; cursor: pointer; background: transparent;
  border: 1px solid var(--rule); border-radius: var(--radius);
  font-family: var(--mk-font-ui); font-size: calc(12.5px * var(--mk-text-scale)); padding: 9px 14px;
  color: var(--fg-dim); min-height: 40px;
}
@media (hover: hover) { .tool-seg button:hover { border-color: var(--fg); color: var(--fg); } }
.tool-seg button.on { background: var(--after); border-color: var(--after); color: var(--ground); }

.tool-range { width: 100%; accent-color: var(--after); margin-top: 6px; }
.tool-rangeval {
  font-family: var(--mk-font-data); font-size: calc(13px * var(--mk-text-scale)); color: var(--after);
  font-variant-numeric: tabular-nums;
}
.tool-check {
  display: flex; align-items: center; gap: 9px; cursor: pointer; user-select: none;
  font-family: var(--mk-font-ui); font-size: calc(13.5px * var(--mk-text-scale)); color: var(--fg-dim);
}
.tool-check input { width: 18px; height: 18px; accent-color: var(--after); flex: none; }

.cta--block { width: 100%; justify-content: center; }

.tool-msg { font-size: calc(13.5px * var(--mk-text-scale)); margin: 12px 0 0; min-height: 1.2em; color: var(--fg-dim); }
.tool-msg.ok { color: var(--after); }
.tool-msg.err { color: var(--fg); border-left: 2px solid var(--before); padding-left: 10px; }

/* the result: a figure of the document — mono, in the architected colour */
.tool-big {
  font-family: var(--mk-font-data); font-size: clamp(34px, 7vw, 52px); font-weight: 500;
  letter-spacing: -.03em; line-height: 1.05; color: var(--after);
  font-variant-numeric: tabular-nums;
}
.tool-big small { font-size: calc(20px * var(--mk-text-scale)); font-weight: 400; }
.tool-frac { font-size: calc(15px * var(--mk-text-scale)); color: var(--fg-dim); margin: 8px 0 0; }
.tool-frac b { color: var(--fg); font-weight: 600; }

/* the waterfall — the calculator's own worked example, same bones as .calc.
   A plate (2px), like .calc — never the in-between 1px --fg. */
.wf { margin-top: var(--mk-space-5); border-top: 2px solid var(--fg); padding-top: 4px; }
.wf-row {
  display: grid; grid-template-columns: 1fr auto; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--rule); align-items: baseline;
}
.wf-row:last-child { border-bottom: 0; }
.wf-name { font-size: calc(14px * var(--mk-text-scale)); }
.wf-name span { display: block; font-size: calc(12px * var(--mk-text-scale)); color: var(--fg-annot); }
.wf-val {
  font-family: var(--mk-font-data); font-size: calc(13.5px * var(--mk-text-scale)); color: var(--fg-dim);
  font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right;
}
.wf-row.start .wf-val, .wf-row.mid .wf-val { color: var(--fg); }
.wf-row.total { margin-top: 4px; padding-top: 12px; border-top: 2px solid var(--fg); border-bottom: 0; }
.wf-row.total .wf-name { font-weight: 600; }
.wf-row.total .wf-val { color: var(--after); font-weight: 500; font-size: calc(15px * var(--mk-text-scale)); }
/* the loss bar: Terra as a FILL — never as text (2.4:1 on paper). Scoped under
   .wf-name because this file is shared with the customer app and `.bar` is too
   generic a name to claim globally. */
.wf-name .bar { height: 4px; background: var(--ground-2); margin-top: 6px; overflow: hidden; }
.wf-name .bar > i { display: block; height: 100%; background: var(--before); }

/* the reading the diagnostic returns */
.tool-reading-k {
  font-family: var(--mk-font-data); font-size: calc(12px * var(--mk-text-scale)); letter-spacing: .1em;
  text-transform: uppercase; color: var(--after); margin: 0 0 10px; font-weight: 500;
}
.tool-reading { font-size: calc(16.5px * var(--mk-text-scale)); line-height: 1.65; margin: 0; white-space: pre-wrap; }

/* the sources fold (calculator) */
.tool-sources { margin: 28px 0; }
.tool-sources summary {
  cursor: pointer; font-family: var(--mk-font-data); font-size: var(--mk-label);
  letter-spacing: var(--mk-label-track); text-transform: uppercase; color: var(--after);
  padding: 8px 0; list-style: none;
}
.tool-sources summary::-webkit-details-marker { display: none; }
.tool-sources ul { list-style: none; margin: 10px 0 0; padding: 0; }
.tool-sources li {
  font-family: var(--mk-font-ui); font-size: calc(13px * var(--mk-text-scale)); color: var(--fg-dim); line-height: 1.55;
  padding: 5px 0 5px 14px; position: relative;
}
.tool-sources li::before { content: "·"; position: absolute; left: 0; color: var(--after); }

/* ═══ MOTION — THE 150ms SETTLE ═══════════════════════════════════════════
   E8: one hover behaviour, everywhere — a 150ms colour/border settle. The
   controls whose rules predate the standard read this grouped transition;
   every :hover rule in the file is wrapped in @media (hover: hover) so
   nothing sticks on touch. */
.runhead a, .chip, .door, .toc-t a, .art-toc a, .variant-btn, .tool-seg button,
.area-modal-x, .area-bar-btn, .foots a, .srcs a, .acts a:not(.cta), .note a {
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
@media (hover: hover) { .area-bar-btn:hover { text-decoration: underline; } }

/* ═══ MOTION — THE HEARTBEAT (opf-heart) ══════════════════════════════════
   The one ambient motion the doctrine sanctions (motion doctrine v4, brand
   amendment D4): a quiet double-beat on the mark's core — the organism is
   alive; nothing else on the page moves on its own. ~2.6s cycle: lub, dub,
   rest. Opacity only (compositor); gated on reduced-motion. The doctrine
   names web/assets/motion.css as its home — that file belonged to the
   pre-rebuild static site; on the template system this component layer IS
   the marketing CSS, so the primitive lives here under its doctrine names
   (`opf-heart`, `[data-opf-heart]`). */
@keyframes opf-heart {
  0%, 20%, 100% { opacity: 1; }
  5%  { opacity: .35; }
  9%  { opacity: 1; }
  13% { opacity: .5; }
}
@media (prefers-reduced-motion: no-preference) {
  [data-opf-heart]::after { animation: opf-heart 2.6s ease-in-out infinite; }
}

/* ═══ SPACING UTILITIES ═══════════════════════════════════════════════════
   The ONLY sanctioned replacement for inline template margins (E3 retired the
   style="margin-top:…" leaks). Ramp values only. Last in the file on purpose:
   a utility must win the tie against any component shorthand above. */
.mt-2 { margin-top: var(--mk-space-2); }
.mt-5 { margin-top: var(--mk-space-5); }
.mt-6 { margin-top: var(--mk-space-6); }
.mt-7 { margin-top: var(--mk-space-7); }
