/* The site's own stylesheet.
 *
 * Colour and radius come from assets/tokens.css, which is VENDORED from the
 * application and MUST NOT BE EDITED HERE. This file adds only what the app has
 * no opinion about: the marketing type scale, the vault band, and the
 * dimension line.
 *
 * Two deliberate departures from the application's ui.md, both recorded in
 * docs/design/README.md § Where it departs from ui.md — the dark hero band, and
 * a display scale above the app's largest role. Do not "fix" either; do not add
 * a third without recording it there.
 */

:root {
  /* Not in tokens.css — the application sets its sans stack in Tailwind config
   * rather than as a custom property. Same family, same four weights. */
  --v-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif;

  /* THE VAULT BAND — an alias layer over Nord Polar Night values the app
   * already owns. NO NEW COLOUR IS INTRODUCED, which is what keeps the
   * departure a layout decision rather than a palette one. */
  --m-vault: #242933;
  --m-vault-2: #2E3440;
  --m-vault-ink: #ECEFF4;
  --m-vault-muted: #C2C9D6;
  --m-vault-faint: #828C9E;
  --m-vault-line: #3B4252;
  --m-vault-accent: #81A1C1;
  --m-vault-accent-hover: #88C0D0;
  --m-vault-btn-ink: #1B2028;
  --m-vault-chip: rgba(129, 161, 193, .13);
}

/* Keyed off the viewer's preference, matching the pattern the vendored
 * tokens.css uses — including its [data-theme="light"] opt-out. In dark the
 * vault steps down so the band still reads as darker than the ground below it,
 * and the hard cut between the two halves survives both themes. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --m-vault: #1B2028;
    --m-vault-2: #242933;
    --m-vault-line: #343C4A;
  }
}

* { box-sizing: border-box; }

/* THE `hidden` ATTRIBUTE HAS TO WIN, AND WITHOUT THIS IT DOES NOT.
 *
 * `hidden` works by a UA rule of `display: none`, which ANY author `display`
 * declaration outranks — so the moment an element that gets toggled is also
 * given `display: flex` or `grid`, the attribute silently stops doing anything.
 *
 * That is not hypothetical. The contact form is `hidden` in the markup and
 * revealed by /scripts/contact.js, and `.contact-ask form { display: flex }`
 * made it visible anyway: a visitor without JavaScript was shown the sentence
 * saying the form cannot work AND a fully rendered form directly beneath it,
 * and the success state could not replace the form it was meant to replace.
 * Nothing reported it — the markup was right and the attribute was right.
 *
 * `!important` is the whole point rather than a shortcut: the rule has to beat
 * author declarations it cannot know about in advance, and every other tool
 * here (higher specificity, source order) loses to the next `display` someone
 * adds. This is the one in the file, and it is why. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--v-ground);
  color: var(--v-ink);
  font-family: var(--v-sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--v-accent);
  outline-offset: 3px;
  border-radius: var(--v-radius-focus);
}
.vault :focus-visible { outline-color: var(--m-vault-accent); }

/* For a label that names a control the sighted reader can already see named by
 * its placeholder. Not display:none — that would take it out of the
 * accessibility tree, which is the one place it is needed. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Layout scaffolding ----------
   Bands own vertical rhythm. Component classes never set band padding, so
   nothing cancels out in the cascade. */
.wrap { width: min(1080px, 100% - 48px); margin-inline: auto; }
.band { padding-block: 104px; }
.band-tight { padding-block: 72px; }

.eyebrow {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  line-height: 1.4;
  /* MUTED, NOT FAINT, AND THAT IS A CONTRAST FIX RATHER THAN A TONAL CHOICE.
   * --v-ink-faint on --v-ground is 2.63:1 at this size — under the 4.5:1 AA
   * floor and under even the 3:1 large-text allowance, which would not apply
   * at 10.5px anyway. These labels are the only thing naming the section a
   * reader is in, so they were the page's least readable text and its whole
   * wayfinding at once. --v-ink-muted is 5.70:1.
   *
   * The label still reads as a label: size, 600 weight, uppercase and the
   * letter-spacing below carry that, not the colour alone. There is no token
   * between faint and muted, and tokens.css is vendored — a dimmer variant
   * that still clears AA would have to be added in the application. */
  color: var(--v-ink-muted);
  margin: 0;
}
/* Same 4.5:1 correction as .eyebrow above, on the dark ground: --m-vault-faint
 * is 4.30:1 on the vault and --m-vault-muted is 8.76:1. The word this affects
 * is `Aufbewahrungspflicht`, which labels the statute beside it. The citation
 * itself was already fine — .cite below is 5.42:1. */
.vault .eyebrow { color: var(--m-vault-muted); }
.vault .eyebrow .cite {
  font-family: var(--v-mono);
  letter-spacing: 0.04em;
  color: var(--m-vault-accent);
}

/* ============================================================
   THE VAULT BAND
   ============================================================ */
.vault { background: var(--m-vault); color: var(--m-vault-ink); }

/* Two tiers. The meta bar carries things that change how you see the site
 * (language) or who you are (sign in); the row below carries destinations.
 * In one row, the language control read as a menu item, which it is not. */
.metabar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding-block: 8px;
  border-bottom: 1px solid var(--m-vault-line);
}
/* Muted, not faint: this is the sign-in link, so it is a control an existing
 * customer has to find, and --m-vault-faint puts it at 4.30:1 on the vault —
 * the same shortfall as the eyebrows above. --m-vault-muted is 8.76:1, and the
 * link stays quiet by being 12.5px in a bar of its own rather than by being
 * hard to read. */
.metabar > a {
  font-size: 12.5px;
  color: var(--m-vault-muted);
  text-decoration: none;
}
.metabar > a:hover { color: var(--m-vault-ink); }
.metabar .meta-sep { color: var(--m-vault-line); font-size: 12px; user-select: none; }

/* Three locales, so show all three rather than hiding them behind a dropdown. */
.locales {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--m-vault-line);
  border-radius: var(--v-radius-focus);
  overflow: hidden;
}
.locales a {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--m-vault-faint);
  text-decoration: none;
  border-right: 1px solid var(--m-vault-line);
  padding: 3px 9px;
  transition: color .15s ease, background-color .15s ease;
}
.locales a:last-child { border-right: 0; }
.locales a:hover { color: var(--m-vault-ink); }
/* Attribute presence, NOT [aria-current="page"]. header.njk emits `page` only
 * where the link really does point at the page being read — the home pages —
 * and `true` everywhere else, so a value match would leave the 404 with no
 * language marked at all. The fill means "this is the language you are
 * reading", which is equally true on both. */
.locales a[aria-current] {
  color: var(--m-vault-btn-ink);
  background: var(--m-vault-accent);
}
/* The abbr carries the language's endonym as its title; it must not inherit the
 * dotted underline and help cursor, which would suggest a definition. */
.locales abbr { text-decoration: none; cursor: inherit; }

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-block: 18px;
  border-bottom: 1px solid var(--m-vault-line);
  flex-wrap: wrap;
  /* The containing block for .navmenu-panel, which hangs below this row at
     phone width. Positioned on the ROW rather than on .navmenu so the panel
     spans the full .wrap, not the width of the control that opens it. The
     z-index keeps it over the band beneath, whose hero has none of its own. */
  position: relative;
  z-index: 10;
}
.brand {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--m-vault-ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.brand i {
  width: 3px;
  height: 17px;
  background: var(--m-vault-accent);
  border-radius: var(--v-radius-pill);
  display: block;
}
.topnav { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.topnav a.navlink {
  font-size: 13.5px;
  color: var(--m-vault-muted);
  text-decoration: none;
}
.topnav a.navlink:hover { color: var(--m-vault-ink); }

/* ── The phone disclosure (#91) ──────────────────────────────────────────────
   Hidden entirely above 760px — display:none, not merely collapsed, so the four
   destinations are never in the accessibility tree twice. The media query at
   the foot of this file is the only place it is switched on. */
/* NO `position` HERE ON PURPOSE. The panel below is absolute against .topbar,
   which is what makes it span the full .wrap; making this element a containing
   block anchors the panel to the width of the word "Menü" instead, which is
   what the first attempt did. */
.navmenu { display: none; }
.navmenu > summary {
  font-size: 13.5px;
  color: var(--m-vault-muted);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border: 1px solid var(--m-vault-line);
  border-radius: var(--v-radius-pill);
  /* Both are needed: the standard property and the WebKit pseudo-element. The
     default marker is a filled triangle that would sit beside the caret below
     and read as a second control. */
  list-style: none;
}
.navmenu > summary::-webkit-details-marker { display: none; }
.navmenu > summary:hover { color: var(--m-vault-ink); }
/* The caret is two borders on a rotated square — no glyph, so it cannot pick up
   a font that renders it differently, and no image to load for one 6px mark. */
.navmenu > summary::after {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform .15s ease;
}
.navmenu[open] > summary::after { transform: translateY(1px) rotate(225deg); }
.navmenu-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  /* Clears this row's bottom border rather than sitting on it. */
  margin-top: 18px;
  display: flex;
  flex-direction: column;
  background: var(--m-vault-2);
  border: 1px solid var(--m-vault-line);
  border-radius: var(--v-radius);
  padding: 6px 0;
}
.navmenu-panel a {
  font-size: 15px;
  color: var(--m-vault-muted);
  text-decoration: none;
  /* A row, not a word: the whole width is the target, which is what a thumb
     expects of a list like this. 44px tall at this padding and line height. */
  padding: 12px 18px;
}
.navmenu-panel a:hover { color: var(--m-vault-ink); background: var(--m-vault-chip); }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.005em;
  padding: 9px 16px;
  border-radius: var(--v-radius-control);
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease;
}
.btn-primary { background: var(--v-accent-fill); color: var(--v-accent-ink); }
.btn-primary:hover { background: var(--v-accent-fill-hover); }
.vault .btn-primary { background: var(--m-vault-accent); color: var(--m-vault-btn-ink); }
.vault .btn-primary:hover { background: var(--m-vault-accent-hover); }
.btn-lg { font-size: 15px; padding: 13px 22px; }

/* ---------- Hero ---------- */
.hero { padding-block: 58px 82px; }

.hero h1 {
  margin: 18px 0 0;
  font-size: 68px;
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 1.02;
  text-wrap: balance;
  /* ch at the h1's own size, so the measure holds across three languages of
   * different length. px would only fit German. */
  max-width: 19ch;
}
.hero .lede {
  margin: 26px 0 0;
  font-size: 19px;
  line-height: 1.5;
  letter-spacing: -0.01em;
  color: var(--m-vault-muted);
  max-width: 46ch;
}
.hero-cta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 18px;
  margin-top: 36px;
}
.hero-cta .fine { font-size: 13px; color: var(--m-vault-faint); }

/* ---------- SIGNATURE: the retention span ----------
   A dimension line — the drafting convention for "this span measures X". The
   span is data: 7 years or 10, from the domain, emitted by the build. */
.record { margin-top: 56px; }

.rowcard {
  background: var(--m-vault-2);
  border: 1px solid var(--m-vault-line);
  border-radius: var(--v-radius);
  padding: 16px 20px;
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 20px;
}
.rowcard .ref {
  font-family: var(--v-mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--m-vault-accent);
  white-space: nowrap;
}
.rowcard .party { font-size: 14.5px; font-weight: 600; letter-spacing: -0.01em; }
.rowcard .kind {
  font-size: 12px;
  font-weight: 600;
  color: var(--m-vault-muted);
  background: var(--m-vault-chip);
  border-radius: var(--v-radius-pill);
  padding: 3px 11px;
  white-space: nowrap;
}
.rowcard .amt {
  font-size: 14.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.rule-stem { width: 1px; height: 22px; background: var(--m-vault-line); margin-left: 28px; }
.dim { position: relative; height: 38px; }
.dim-line { position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--m-vault-line); }
.dim-fill {
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 1px;
  background: var(--m-vault-accent);
  transform-origin: left center;
  animation: draw 1400ms cubic-bezier(.16,.84,.36,1) 400ms both;
}
@keyframes draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }

.dim-cap {
  position: absolute;
  top: 9px; bottom: 9px;
  width: 2px;
  background: var(--m-vault-accent);
  border-radius: var(--v-radius-pill);
}
.dim-cap.left { left: 0; }
.dim-cap.right { right: 0; opacity: 0; animation: tickin 400ms ease 1700ms both; }

/* One column per year of the span. --years and each tick's --d are written by
 * the build from the jurisdiction record, so the count of ticks cannot drift
 * from the number spelled out in the headline. */
.ticks {
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 9px;
  display: grid;
  grid-template-columns: repeat(var(--years), 1fr);
  pointer-events: none;
}
.ticks i {
  display: block;
  border-right: 1px solid var(--m-vault-line);
  opacity: 0;
  animation: tickin 400ms ease both;
  animation-delay: calc(var(--d) * 1ms);
}
.ticks i:last-child { border-right: 0; }
@keyframes tickin { to { opacity: 1; } }

.dim-label {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  background: var(--m-vault);
  padding: 0 14px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--m-vault-accent);
  white-space: nowrap;
  opacity: 0;
  animation: tickin 500ms ease 1800ms both;
}

.rule-legend { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; margin-top: 12px; }
.rule-legend .end { display: flex; flex-direction: column; gap: 2px; }
.rule-legend .end.right { text-align: right; }
.rule-legend b { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.rule-legend span {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--m-vault-faint);
}

/* ============================================================
   LIGHT BODY
   ============================================================ */
.band h2 {
  margin: 14px 0 0;
  font-size: 34px;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.15;
  text-wrap: balance;
  max-width: 24ch;
}
.band .intro { margin: 16px 0 0; font-size: 16px; color: var(--v-ink-muted); max-width: 58ch; }

.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-top: 52px; }

/* THE PRODUCT SCREENSHOT — /features/ § Bestätigen and /guides/ § Der Posteingang.
 *
 * One rule set, because there is one image and it is the same file on both
 * pages. It scales fluidly and carries the same border and radius as a .card,
 * so it reads as a framed thing on the page rather than as a bitmap dropped
 * onto it.
 *
 * THE IMAGE IS LIGHT IN BOTH SCHEMES, deliberately: it is a photograph of the
 * application in its light theme, and there is one image rather than six
 * (vaultivo ADR 0108). So the frame is what adapts — var(--v-line) resolves per
 * scheme — and the picture does not. Do not add a filter to "match" dark mode;
 * dimming or inverting a screenshot makes it a picture of a product nobody has.
 */
.shot { margin: 44px 0 0; }
.shot img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--v-line);
  border-radius: var(--v-radius);
}
.shot figcaption {
  margin-top: 12px;
  font-size: 13px;
  color: var(--v-ink-faint);
  line-height: 1.5;
}
.card {
  background: var(--v-surface);
  border: 1px solid var(--v-line);
  border-radius: var(--v-radius);
  padding: 26px 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.card h3 { margin: 0; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.card p { margin: 0; font-size: 14px; color: var(--v-ink-muted); line-height: 1.55; }
/* overflow-wrap, not a truncation: the address is shown in full because its
 * length and illegibility are the point being made about it. */
.card .addr {
  font-family: var(--v-mono);
  font-size: 12.5px;
  color: var(--v-accent);
  background: var(--v-accent-soft);
  border-radius: var(--v-radius-control);
  padding: 8px 11px;
  overflow-wrap: anywhere;
  margin-top: auto;
}

/* The pipeline is a real sequence, so it is an ordered list and it is numbered.
 * The marker is drawn from the copy, not from the list, so it can be mono and
 * tabular; the <ol> carries the semantics. */
.stages { margin: 52px 0 0; padding: 0; list-style: none; border-top: 1px solid var(--v-line); }
.stage {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 24px;
  padding: 22px 0;
  border-bottom: 1px solid var(--v-line);
  align-items: baseline;
}
.stage .n {
  font-family: var(--v-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--v-accent);
  font-variant-numeric: tabular-nums;
}
.stage h3 { margin: 0 0 4px; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.stage p { margin: 0; font-size: 14px; color: var(--v-ink-muted); max-width: 62ch; }

.note {
  margin-top: 26px;
  font-size: 14px;
  color: var(--v-ink-muted);
  border-left: 2px solid var(--v-accent);
  padding-left: 16px;
  max-width: 62ch;
}

/* A link inside a .note has to read as one. Everything else in the block is
   muted body text at the same size, so inheriting `color` left the link
   distinguished by its underline alone — the same problem .notfound .closing
   .fine already solves, solved the same way rather than a second way. */
.note a {
  color: var(--v-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.note a:hover { color: var(--v-accent-strong); }

/* ---------- Search ---------- */
.searchbox {
  margin-top: 44px;
  background: var(--v-surface);
  border: 1px solid var(--v-line);
  border-radius: var(--v-radius);
  overflow: hidden;
}
.searchfield { display: flex; align-items: center; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--v-line); }
.searchfield svg { flex: none; color: var(--v-ink-faint); }
.searchfield input {
  flex: 1;
  border: 0;
  background: transparent;
  font-family: inherit;
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--v-ink);
  padding: 0;
  min-width: 0;
  /* type="search" so the browser offers a clear affordance; the UA's own inset
   * and rounding would fight the field it sits in. */
  appearance: none;
  -webkit-appearance: none;
}
.searchfield input:focus { outline: none; }
.searchfield input::placeholder { color: var(--v-ink-faint); font-weight: 400; }
/* The field ships disabled and /scripts/search.js enables it, so this is what a
 * visitor without JavaScript sees. It should read as "not available", not as
 * "broken" — the result list beside it is complete and correct. */
.searchfield input:disabled { cursor: not-allowed; opacity: .65; -webkit-text-fill-color: var(--v-ink-faint); }

.chips {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 14px 20px;
  background: var(--v-surface-2);
  border-bottom: 1px solid var(--v-line);
}
.chips .lbl {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--v-ink-faint); margin-right: 4px;
}
.chip {
  font-family: var(--v-mono);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--v-ink-muted);
  background: var(--v-surface);
  border: 1px solid var(--v-line);
  border-radius: var(--v-radius-pill);
  padding: 4px 12px;
  cursor: pointer;
}
.chip:hover:not(:disabled) { border-color: var(--v-accent); color: var(--v-accent); }
.chip:disabled { cursor: not-allowed; opacity: .6; }

.results { list-style: none; margin: 0; padding: 0; }
.results li {
  display: grid;
  grid-template-columns: 176px 1fr 128px 96px;
  gap: 18px;
  align-items: center;
  padding: 13px 20px;
  border-bottom: 1px solid var(--v-line);
  font-size: 14px;
}
/* The script filters by toggling [hidden], and `display: grid` above would
 * otherwise beat the UA's `[hidden] { display: none }`. Without this rule the
 * filter does nothing visible at all. */
.results li[hidden] { display: none; }
.results li:last-child { border-bottom: 0; }
/* --v-accent-strong, not --v-accent: on the white panel the plain accent is
 * 4.03:1, which is the same shortfall tokens.css records for white-on-accent
 * and solves the same way. The strong variant is 5.26:1. */
.results .r-ref {
  font-family: var(--v-mono); font-size: 12.5px; letter-spacing: 0.02em;
  color: var(--v-accent-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.results .r-title { font-size: 13.5px; color: var(--v-ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.results .r-party { font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.results .r-date { font-size: 13px; color: var(--v-ink-muted); font-variant-numeric: tabular-nums; }
.results .r-amt { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.tally { padding: 12px 20px; font-size: 12.5px; font-weight: 500; color: var(--v-ink-faint); background: var(--v-surface-2); font-variant-numeric: tabular-nums; }

/* ---------- Tables ----------
   THE SHELL AND THE ROW RHYTHM ARE SHARED; only the cell treatments below are
   per-table. `.tablewrap table` rather than `table.ret`, because the retention
   table stopped being the only one when the features page landed a formats spec
   (#25) — and the alternative was a second copy of the same eight rules, drifting
   from the first the moment either changed.

   Both tables scroll inside the wrapper rather than widening the page: the
   min-width is per-table, since a three-column spec needs far less room than the
   four-column retention table. */
.tablewrap { margin-top: 44px; overflow-x: auto; background: var(--v-surface); border: 1px solid var(--v-line); border-radius: var(--v-radius); }
.tablewrap table { width: 100%; border-collapse: collapse; }
table.ret { min-width: 660px; }
table.spec { min-width: 520px; }
.tablewrap th {
  text-align: left;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--v-ink-faint);
  padding: 14px 20px 14px 0;
  border-bottom: 1px solid var(--v-line);
  white-space: nowrap;
}
.tablewrap th:first-child, .tablewrap td:first-child { padding-left: 20px; }
.tablewrap td { padding: 13px 20px 13px 0; border-bottom: 1px solid var(--v-line); font-size: 14px; vertical-align: baseline; }
.tablewrap tr:last-child td { border-bottom: 0; }

/* The formats table. Its first column is a file KIND and its second an
   extension — an identifier, so it takes the mono face every other identifier on
   this site takes, and the accent that says "this is the literal string". */
table.spec .k { font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; }
table.spec .ext {
  font-family: var(--v-mono);
  font-size: 12.5px;
  color: var(--v-accent);
  white-space: nowrap;
}
table.spec td:last-child { color: var(--v-ink-muted); }
table.ret .juris { font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; }
table.ret .years { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
table.ret .basis { font-family: var(--v-mono); font-size: 12.5px; color: var(--v-ink-muted); white-space: nowrap; }
/* No statute to cite, so it drops the mono treatment that says "statute"
 * rather than filling it with the bare period. */
table.ret .basis.none { font-family: var(--v-sans); font-size: 13.5px; font-style: italic; }

/* The row the visitor's DOMAIN resolves to — never the locale's. The background
   and the accent bar are the whole of the mark; there is no badge beside the
   place name, because the page cannot know where the reader's business is
   registered and a badge saying "yours" claimed exactly that. */
table.ret tr.active td { background: var(--v-accent-soft); }
table.ret tr.active td:first-child { box-shadow: inset 3px 0 0 var(--v-accent); }

/* ---------- Pricing, set as an invoice ---------- */
/* Three panels: the rates, then the same business's first month and every month
 * after. align-items:start because they are different heights by nature — only
 * the rate panel carries sub-lines under every row — and stretching them to
 * match would put dead space under two of the three. */
/* TWO OBJECTS, NOT THREE CARDS: the price list, and one worked example that
 * happens to need two columns. As three equal siblings the section could not be
 * read — each repeated the same three line names and the same 12,00 €, so
 * nothing distinguished the rates from the arithmetic derived from them.
 *
 * The rate card is narrower because it is a list of three short rows; the
 * example is wider because it carries two ledgers side by side. */
.invoice { margin-top: 44px; display: grid; grid-template-columns: 1fr 1.85fr; gap: 20px; align-items: start; }
.panel { background: var(--v-surface); border: 1px solid var(--v-line); border-radius: var(--v-radius); padding: 26px 24px; }
.panel > .eyebrow { margin-bottom: 18px; }
.ledger { list-style: none; margin: 0; padding: 0; }
.ledger li { display: grid; grid-template-columns: 1fr auto; gap: 16px; align-items: baseline; padding: 11px 0; border-bottom: 1px solid var(--v-line); }
.ledger li:last-child { border-bottom: 0; }
.ledger .l-name { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.ledger .l-sub { display: block; font-size: 12.5px; font-weight: 400; color: var(--v-ink-faint); margin-top: 1px; }
.ledger .l-amt { font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; white-space: nowrap; }
/* RATES CARRY THEIR UNIT; the worked example beside them does not, because its
 * figures are computed totals rather than rates.
 *
 * The unit gets its OWN grid column rather than sitting inside .l-amt. With one
 * shared column the row right-aligns on the end of the unit — and since /Monat,
 * /Dokument and /GB are different widths (English /document is the same
 * nine characters), the figures themselves come out ragged and the ledger stops
 * reading as a ledger. Split, the amounts right-align against each other and
 * the units hang off the end, so the decimal points line up in every locale.
 *
 * column-gap is zeroed because "0,15" and "/GB" are one number, not two cells;
 * the 16px that separated name from amount is restored as padding. */
.ledger-rates li { grid-template-columns: 1fr auto auto; column-gap: 0; }
.ledger-rates .l-amt { padding-left: 16px; text-align: right; }
.ledger .l-unit { font-weight: 500; color: var(--v-ink-faint); }
.ledger li.total { border-top: 2px solid var(--v-ink); border-bottom: 0; margin-top: 6px; padding-top: 14px; }
.ledger li.total .l-name { font-size: 15px; }
.ledger li.total .l-amt { font-size: 19px; letter-spacing: -0.02em; }
.panel .fine { margin: 18px 0 0; font-size: 12.5px; color: var(--v-ink-faint); }

/* THE RATE CARD IS THE PRICE; THE EXAMPLE IS DERIVED FROM IT, and the surfaces
 * now say so. The rates keep the page's own card surface, the example is
 * recessed onto surface-2 — the same relationship the search band already uses
 * between its result rows and its chips-and-tally furniture. */
.panel-example { background: var(--v-surface-2); }

.example-intro {
  margin: -6px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--v-ink-muted);
  max-width: 56ch;
}

/* Two months, one business. The divider is what stops them reading as two
 * unrelated plans, which is exactly how they read as separate cards. */
.months { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; margin-top: 22px; }
.month + .month { border-left: 1px solid var(--v-line); padding-left: 28px; }

/* A month heading is subordinate to the panel's eyebrow above it, so it is not
 * another .eyebrow — that treatment is reserved for the label of a whole
 * object, and using it here would flatten the hierarchy this rework exists to
 * create. Sentence case, ink rather than faint. */
.month-h {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--v-ink);
}

/* THE HOME PAGE'S LAST WORD (#103), between the price band and its button.
   Set above body size and on a rule, so it reads as the page concluding rather
   than as one more paragraph of the pricing section it happens to sit in — and
   held to a comfortable measure, since it is the one place on the page where
   four short sentences run on unbroken.

   ITS MARGIN IS WHAT SEPARATES IT FROM THE LEDGERS ABOVE, and .closing's own
   top margin then separates the button from it, so the three sit on a rhythm
   that widens downward: table, statement, button. */
.sendoff {
  margin: 64px 0 0;
  padding-top: 34px;
  border-top: 1px solid var(--v-line);
  max-width: 60ch;
  font-size: 17px;
  line-height: 1.6;
  color: var(--v-ink);
}

.closing { margin-top: 40px; display: flex; align-items: center; flex-wrap: wrap; gap: 18px; }
.closing .fine { font-size: 13.5px; color: var(--v-ink-muted); }

/* A two-up card row, for a section that has exactly two things to say. .grid-3
   at two children would leave a third of the row empty and read as a missing
   card. Same gap and same margin, so the two rows sit on one rhythm. */
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 52px; }

/* One-up, same reasoning taken to its end: the enterprise page's scope section
   had three cards, two of them shipped and moved into the section above, and one
   is left. Under .grid-3 it would sit in the left third of an empty row and read
   as two cards having gone missing — the opposite of what happened. Full measure
   instead, on the same gap and margin as the rows above. */
.grid-1 { display: grid; grid-template-columns: 1fr; gap: 20px; margin-top: 52px; }

/* The rate panel on the pricing page stands alone rather than beside the worked
   example it does on the home page, so it must not stretch to the full measure —
   three short rows across 1080px reads as a table with the data missing. It keeps
   roughly the width it has inside .invoice's 1fr / 1.85fr split. */
.panel-solo { max-width: 380px; }

/* ---------- Question and answer ----------
   A <dl> of nine pairs, all open. No accordion: this site ships one script and
   every page must be complete without it, and each answer is a claim a prospect
   is deciding on — hiding nine of them behind nine clicks hides the reassurance
   the page exists to give.

   The pairs sit on the same hairline rhythm as .stages, so the FAQ reads as a
   list of the same kind as the rest of the site rather than a new component. The
   question carries the weight; the answer is muted body text at the measure every
   other paragraph uses. */
.qa { margin: 52px 0 0; border-top: 1px solid var(--v-line); }
.qa-item { padding: 22px 0; border-bottom: 1px solid var(--v-line); }
.qa dt { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.qa dd { margin: 6px 0 0; font-size: 14px; color: var(--v-ink-muted); max-width: 68ch; }

/* "Read the whole thing" after an answer that is a summary of a fuller section.
   Inline rather than on its own line — it is the tail of the sentence above it,
   not a call to action — and in the accent so it reads as a link inside muted
   text, the same problem .note a and .notfound .closing .fine solve. */
.qa-more {
  margin-left: 6px;
  color: var(--v-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}
.qa-more:hover { color: var(--v-accent-strong); }

/* The closing row's fine print carries a mailto on these pages, so its link
   needs the same treatment the 404's does. Scoped to .band so it cannot reach
   the .notfound rule, which already says this for itself. */
.band .closing .fine a {
  color: var(--v-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.band .closing .fine a:hover { color: var(--v-accent-strong); }

/* ============================================================
   PAGE HEAD — for a page that is not the pitch
   ============================================================ */

/* Every page beyond the home page runs the vault over the header and closes it
   straight after this block, which is the shape base.njk describes for a page
   with no hero. The 404 took that shape first; this is the same idea with
   something to say.

   NOT A THIRD DEPARTURE from the application's ui.md. --m-h1-page sits inside
   the type scale this site already owns, between the hero's 68px and a section
   head's 34px, and the 404 already used exactly this size — it is now named and
   read from one place rather than written twice, which is the only change to
   that page. */
:root { --m-h1-page: 44px; }

.pagehead { padding-block: 46px 64px; }

.pagehead h1 {
  margin: 16px 0 0;
  font-size: var(--m-h1-page);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.08;
  text-wrap: balance;
  /* ch at the h1's own size, so the measure survives all three languages. */
  max-width: 24ch;
}

.pagehead .intro {
  margin: 22px 0 0;
  font-size: 17px;
  line-height: 1.55;
  color: var(--m-vault-muted);
  max-width: 60ch;
}

/* ---------- Alternatives, not a sequence ----------
   .stages draws a numbered rail for the home page's pipeline, because every
   document runs through all four in order and the number is the information.
   The features page reuses the ROW RHYTHM for sets that are alternatives — one
   document takes one route — where a step count would assert an order that is
   not there.

   IT CARRIES NO MARKER AT ALL, and that is the second attempt. The first put
   A / B / C in the rail, which failed twice over: too faint to read against the
   ground, and dishonest even if it had been legible, since lettering a set is
   still enumerating it. The hairline rows and the headings already say "these
   are three of a kind", and where precedence genuinely exists the copy states it
   in words ("the document takes the route below"). One column, no rail, nothing
   to misread. */
.stages-alt .stage { grid-template-columns: 1fr; gap: 0; }

/* A closing statement that belongs to the section above rather than starting a
   new one — the fields extraction sets, which all three routes above converge
   on.

   IT TAKES .note's ACCENT RULE, and that is the second attempt too. Flush and
   unmarked it was indistinguishable from a fourth row in the list it follows:
   same left edge, same heading size, and the last row's own border sitting above
   it like a divider. Since it is a qualifier on the whole section, it borrows the
   device this site already uses for exactly that — .note's left rule in the
   accent — and keeps its heading, which .note has no room for. */
.afterword {
  margin-top: 34px;
  border-left: 2px solid var(--v-accent);
  padding-left: 16px;
  max-width: 62ch;
}
.afterword h3 { margin: 0 0 4px; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.afterword p { margin: 0; font-size: 14px; color: var(--v-ink-muted); }

/* ============================================================
   THE 404 PAGE
   ============================================================ */

/* THE QUIETEST PAGE ON THE SITE, and deliberately the only one with no drawing
 * on it. The hero's dimension line is not decoration — the tick count, the end
 * date and the word in the headline are one datum, which is what earns it its
 * place (docs/design/README.md § The signature). A 404 has no datum, so
 * anything drawn here would be the decorative version of the one device this
 * site has that isn't. Leave it empty; that restraint is the design.
 *
 * The page runs the vault over the header and closes it there — the shape
 * base.njk describes for a page with no hero, taken here for the first time. */
.notfound { padding-block: 96px 128px; }

/* The hero's eyebrow puts a word beside a mono span and lets the span be the
 * identifier; this is the same construction with a status code in place of a
 * statute. Accent rather than faint, because it is the one piece of the page a
 * visitor might recognise before reading anything. */
.notfound .eyebrow .status {
  font-family: var(--v-mono);
  letter-spacing: 0.04em;
  color: var(--v-accent);
}

/* Between the hero's 68px and a section head's 34px, and that is a considered
 * position rather than a split difference: this is the only heading on the page
 * so it carries more than a section head, and it is not the pitch so it does
 * not carry the hero's. Inside the type scale this site already owns — NOT a
 * third departure from the application's ui.md.
 *
 * The size is now --m-h1-page, shared with .pagehead: the same type role on
 * every page that is not the pitch, read from one place instead of written in
 * two. Same computed value as before. */
.notfound h1 {
  margin: 16px 0 0;
  font-size: var(--m-h1-page);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.08;
  text-wrap: balance;
  /* ch at the h1's own size, so the measure survives all three languages. */
  max-width: 22ch;
}

.notfound .intro {
  margin: 20px 0 0;
  font-size: 17px;
  color: var(--v-ink-muted);
  max-width: 50ch;
}

/* .closing is the pricing band's CTA row, and this is the same object rather
 * than a lookalike: one primary action with a line of fine print beside it.
 * Only the space above it differs — here it follows a paragraph rather than a
 * full band, so the component's own margin is overridden and nothing else is. */
.notfound .closing { margin-top: 34px; }
/* The fine print's link has to read as one. It is the only place on the site
 * where a link sits inside muted text at this size with no button beside it. */
.notfound .closing .fine a {
  color: var(--v-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.notfound .closing .fine a:hover { color: var(--v-accent-strong); }

/* ---------- Contact (#31) ----------
 *
 * TWO CHANNELS, AND THE COLUMNS SAY WHICH IS WHICH. The published address is
 * narrow and complete; the form is wide and conditional. They are not a
 * two-column "contact info beside a form" layout, which would state that they
 * are peers — the address works for everyone with no JavaScript and no third
 * party, and the form does not. Source order matches, so the address is also
 * first for a screen reader and first when the columns stack.
 *
 * The split is the one .invoice already uses on the home page rather than a new
 * proportion. */
/* NO TOP MARGIN, unlike .grid-3 and .stages. Those sit under a section's
 * eyebrow, h2 and intro, and the 52px is the space below that head. This band
 * has no head — the page's own .pagehead does that job one band up — so the
 * same margin here just adds to .band's 104px and opens a hole above the
 * content. */
.contact-cols {
  display: grid;
  grid-template-columns: 1fr 1.6fr;
  gap: 20px;
  align-items: start;
}

.contact-direct { display: flex; flex-direction: column; gap: 14px; }

/* The same treatment the intake card gives the filing address on the home page
 * — mono, accent, on accent-soft — because it is the same kind of object: an
 * address meant to be read off the screen and used. It is a link here, so it
 * also needs a hover state, which .card .addr has no use for. */
.contact-direct .addr {
  font-family: var(--v-mono);
  font-size: 13px;
  color: var(--v-accent);
  background: var(--v-accent-soft);
  border-radius: var(--v-radius-control);
  padding: 10px 12px;
  overflow-wrap: anywhere;
  text-decoration: none;
}
.contact-direct .addr:hover { color: var(--v-accent-strong); }
.contact-direct .fine { margin: 0; font-size: 12.5px; color: var(--v-ink-faint); line-height: 1.5; }

.contact-ask form { display: flex; flex-direction: column; gap: 22px; }
.contact-ask .btn { align-self: flex-start; }

/* THE NO-JAVASCRIPT STATE, and it ships visible — /scripts/contact.js hides it.
 * Not an error treatment: nothing has gone wrong, and the address above is a
 * complete way to reach us. Info rather than warn or danger for exactly that
 * reason. */
.needs-js {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--v-ink-muted);
  background: var(--v-info-soft);
  border-radius: var(--v-radius-control);
  padding: 12px 14px;
}

.field { display: flex; flex-direction: column; gap: 7px; }
.field label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--v-ink-faint);
}

/* Ledger discipline: a field is a ruled box, not a pill. Radius and colour are
 * the application's own tokens — the departures recorded in
 * docs/design/README.md are the dark hero and the display scale, and a third
 * one must not arrive through a form control. */
.field input,
.field textarea {
  font-family: inherit;
  font-size: 15px;
  color: var(--v-ink);
  background: var(--v-surface-2);
  border: 1px solid var(--v-line);
  border-radius: var(--v-radius-control);
  padding: 11px 13px;
  width: 100%;
  appearance: none;
  -webkit-appearance: none;
}
.field textarea { resize: vertical; min-height: 132px; line-height: 1.55; }
.field input:focus-visible,
.field textarea:focus-visible { border-color: var(--v-accent); }
.field input::placeholder,
.field textarea::placeholder { color: var(--v-ink-faint); }

.field-note { margin: 0; font-size: 12.5px; color: var(--v-ink-faint); line-height: 1.5; }

/* Errors are shown by the script and are `hidden` until then, so this rule only
 * ever applies to a message a reader needs. Danger rather than warn: the
 * submission did not happen. */
.field-err { margin: 0; font-size: 12.5px; color: var(--v-danger); line-height: 1.5; }

/* The honeypot. Off-canvas rather than `display: none` — some bots skip fields
 * that are display:none, and the point is that they fill this one in. It is
 * aria-hidden and not tabbable in the markup, so nothing reaches it by keyboard
 * or by screen reader. */
.hp {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.formstate { border-radius: var(--v-radius-control); padding: 16px 18px; }
.formstate h3 { margin: 0; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.formstate p { margin: 6px 0 0; font-size: 13.5px; line-height: 1.55; color: var(--v-ink-muted); }
.formstate-ok { background: var(--v-good-soft); }
.formstate-err { background: var(--v-danger-soft); }
.formstate-ok h3 { color: var(--v-good); }
.formstate-err h3 { color: var(--v-danger); }

/* WHAT THE FORM DOES WITH WHAT IT COLLECTS — not a privacy policy, and it must
 * not grow into one (#22 is, and this page cannot ship before it). Recessed and
 * quiet: it is a standing note rather than a section of the page, so it takes
 * the fine-print scale and sits below the two columns rather than beside them. */
.contact-privacy {
  margin-top: 44px;
  padding-top: 22px;
  border-top: 1px solid var(--v-line);
  max-width: 70ch;
}
/* THIS SITS INSIDE .band, SO `.band h2` APPLIES TO IT — same specificity, and
 * this rule only wins because it comes later in the file. That is too quiet a
 * dependency to leave implicit, so every property `.band h2` sets is answered
 * here even where the value happens to suit: a heading role this small must not
 * inherit a 34px section head's measure or balance. */
.contact-privacy h2 {
  margin: 0;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em;
  line-height: 1.4;
  text-wrap: auto;
  max-width: none;
  text-transform: uppercase; color: var(--v-ink-faint);
}
.contact-privacy p { margin: 10px 0 0; font-size: 13px; color: var(--v-ink-muted); line-height: 1.6; }

/* ---------- Legal pages (#21, #22, #23, #39) ----------
 *
 * A READING COLUMN, NOT A MARKETING BAND. Everything else on this site is laid
 * out to be scanned; these are read start to finish, by someone who may be
 * looking for one clause. So the measure is tight, the headings are small and
 * frequent, and nothing competes with the text. */
.prose { max-width: 68ch; }
.prose h2 {
  /* `.band h2` applies here too and is 34px — a section head for a marketing
     band, which would swamp a document with a dozen headings. Every property it
     sets is answered, for the same reason .contact-privacy answers them. */
  margin: 40px 0 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.35;
  text-wrap: auto;
  max-width: none;
}
.prose p { margin: 12px 0 0; font-size: 14.5px; line-height: 1.7; color: var(--v-ink-muted); }
.prose .lede { font-size: 16px; color: var(--v-ink); margin-top: 0; }
.prose a { color: var(--v-accent); text-decoration: underline; text-underline-offset: 2px; }
.prose a:hover { color: var(--v-accent-strong); }

/* The legal basis for the section above it. Set apart because it answers a
   different question from the prose — "under what article" rather than "what
   happens" — and a reader looking for one is not reading the other.

   `p.basis`, NOT `.basis`. The retention table's fourth column is also a legal
   basis and is also called `.basis`, and it is a `td`. This rule is later in the
   file and declares two properties `table.ret .basis` does not, so a bare
   selector handed every cell in that column a 2px left border it was never
   designed with: a stray vertical rule with the statute pressed up against it,
   because `.tablewrap td` sets `padding-left: 0` and wins on specificity.
   Scoping by element keeps the two apart without renaming either. */
p.basis {
  margin-top: 10px;
  font-size: 12.5px;
  color: var(--v-ink-faint);
  border-left: 2px solid var(--v-line);
  padding-left: 12px;
}

.note-inline { font-size: 13px; color: var(--v-ink-faint); }

/* THE DRAFT BAND. Warn rather than danger: nothing is broken, the document is
   unfinished. It
   must not be mistaken for the page's own content, hence the full surface.

   IN USE AGAIN AS OF 2026-08-09, WHICH IS WHAT THIS BLOCK WAS KEPT FOR. The
   privacy policy carried it until that day and lost it on publication — a page
   that is the operative policy cannot also announce it is not in force. The
   terms (#23) and the DPA page (#39) landed the same day as drafts and both
   render it. The prediction held, so the "delete this block if they ship
   without it" instruction is retired rather than left to be acted on.

   IT COMES OFF EACH PAGE IN THE COMMIT THAT PUBLISHES THAT PAGE, not as a
   tidy-up afterwards: the band and `published` in src/_lib/legal.js are two
   halves of one statement and must never disagree. */
.draftband {
  background: var(--v-warn-soft);
  border-radius: var(--v-radius);
  padding: 18px 20px;
  margin-bottom: 28px;
}
.draftband h2 {
  margin: 0;
  font-size: 12px; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--v-warn-strong);
  line-height: 1.4; max-width: none; text-wrap: auto;
}
.draftband p { margin: 8px 0 0; font-size: 13.5px; color: var(--v-ink-muted); }

/* AN OWED VALUE. entity.md's argument for a literal TODO is that it cannot be
   skimmed past, so this is the one place on the site that shouts. If it ever
   stops being loud, the reasoning behind the marker has been lost. */
.todo {
  font-family: var(--v-mono);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--v-danger);
  background: var(--v-danger-soft);
  border-radius: var(--v-radius-control);
  padding: 2px 7px;
  white-space: nowrap;
}
.confirm { display: inline-block; margin-top: 4px; font-size: 12.5px; color: var(--v-ink-faint); }

/* The convenience-translation notice, on the English and Romanian pages only.
   German binds, so the German page has nothing to say here. */
.translation-note {
  margin: 0 0 24px;
  font-size: 13px;
  color: var(--v-ink-faint);
  border-left: 2px solid var(--v-accent);
  padding-left: 12px;
}

/* Controller identity. A description list because that is what it is — a label
   and its value — and a table would imply rows that relate to each other. */
.factlist { margin: 16px 0 0; display: grid; grid-template-columns: max-content 1fr; gap: 8px 20px; }
.factlist dt {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--v-ink-faint); padding-top: 3px;
}
.factlist dd { margin: 0; font-size: 14px; color: var(--v-ink); }

.plainlist { margin: 12px 0 0; padding-left: 18px; }
.plainlist li { font-size: 14.5px; line-height: 1.7; color: var(--v-ink-muted); margin-top: 6px; }

/* QUOTED TEXT THIS SITE DOES NOT OWN. One use so far: the terms quote the
   business-capacity declaration verbatim from entity.md § D1a, which is
   canonical wording shared with the application's registration checkbox.

   IT LOOKS QUOTED ON PURPOSE. The distinction the indent draws is legal rather
   than typographic — the surrounding clauses are this document's own sentences,
   and this one is a reproduction of a string the reader will meet again, word
   for word, at signup. Set in the body face rather than italicised, because it
   is a sentence the reader is being asked to make, not an aside. */
.quoted {
  margin: 12px 0 0;
  padding-left: 16px;
  border-left: 2px solid var(--v-line-strong);
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--v-ink);
}

/* Wide content scrolls inside its own container rather than making the page
   scroll — the sub-processor table has three columns and long role sentences. */
.tablewrap { margin-top: 16px; overflow-x: auto; }
.proctable { border-collapse: collapse; width: 100%; min-width: 460px; }
.proctable th {
  text-align: left; padding: 0 14px 8px 0;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--v-ink-faint);
  border-bottom: 1px solid var(--v-line);
}
.proctable td {
  padding: 11px 14px 11px 0;
  font-size: 13.5px; line-height: 1.5;
  color: var(--v-ink-muted);
  border-bottom: 1px solid var(--v-line);
  vertical-align: top;
}
.proctable tbody tr:last-child td { border-bottom: 0; }
.proctable td:first-child { color: var(--v-ink); font-weight: 600; white-space: nowrap; }

/* ---------- Footer: a sitemap, because this is a site ---------- */
.foot { border-top: 1px solid var(--v-line); padding-block: 48px 56px; }
.foot-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 32px; }
.foot .brand { color: var(--v-ink); }
.foot .brand i { background: var(--v-accent); }
.foot .tagline { margin: 14px 0 0; font-size: 13px; color: var(--v-ink-muted); max-width: 34ch; }
/* h3, not h4: nothing here is an h3's child, so an h4 announced a level that
 * does not exist to anyone navigating by heading. Purely semantic — no bare
 * heading selector exists in this file, so the rendering is unchanged.
 *
 * The colour is the same 2.63:1 correction as .eyebrow: identical token,
 * identical size, and the footer sits on --v-ground like the bands do. */
.foot h3 {
  margin: 0 0 12px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--v-ink-muted);
}
.foot ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.foot ul a { font-size: 13.5px; color: var(--v-ink-muted); text-decoration: none; }
.foot ul a:hover { color: var(--v-ink); }
/* An entry whose page does not exist yet. It sits at the same size and rhythm
 * as its neighbours but is faint and inert, so the sitemap keeps its shape
 * without any of these pretending to be a link. Three of them are legally
 * mandatory and blocked on owner-supplied entity details — see the comment in
 * src/_includes/footer.njk before touching them. */
.foot ul .pending { font-size: 13.5px; color: var(--v-ink-faint); cursor: default; }

/* ---------- Responsive ---------- */
@media (max-width: 940px) {
  .grid-3 { grid-template-columns: 1fr; }
  .grid-2 { grid-template-columns: 1fr; }
  .panel-solo { max-width: none; }
  .invoice { grid-template-columns: 1fr; }
  /* The two months stay side by side here — the contrast between them IS the
     argument, and stacking them loses it. They only stack at 760px, where two
     ledgers no longer fit. */
  .foot-grid { grid-template-columns: 1fr 1fr; gap: 28px; }
  /* The address goes above the form, which is its source order — it is the
     channel that always works, so it should not be what a narrow screen pushes
     below the fold. */
  .contact-cols { grid-template-columns: 1fr; }
  .hero h1 { font-size: 46px; }
  .band h2 { font-size: 28px; }
  /* One override for both page heads, since they share the role. */
  :root { --m-h1-page: 36px; }
}
@media (max-width: 760px) {
  .wrap { width: min(1080px, 100% - 32px); }
  .band { padding-block: 72px; }
  .hero { padding-block: 52px 68px; }
  .hero h1 { font-size: 37px; letter-spacing: -0.03em; }
  .hero .lede { font-size: 17px; }
  .notfound { padding-block: 68px 88px; }
  :root { --m-h1-page: 30px; }
  .pagehead { padding-block: 36px 52px; }
  /* The rail the stage bodies sit on narrows to 34px here, so the afterword's
     indent follows it rather than stranding the paragraph mid-page. */
  .afterword { padding-left: 48px; }
  .topbar { gap: 14px; }
  /* The nav links collapse into the disclosure beside the CTA; the CTA, sign-in
   * and the locale switcher stay where they are, which is why those three live
   * in the meta bar and the header row.
   *
   * UNTIL #91 NOTHING REPLACED THE LINKS. The reasoning for dropping them was
   * sound as far as it went and did not account for `Preis` being one of the
   * four: a visitor arriving on /features/ from a search result had to scroll a
   * whole page to the footer to reach the price, on the most common path the
   * site has. The four are still in the footer; this is about reach. */
  .topnav a.navlink { display: none; }
  .navmenu { display: block; }
  .rowcard { grid-template-columns: 1fr auto; gap: 8px 16px; }
  .rowcard .ref { grid-column: 1 / -1; }
  .rowcard .kind { display: none; }
  .results li { grid-template-columns: 1fr auto; gap: 4px 14px; }
  .results .r-ref, .results .r-title { grid-column: 1 / -1; }
  .results .r-date { display: none; }
  .stage { grid-template-columns: 34px 1fr; gap: 14px; }
  /* Two ledgers no longer fit abreast. Stacked, the divider becomes a rule
     between them rather than beside them. */
  .months { grid-template-columns: 1fr; gap: 22px; }
  .month + .month { border-left: 0; padding-left: 0; border-top: 1px solid var(--v-line); padding-top: 22px; }
  .foot-grid { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  /* The dimension line is data, so it must still be fully drawn — only the
     drawing OF it goes. .dim-label keeps its centring transform; only the
     animation is dropped. */
  .dim-fill, .ticks i, .dim-cap.right, .dim-label { animation: none !important; opacity: 1; }
  .dim-fill { transform: none; }
}

/* ============================================================
   PRINT
   ============================================================

   THIS EXISTS FOR ONE PAGE. The security paper asks its reader to name the
   version they read in their own documentation, which means it gets printed
   or saved as PDF and filed — by exactly the auditor it is written for. The
   legal pages get filed for the same reason. The marketing pages are not
   expected to be printed and simply come out tidier for these rules.

   NOT COVERED, DELIBERATELY: a running head repeating the version on every
   sheet. The technique for it (`position: fixed`) behaves differently across
   print engines, and there is no print preview in the build to verify it
   against, so it is left undone and stated rather than shipped unverified.
   The version prints twice as it is — in the page head and in the closing
   section — which is enough to identify a filed copy.

   FORCE THE LIGHT PALETTE. tokens.css keys dark off prefers-color-scheme, so
   a reader whose machine is in dark mode would otherwise print white text on
   a black flood. Print has one ground and it is paper. */
@media print {
  :root, :root:not([data-theme="light"]), :root[data-theme="dark"] {
    --v-ground: #FFFFFF;
    --v-surface: #FFFFFF;
    --v-surface-2: #FFFFFF;
    --v-ink: #1A1D23;
    --v-ink-muted: #3A4150;
    --v-ink-faint: #555D6C;
    --v-line: #B9C0CC;
    --v-line-strong: #939CAB;
    --v-accent: #2F4A6B;
    --v-accent-strong: #2F4A6B;
    --m-vault: #FFFFFF;
    --m-vault-2: #FFFFFF;
    --m-vault-ink: #1A1D23;
    --m-vault-muted: #3A4150;
    --m-vault-faint: #555D6C;
    --m-vault-line: #B9C0CC;
    --m-vault-accent: #2F4A6B;
    --v-shadow: none;
  }

  body { background: #fff; font-size: 10.5pt; }

  /* The site's own navigation is dead weight on paper. The footer's brand and
     tagline stay: the tagline names who operates the service, which is the one
     line a filed copy should not lose. */
  .metabar, .topbar, .foot-grid > div:not(.foot-brand) { display: none; }
  .foot { border-top: 1px solid var(--v-line); padding-block: 18px 0; }
  .foot-grid { grid-template-columns: 1fr; }

  /* The vault band is a full-bleed dark flood. Reversed for paper it is a
     page of ink; here it becomes an ordinary opening block with a rule under
     it, which is what a title page wants anyway. */
  .vault { background: #fff; border-bottom: 1px solid var(--v-line); }
  .hero, .pagehead { padding-block: 0 24px; }
  .band { padding-block: 24px; }
  .wrap { width: 100%; }
  .prose, .band .intro, .stage p, .qa dd { max-width: none; }

  /* Keep a heading with what it introduces, and never split a table that a
     reviewer is reading as one object — the sub-processor list and the
     recovery-drill figures are both read row against row. */
  h1, h2, h3, h4 { break-after: avoid; page-break-after: avoid; }
  section, .stage, .card, .qa-item, li { break-inside: avoid; page-break-inside: avoid; }
  table, .tablewrap, .proctable { break-inside: avoid; page-break-inside: avoid; }
  thead { display: table-header-group; }

  /* Nothing scrolls on paper; a table clipped to a scroll container would
     simply lose its right-hand columns. */
  .tablewrap { overflow: visible; }

  /* Interactive things that cannot be operated from a sheet of paper. */
  .btn, .cta, .chips, .searchfield, .locales, form { display: none; }

  a { text-decoration: underline; }
}

/* ---------- The tenant's half of the Verfahrensdokumentation ---------- */
/* THE ONE THING THIS PAGE HAS TO SAY VISUALLY (vaultivo#1263). A
   Verfahrensdokumentation documents the TENANT's process, so a vendor can write
   only part of it — and a building block whose borrowed half is
   indistinguishable from the half the reader still owes is worse than no
   building block, because it gets filed as finished.

   Hence a treatment that survives being SKIMMED and being PRINTED: an accent
   rule and a soft ground, not italics or a colour on the text alone. Somebody
   flicking through the page must be able to count what is still theirs to
   answer without reading a word of it.

   The label is a <b> inside the block rather than a heading, because these sit
   under an <h2> and must not compete with it in a table of contents or for a
   screen reader walking the outline.

   Deliberately NOT .note-inline, which is quieter than the prose around it.
   This is louder. .todo is the only louder thing on the site and it is danger
   red for an owed entity value — an unanswered question here is expected at
   this point in the reader's work, not a defect. */
.yourpart {
  margin-top: 16px;
  border-left: 3px solid var(--v-accent);
  background: var(--v-accent-soft);
  border-radius: 0 var(--v-radius-control) var(--v-radius-control) 0;
  padding: 12px 16px;
}
.yourpart b {
  display: block;
  margin-bottom: 3px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--v-accent-strong);
}
/* Answers `.prose p`, which would otherwise put 12px above the first line and
   push it off the label. */
.yourpart p { margin: 0; font-size: 13.5px; color: var(--v-ink); }

/* ---------- The article listing (#140) ----------
 *
 * THE ONLY RULE THE ARTICLES NEEDED. Everything else on those pages is the
 * vocabulary that was already here: .pagehead for the head, .prose for the
 * reading column, .proctable inside .tablewrap for the period table, .basis for
 * the statute under a section, .note-inline for the date, .grid-1 for the list.
 * That is deliberate and worth keeping — a content surface that arrives with
 * its own visual language is a second design to maintain.
 *
 * A CARD THAT IS ITSELF THE LINK. `.card` is written for a <div>, so an <a>
 * carrying it inherits the anchor's colour and underline and lands looking like
 * a very large link. These four lines answer that and nothing else: the heading
 * keeps the ink colour, the body keeps the muted one, and the whole tile is the
 * target, which is what a list like this has to be on a phone.
 *
 * The hover moves the border rather than the background, because these sit on
 * --v-surface already and a surface-on-surface hover is invisible in the dark
 * scheme. */
a.card { color: inherit; text-decoration: none; transition: border-color 120ms ease; }
a.card:hover { border-color: var(--v-line-strong); }
a.card h3 { color: var(--v-ink); }
a.card .note-inline { margin-top: auto; padding-top: 4px; }
